BUG#: 8730
[tpot/pegasus.git.bak/pegasus.git] / src / Clients / cimcli / CIMCLIOptions.cpp
1 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //////////////////////////////////////////////////////////////////////////
29 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 /*******************************************************************************
33 *
34 * Command line options processing.  All option processing is based on the
35 * Pegasus OptionManager and the definition of options contained in this
36 * file. This file also contains the funtions to process input options.
37 *
38 * Once processed, the input options are placed into the options structure
39 * to be passed to the operation processors.
40 *
41 *******************************************************************************/
42 #include <Pegasus/Common/Config.h>
43 #include <Pegasus/Common/Constants.h>
44 #include <Pegasus/Common/PegasusAssert.h>
45 #include <Pegasus/Common/FileSystem.h>
46 #include <Pegasus/Common/XmlWriter.h>
47 #include <Pegasus/General/MofWriter.h>
48 #include <Pegasus/Common/Tracer.h>
49 #include <Pegasus/Common/StringConversion.h>
50 #include <Pegasus/Common/ArrayInternal.h>
51 #include <Pegasus/Common/PegasusVersion.h>
52
53 #include "CIMCLIOptions.h"
54 #include "CIMCLIClient.h"
55 #include "CIMCLIHelp.h"
56 #include "CIMCLICommon.h"
57 #include "CIMCLIClient.h"
58
59 PEGASUS_USING_STD;
60 PEGASUS_NAMESPACE_BEGIN
61
62 /*******************************************************************************
63 **
64 **  BuildOptionsTable
65 **
66 *******************************************************************************/
67 /*
68     This function builds the complete options table from the entries defined
69     below.  It then merges in the options from any config file and from any
70     command line parameters. The command line parameters will override
71     any config file parameters.
72 */
73 void BuildOptionsTable(
74     OptionManager& om,
75     int& argc,
76     char** argv,
77     const String& testHome)
78 {
79     // Table of available options to be used by cimcli.  Each of the possible
80     // options is defined in one entry in the table below.
81
82     static const char* outputFormats[] = { "xml", "mof", "txt", "table"};
83     static const Uint32 NUM_OUTPUTFORMATS = sizeof(outputFormats) /
84                                             sizeof(outputFormats[0]);
85     static OptionRowWithMsg optionsTable[] =
86         //optionname defaultvalue rqd  type domain domainsize clname msgkey
87         // hlpmsg
88     {
89         // FUTURE TODO.  This strange number was a way to tell option parser
90         // that the option was not found on the command line.  That concept
91         //  does not exist today in the OptionManager. The error mechanism
92         // tells you whether the option name is defined not whether there was
93         // an option supplied.  Need to fix OptionManager
94         {"count", "29346", false, Option::WHOLE_NUMBER, 0, 0, "count",
95         "Clients.cimcli.CIMCLIClient.COUNT_OPTION_HELP",
96         "Expected count of objects returned if summary set.\n"
97             "    Tests this count and displays difference.\n"
98             "    Return nonzero status code if test fails"},
99
100         {"debug", "false", false, Option::BOOLEAN, 0, 0, "d",
101         "Clients.cimcli.CIMCLIClient.DEBUG_OPTION_HELP",
102         "More detailed debug messages"},
103
104         {"delay", "0", false, Option::WHOLE_NUMBER, 0, 0, "delay",
105         "Clients.cimcli.CIMCLIClient.DELAY_OPTION_HELP",
106         "Delay between connection and request"},
107
108         {"Password", "", false, Option::STRING, 0, 0, "p",
109         "Clients.cimcli.CIMCLIClient.PASSWORD_OPTION_HELP",
110         "Defines password for authentication" },
111
112         {"location", "", false, Option::STRING, 0, 0, "l",
113         "Clients.cimcli.CIMCLIClient.LOCATION_OPTION_HELP",
114         "Specifies system and port (HostName:port).\n"
115             "    Port is optional" },
116
117 #ifdef PEGASUS_HAS_SSL
118         {"ssl", "false", false, Option::BOOLEAN, 0, 0, "s",
119         "Clients.cimcli.CIMCLIClient.SSL_OPTION_HELP",
120         "Specifies to connect over HTTPS" },
121
122         {"clientCert", "", false, Option::STRING, 0, 0, "-cert",
123         "Clients.cimcli.CIMCLIClient.CLIENTCERT_OPTION_HELP",
124         "Specifies a client certificate file path to present to the server.\n"
125             "    This is optional and only has an effect on connections\n"
126             "    made over HTTPS using -s" },
127
128         {"clientKey", "", false, Option::STRING, 0, 0, "-key",
129         "Clients.cimcli.CIMCLIClient.CLIENTKEY_OPTION_HELP",
130         "Specifies a client private key file path.\n"
131             "    This is optional and only has an effect on connections\n"
132             "    made over HTTPS using -s" },
133 #endif
134         {"User", "", false, Option::STRING, 0, 0, "u",
135         "Clients.cimcli.CIMCLIClient.USER_OPTION_HELP",
136         "Defines User Name for authentication" },
137
138         {"namespace", "root/cimv2", false, Option::STRING, 0, 0, "n",
139         "Clients.cimcli.CIMCLIClient.NAMESPACE_OPTION_HELP",
140         "Specifies namespace to use for operation" },
141
142         {"includeClassOrigin", "false", false, Option::BOOLEAN, 0, 0, "ic",
143         "Clients.cimcli.CIMCLIClient.INCLUDECLASSORIGIN_OPTION_HELP",
144         "If set includeClassOrigin  parameter\n"
145             "    set true on requests that honor this parameter"},
146
147         {"deepInheritance", "false", false, Option::BOOLEAN, 0, 0, "di",
148         "Clients.cimcli.CIMCLIClient.DEEPINHERITANCE_OPTION_HELP",
149         "If set deepInheritance parameter\n"
150             "    set true"},
151
152         // TODO - Drop this option completely
153         {"localOnly", "true", false, Option::BOOLEAN, 0, 0, "lo",
154         "Clients.cimcli.CIMCLIClient.LOCALONLY_OPTION_HELP",
155         "DEPRECATED. This was used to set LocalOnly.\n"
156             "    However, default should be true and we cannot use True\n"
157             "    as default. See -nlo"},
158
159         {"notLocalOnly", "false", false, Option::BOOLEAN, 0, 0, "nlo",
160         "Clients.cimcli.CIMCLIClient.NOTLOCALONLY_OPTION_HELP",
161         "When set, sets LocalOnly = false on\n"
162             "    operations"},
163
164         {"includeQualifiers", "false", false, Option::BOOLEAN, 0, 0, "iq",
165         "Clients.cimcli.CIMCLIClient.INCLUDEQUALIFIERS_OPTION_HELP",
166         "DEPRECATED. Sets includeQualifiers = True.\n"
167             "    Useful for instance operations where default is false"},
168
169         {"notIncludeQualifiers", "false", false, Option::BOOLEAN, 0, 0, "niq",
170         "Clients.cimcli.CIMCLIClient.NOTINCLUDEQUALIFIERS_OPTION_HELP",
171         "Sets includeQualifiers = false\n"
172             "    on operations. Useful for class operations where \n"
173             "    the default is true."},
174
175         // Uses a magic string as shown below to indicate never used.
176         {"propertyList", "###!###", false, Option::STRING, 0, 0, "pl",
177         "Clients.cimcli.CIMCLIClient.PROPERTYLIST_OPTION_HELP",
178         "Defines a propertyNameList. Format is p1,p2,p3\n"
179             "    (without spaces). Use \"\" for empty"},
180
181         {"assocClass", "", false, Option::STRING, 0, 0, "ac",
182         "Clients.cimcli.CIMCLIClient.ASSOCCLASS_OPTION_HELP",
183         "Defines a assocation Class string for Associator calls"},
184
185         {"assocRole", "", false, Option::STRING, 0, 0, "ar",
186         "Clients.cimcli.CIMCLIClient.ASSOCROLE_OPTION_HELP",
187         "Defines a role string for Associators. AssocRole\n"
188             "    parameter"},
189
190         {"role", "", false, Option::STRING, 0, 0, "r",
191         "Clients.cimcli.CIMCLIClient.ROLE_OPTION_HELP",
192         "Defines a role string for reference role parameter"},
193
194         {"resultClass", "", false, Option::STRING, 0, 0, "rc",
195         "Clients.cimcli.CIMCLIClient.RESULTCLASS_OPTION_HELP",
196         "Defines a resultClass string for References and\n"
197             "    Associatiors"},
198
199         {"resultRole", "", false, Option::STRING, 0, 0, "rr",
200         "Clients.cimcli.CIMCLIClient.RESULTROLE_OPTION_HELP",
201         "Defines a role string for associators operation resultRole\n"
202             "    parameter"},
203
204         // This options has been deprecated and its functionality removed
205         // Keeping it simply as means to explain the issue to users in case
206         // they try to use it.
207         {"inputParameters", "", false, Option::STRING, 0, 0, "ip",
208         "Clients.cimcli.CIMCLIClient.INPUTPARAMETERS_OPTION_HELP",
209         "This option deprecated and removed. Replaced by use of\n"
210             "    the same name/value pair syntax as properties in create\n"
211             "    and modify instance."},
212
213         {"filter", "", false, Option::STRING, 0, 0, "f",
214         "Clients.cimcli.CIMCLIClient.FILTER_OPTION_HELP",
215         "Defines a filter to use for query. Single String input"},
216
217         {"queryLanguage", "WQL", false, Option::STRING, 0, 0, "ql",
218         "Clients.cimcli.CIMCLIClient.QUERYLANGUAGE_OPTION_HELP",
219         "Defines a Query Language to be used with a query filter.\n"},
220
221         // KS change the output formats to use the enum options function
222         // Deprecate this function.
223         {"outputformats", "mof", false, Option::STRING, 0,NUM_OUTPUTFORMATS,
224         "o",
225         "Clients.cimcli.CIMCLIClient.OUTPUTFORMATS_OPTION_HELP",
226         "Output in xml, mof, txt, table"},
227
228         {"xmlOutput", "false", false, Option::BOOLEAN, 0,0, "x",
229         "Clients.cimcli.CIMCLIClient.XMLOUTPUT_OPTION_HELP",
230         "Output objects in xml format"},
231
232         {"version", "false", false, Option::BOOLEAN, 0, 0, "-version",
233         "Clients.cimcli.CIMCLIClient.VERSION_OPTION_HELP",
234         "Displays software Version"},
235
236         {"verbose", "false", false, Option::BOOLEAN, 0, 0, "v",
237         "Clients.cimcli.CIMCLIClient.VERBOSE_OPTION_HELP",
238         "Verbose Display. Outputs detailed parameter input\n"
239             "    display and other request processing information"},
240
241         {"summary", "false", false, Option::BOOLEAN, 0, 0, "-sum",
242         "Clients.cimcli.CIMCLIClient.SUMMARY_OPTION_HELP",
243         "Displays only summary count for enumerations,\n"
244             "    associators, etc."},
245
246         {"help", "false", false, Option::BOOLEAN, 0, 0, "h",
247         "Clients.cimcli.CIMCLIClient.HELP_OPTION_HELP",
248         "Prints help usage message"},
249
250         {"full help", "false", false, Option::BOOLEAN, 0, 0, "-help",
251         "Clients.cimcli.CIMCLIClient.FULLHELP_OPTION_HELP",
252         "Prints full help message with commands, options,\n"
253             "    examples"},
254
255         {"help options", "false", false, Option::BOOLEAN, 0, 0, "ho",
256         "Clients.cimcli.CIMCLIClient.HELPOPTIONS_OPTION_HELP",
257         "Prints list of options"},
258
259         {"help commands", "false", false, Option::BOOLEAN, 0, 0, "hc",
260         "Clients.cimcli.CIMCLIClient.HELPCOMMANDS_OPTION_HELP",
261         "Prints CIM Operation command list"},
262
263         {"connecttimeout", "0", false, Option::WHOLE_NUMBER, 0, 0, "-timeout",
264         "Clients.cimcli.CIMCLIClient.CONNECTIONTIMEOUT_OPTION_HELP",
265         "Set the connection timeout in seconds."},
266
267         {"interactive", "false", false, Option::BOOLEAN, 0, 0, "i",
268         "Clients.cimcli.CIMCLIClient.INTERACTIVE_OPTION_HELP",
269         "Interactively ask user to select instances.\n"
270             "    Used with associator and reference operations"},
271
272         {"setRtnHostNames", "", false, Option::STRING, 0, 0,
273              "-setRtnHostNames",
274             "Clients.cimcli.CIMCLIClient.SETRTNHOSTNAMES_OPTION_HELP",
275             "Set namespace component of reference and path outputs parameter.\n"
276             "    Used to allow comparison of paths and instances without"
277             " involving the variable of host namespaces."},
278
279         {"trace", "0", false, Option::WHOLE_NUMBER, 0, 0, "trace",
280         "Clients.cimcli.CIMCLIClient.TRACE_OPTION_HELP",
281         "Set Pegasus Common Components Trace. Sets the Trace level.\n"
282             "    0 is off"},
283
284         {"repeat", "0", false, Option::WHOLE_NUMBER, 0, 0, "-r",
285         "Clients.cimcli.CIMCLIClient.REPEAT_OPTION_HELP",
286         "Number of times to repeat the operation.\n"
287             "    Zero means one time"},
288
289         {"time", "false", false, Option::BOOLEAN, 0, 0, "-t",
290         "Clients.cimcli.CIMCLIClient.TIME_OPTION_HELP",
291         "Measure time for the operation and present results"},
292
293         {"sort", "false", false, Option::BOOLEAN, 0, 0, "-sort",
294         "Clients.cimcli.CIMCLIClient.SORT_OPTION_HELP",
295         "Sort the returned entities for multi-entity responses"}
296     };
297     const Uint32 NUM_OPTIONS = sizeof(optionsTable) / sizeof(optionsTable[0]);
298
299     // Register all of the options in the table above
300     om.registerOptions(optionsTable, NUM_OPTIONS);
301
302     // Merge any options from the config file if it exists
303     String configFile = "cimcli.conf";
304
305     if (FileSystem::exists(configFile))
306     {
307         om.mergeFile(configFile);
308     }
309
310     // Merge options from the command line
311     om.mergeCommandLine(argc, argv);
312
313     om.checkRequiredOptions();
314 }
315
316 /*
317     Execute lookup on option.  This used because the OptionTable functions
318     generally return error when the option is not found.  In cimcli this is
319     really a developer error (i.e option not in the table) so we isolate it
320     from the general lookup functionality. This function exits if the
321     lookup fails, that means that there is a discrepency between the table
322     of options and the names in the lookup functions. Fix the table.
323     The error exit in this function should NEVER happen in a released
324     version of cimcli.
325 */
326 static const Option* _lookupOption(OptionManager& om, const char* optionName)
327 {
328     const Option* op = om.lookupOption(optionName);
329
330     // if option does not exist in table, terminate.  All options must exist
331     // in the table. This is a programming error between the input
332     // parsing code and the table defining options.
333     if (op == 0)
334     {
335                cerr << "Parse Error in " << optionName
336                    << " Name not valid cimcli option. Fix options table"
337                     << endl;
338                exit(CIMCLI_INPUT_ERR);
339     }
340     return op;
341 }
342
343 // Get the value of the option if it was resolved.  Note that
344 // resolved means that it was input on either the command line or
345 // a configuration file.
346 // @param opts - reference to the options structure
347 // @param om -reference to the OptionManger where the data is saved.
348 // @param optionName - Name of the option for which we want the value
349 // @param resolvedStateVariable Boolean that is set true if the option has
350 //     been resolved (i.e. provided by either the config file or command line)
351 // @param optsTarget String containing the value of the parameter if it
352 //    was resolved.
353 // @return Boolean indicating whether the parameter was found in the table
354
355
356 Boolean lookupStringResolvedOption(Options& opts,
357     OptionManager& om,
358     const char* optionName,
359     Boolean& resolvedStateVariable,
360     String& optsTarget)
361 {
362     // test for existing option
363     const Option* op = _lookupOption(om, optionName);
364
365     if (op->isResolved())
366     {
367         resolvedStateVariable = true;
368         optsTarget = op->getValue();
369
370         if (opts.verboseTest && opts.debug)
371         {
372             cout << optionName << " = " << optsTarget << endl;
373         }
374     }
375     else
376     {
377         resolvedStateVariable = false;
378     }
379     return resolvedStateVariable;
380 }
381
382 /*
383     Lookup string option and insert into target property
384     Uses the table defined default directly if nothing input from
385     either command line or config file.
386 */
387 void lookupStringOption(Options& opts,
388     OptionManager& om,
389     const char* optionName,
390     String& optsTarget)
391 {
392     // Test for existing option. If nothing found, this
393     // function exits cimcli with error status
394     const Option* op = _lookupOption(om, optionName);
395
396     if (om.lookupValue(optionName, optsTarget))
397     {
398         if (opts.verboseTest && opts.debug)
399             cout << optionName << " = " << optsTarget << endl;
400     }
401 }
402
403 // Looks up a String option by name.  If the returned value is empty
404 // insures that it is value by setting to String::EMPTY
405 void lookupStringOptionEMPTY(Options& opts,
406     OptionManager& om,
407     const char* optionName,
408     String& optsTarget)
409 {
410     // Test for Existing Option
411     const Option* op = _lookupOption(om, optionName);
412
413     String temp;
414     if (om.lookupValue(optionName, temp))
415     {
416         optsTarget = (temp.size() == 0)? String::EMPTY : temp;
417
418         if (opts.verboseTest && opts.debug)
419         {
420             cout << optionName << " = " << optsTarget << endl;
421         }
422     }
423 }
424
425 void lookupCIMNameOption(Options& opts,
426     OptionManager& om,
427     const char* optionName,
428     CIMName& optsTarget,
429     const CIMName& defaultValue)
430 {
431     // Test for existing option
432     const Option* op = _lookupOption(om, optionName);
433
434     String temp;
435     if (om.lookupValue(optionName, temp))
436     {
437        if (temp != "")
438        {
439            //Assigning to CIMName can cause exception.
440            try
441            {
442                optsTarget = temp;
443            }
444            catch(Exception& e)
445            {
446                cerr << "Parse Error in " << optionName << " Class. Exception "
447                     << e.getMessage()
448                     << endl;
449                exit(CIMCLI_INPUT_ERR);
450            }
451        }
452        else
453            optsTarget = defaultValue;
454
455        if (opts.verboseTest && opts.debug && temp != "")
456        {
457            cout << optionName << " = " << optsTarget.getString() << endl;
458        }
459     }
460 }
461
462 // Lookup a single Uin32 option.  NOTE: The issue here is with detecting
463 // whether the option exists or we should use the internal default.
464 // Return from the option manager is the defined default which is itself
465 // an integer.
466 void lookupUint32Option(Options& opts,
467     OptionManager& om,
468     const char* optionName,
469     Uint32& optsTarget,
470     Uint32 defaultValue,
471     const char* units = "")
472 {
473     // Test for existing option
474     const Option* op = _lookupOption(om, optionName);
475
476     optsTarget = 0;
477     if (!om.lookupIntegerValue(optionName, optsTarget))
478     {
479         optsTarget = 0;
480     }
481
482     if (opts.verboseTest && opts.debug && optsTarget != 0)
483     {
484         cout << optionName << " = "
485             << optsTarget << units
486             << endl;
487     }
488 }
489
490 // Lookup value only if the option was resolved. Ignores default values.
491 Boolean lookupUint32ResolvedOption(Options& opts,
492     OptionManager& om,
493     const char* optionName,
494     Boolean& resolvedStateVariable,
495     Uint32& optsTarget,
496     Uint32 defaultValue,
497     const char* units = "")
498 {
499     // Test for existing Option
500     const Option* op = _lookupOption(om, optionName);
501
502     optsTarget = 0;
503     if (op->isResolved())
504     {
505         resolvedStateVariable = true;
506         const String value = op->getValue();
507         Uint64 u64 = strToUint(value.getCString(), CIMTYPE_UINT32);
508         optsTarget = (Uint32)u64;
509     }
510     else
511     {
512         resolvedStateVariable = false;
513     }
514     return resolvedStateVariable;
515 }
516
517 void lookupBooleanOption(Options& opts,
518                    OptionManager& om,
519                    const char* optionName,
520                    Boolean& optsTarget)
521 {
522     // Test for existing option
523     const Option* op = _lookupOption(om, optionName);
524
525     optsTarget = om.isTrue(optionName);
526     if (optsTarget  && opts.verboseTest && opts.debug)
527     {
528         cout << optionName << " = " << _toString(optsTarget) << endl;
529     }
530 }
531
532 void lookupBooleanOptionNegate(Options& opts,
533                    OptionManager& om,
534                    const char* optionName,
535                    Boolean& optsTarget)
536 {
537     // Test for existing option
538     const Option* op = _lookupOption(om, optionName);
539
540     optsTarget = !om.isTrue(optionName);
541     if (optsTarget  && opts.verboseTest && opts.debug)
542     {
543         cout << optionName << " = " << _toString(optsTarget) << endl;
544     }
545 }
546
547 int CheckCommonOptionValues(OptionManager& om, char** argv, Options& opts)
548 {
549     Uint32 lineLength = 75;
550     // Catch the verbose and debug options first so they can control other
551     // processing
552     Boolean verboseTest = (om.valueEquals("verbose", "true")) ? true :false;
553     Boolean debug = (om.valueEquals("debug", "true")) ? true :false;
554
555     if (verboseTest)
556     {
557         opts.verboseTest = verboseTest;
558     }
559
560     if (debug)
561     {
562         opts.debug= debug;
563     }
564
565     if (om.isTrue("full help"))
566     {
567         showFullHelpMsg(argv[0], om, lineLength);
568         exit(CIMCLI_RTN_CODE_OK);
569     }
570
571     // show usage for a single operation and exit
572     if (om.isTrue("help"))
573     {
574         if (!showOperationUsage(argv[1], om, lineLength))
575         {
576             exit(CIMCLI_INPUT_ERR);
577         }
578
579         showUsage();
580         exit(CIMCLI_RTN_CODE_OK);
581     }
582
583     // show version number
584     if (om.isTrue("version"))
585     {
586         showVersion(argv[0], om);
587         exit(CIMCLI_RTN_CODE_OK);
588     }
589
590     // show all help options
591     if (om.isTrue("help options"))
592     {
593         showOptions(argv[0], om);
594         exit(CIMCLI_RTN_CODE_OK);
595     }
596
597     // show help Operation list
598     if (om.isTrue("help commands"))
599     {
600         showOperations(argv[0], lineLength);
601         exit(CIMCLI_RTN_CODE_OK);
602     }
603
604     lookupStringOption(opts, om, "namespace", opts.nameSpace);
605
606     lookupStringOptionEMPTY(opts, om, "role", opts.role);
607
608     lookupStringOptionEMPTY(opts, om, "resultRole", opts.resultRole);
609
610     lookupStringOption(opts, om, "location", opts.location);
611
612 #ifdef PEGASUS_HAS_SSL
613     // Determine whether to connect over HTTPS
614     opts.ssl = om.isTrue("ssl");
615
616     // Get value for client certificate
617     om.lookupValue("clientCert", opts.clientCert);
618
619     // Get value for client key
620     om.lookupValue("clientKey", opts.clientKey);
621
622     if (verboseTest && debug && opts.ssl)
623     {
624         cout << "ssl = true" << endl;
625         if (opts.clientCert != "" && opts.clientKey != "")
626         {
627             cout << "clientCert = " << opts.clientCert << endl;
628             cout << "clientKey = " << opts.clientKey << endl;
629         }
630     }
631 #endif
632
633     // Assign the result class
634     lookupCIMNameOption(opts, om, "resultClass", opts.resultClass, CIMName());
635
636     lookupCIMNameOption(opts, om, "assocClass", opts.assocClass, CIMName());
637
638     // Evaluate connectiontimeout option.
639     lookupUint32Option(opts, om, "connecttimeout", opts.connectionTimeout, 0,
640         "seconds");
641
642     lookupUint32Option(opts, om, "delay", opts.delay, 0, "seconds");
643
644     // Set the interactive request flag based on input
645     lookupBooleanOption(opts, om,"interactive", opts.interactive);
646
647     // Set the sort request flag based on input
648     lookupBooleanOption(opts, om,"sort", opts.sort);
649
650     // set the deepInheritance flag based on input
651     lookupBooleanOption(opts, om,"deepInheritance", opts.deepInheritance);
652
653     // only use this one if there was an input from the command line
654     // or config file. sets the Boolean setRtnHostNames based on whether
655     // there was an option input (i.e. resolved).
656     lookupStringResolvedOption(opts, om,
657                                    "setRtnHostNames",
658                                    opts.setRtnHostNames,
659                                    opts.rtnHostSubstituteName);
660
661     lookupStringOption(opts, om, "filter", opts.query);
662
663     lookupStringOption(opts, om, "queryLanguage", opts.queryLanguage);
664
665     // Test for existence of input parameter option.  If found, put out
666     // warning and exit with syntax error message.  This parameter was
667     // deprecated and removed in favor of direct input of name/value pairs
668     // as separate input entities in CIM Version 2.10
669     Boolean inputParametersResolved = false;
670     String inputParameters;
671     lookupStringResolvedOption(opts, om,
672                                    "inputParameters",
673                                    inputParametersResolved,
674                                    inputParameters);
675     if (inputParametersResolved)
676     {
677         cerr << "The -ip option has been deprecated and removed.\n"
678               "    parameters can be directly input as name/value pairs\n"
679               "    in the same manner properties are input to the\n"
680               "    createInstance and other operations\n" << endl;
681         exit(CIMCLI_INPUT_ERR);
682     }
683
684     // process localOnly and notlocalOnly parameters
685     opts.localOnly = om.isTrue("localOnly");
686     if (om.isTrue("notLocalOnly"))
687     {
688         opts.localOnly = false;
689     }
690
691     // Used the not version because the DMTF and pegasus default is true
692     if (verboseTest && debug && om.isTrue("notLocalOnly"))
693     {
694         cout << "localOnly= " << _toString(opts.localOnly) << endl;;
695     }
696
697     // Process includeQualifiers and notIncludeQualifiers
698     // These are particular in that there are two parameters each
699     // of which may be useful. Also, the CIM/XML default is different
700     // for class operations and instance operations.  In class operations
701     // the default is true while, in instance operations, the default
702     // is false and further, the whole use of the parameter is deprecated for
703     // instance operations.
704     // For each of these parameters we want to specifically confirm if
705     // the command line input parameter is supplied. Thus, for class operations
706     // the user would use the niq to tell the environment to not include
707     // qualifiers whereas for instance operations the user would use iq
708     // to specifically request qualifiers with instances.
709
710     lookupBooleanOption(opts, om, "includeQualifiers",
711         opts.includeQualifiersRequested);
712
713     lookupBooleanOption(opts, om, "notIncludeQualifiers",
714         opts.notIncludeQualifiersRequested);
715
716
717     lookupBooleanOption(opts, om,"includeClassOrigin",
718         opts.includeClassOrigin );
719
720     lookupBooleanOption(opts, om,"time", opts.time);
721
722     if (!om.lookupIntegerValue("trace", opts.trace))
723     {
724             opts.trace = 0;
725     }
726     else
727     {
728         Uint32 traceLevel = 0;
729         switch (opts.trace)
730         {
731             case 0:             // This covers the default.
732                 break;
733             case 1 :
734                 traceLevel = Tracer::LEVEL1;
735                 break;
736             case 2 :
737                 traceLevel = Tracer::LEVEL2;
738                 break;
739             case 3 :
740                 traceLevel = Tracer::LEVEL3;
741                 break;
742             case 4 :
743                 traceLevel = Tracer::LEVEL4;
744                 break;
745             default:
746                 cerr << "Illegal value for Trace. Max = 4" << endl;
747         }
748         opts.trace = traceLevel;
749     }
750     if (verboseTest && debug && opts.trace != 0)
751     {
752         cout << "Pegasus Trace set to  Level  " << opts.trace << endl;
753     }
754
755     lookupBooleanOption(opts, om,"summary", opts.summary);
756
757     // get User name and password if set.
758     lookupStringOptionEMPTY(opts, om, "User", opts.user);
759
760     lookupStringOptionEMPTY(opts, om, "Password", opts.password);
761
762     // Create a variable with the format output and a correponding type.
763     // Suggest we might change this whole thing to the option type that
764     // mike used in the example of colors so that  you could do -red -blue
765     // or in our case -mof -xml, etc.
766
767      opts.isXmlOutput = om.isTrue("xmlOutput");
768      if (opts.isXmlOutput  && debug && verboseTest)
769      {
770          cout << "xmlOutput set" << endl;
771      }
772
773     if (om.lookupValue("outputformats", opts.outputFormat))
774      {
775         if (debug && verboseTest)
776         {
777             cout << "Output Format = " << opts.outputFormat << endl;
778         }
779      }
780
781     // Get the output format parameter and save it
782     Uint32 cnt = 0;
783     opts.outputFormat.toLower();
784
785     for( ; cnt < NUM_OUTPUTS; cnt++ )
786     {
787         if (opts.outputFormat == OutputTable[cnt].OutputName)
788         {
789             break;
790         }
791     }
792     // Note that this makes no notice if a not found
793     if (cnt != NUM_OUTPUTS)
794     {
795         opts.outputFormatType = cnt;
796         opts.outputType = OutputTable[cnt].OutputType;
797     }
798
799     lookupUint32Option(opts, om, "repeat", opts.repeat, 0, "times");
800
801     lookupUint32ResolvedOption(opts, om, "count", opts.executeCountTest,
802                                opts.expectedCount,
803                                0, "Comparison Count");
804
805     /*  Property List parameter.
806         Separate an input stream into an array of Strings
807         Two special situations, empty list and NULL list
808         Use NULL when there is no list. This means return all
809         Use empty if if you want no properties in the response
810         NOTE: We use the ###!### to represent no input of parameter
811     */
812     {
813         String properties;
814         if (om.lookupValue("propertyList", properties))
815         {
816             // om default.  No property list input
817             if (properties == "###!###")
818             {
819                 opts.propertyList.clear();
820             }
821             // propertylist input empty.
822             // Account for inputter error where they try to input string
823             // representing two quotes
824             else if (properties.size() == 0 || properties == "\"\"")
825             {
826                 Array<CIMName> pList;
827                 opts.propertyList = pList;
828             }
829             else
830             {
831                 Array<CIMName> pList;
832                 // tokenize everything separated by commas
833                 Array<String> pListString =  _tokenize(properties, ',', true);
834
835                 for (Uint32 i = 0 ; i < pListString.size(); i++)
836                 {
837                     pList.append(CIMName(pListString[i]));
838                 }
839                 opts.propertyList.set(pList);
840             }
841             if (debug && verboseTest && properties != "###!###")
842             {
843                 cout << "PropertyList= "
844                     << _toString(opts.propertyList)
845                     << endl;
846             }
847         }
848     }
849
850     return 0;
851 }
852
853 PEGASUS_NAMESPACE_END
854 // END_OF_FILE