1 krisbash 1.1 #include <stdio.h>
2 #include <signal.h>
3 #include <MI.h>
4 #include <pal/file.h>
5 #include <pal/dir.h>
6 #include <pal/strings.h>
7 #include <pal/cpu.h>
8 #include <pal/format.h>
9 #include <pal/lock.h>
10 #include <pal/sleep.h>
11 #include <pal/strings.h>
12 #include <base/paths.h>
13 #include <wql/wql.h>
14 #include <base/conf.h>
15 #include <base/env.h>
16 #include <base/instance.h>
17 #include <base/log.h>
18 #include <base/result.h>
19 #include <base/strarr.h>
20 #include <base/ptrarray.h>
21
22 krisbash 1.1 static MI_Boolean ArgsToInstance(
23 const MI_Char*** _p,
24 const MI_Char** end,
25 MI_Uint32 metaType,
26 MI_Boolean key,
27 MI_Instance **instanceOut);
28
29 static FILE* sout;
30 static FILE* serr;
31 const MI_Char* arg0;
32 static MI_Operation gop = {0, 0, 0};
33
34 struct Options
35 {
36 MI_Boolean help;
37 MI_Boolean quiet;
38 MI_Boolean summary;
39 MI_Boolean suppressResults;
40 MI_Boolean trace;
41 MI_Boolean shallow;
42 int repeat;
43 krisbash 1.1 const MI_Char *assocClass;
44 const MI_Char *resultClass;
45 const MI_Char *role;
46 const MI_Char *resultRole;
47 const MI_Char *user;
48 const MI_Char *password;
49 MI_Uint64 timeOut;
50 unsigned int httpport;
51 unsigned int httpsport;
52 MI_Boolean nulls;
53 const MI_Char *querylang;
54 const MI_Char *queryexpr;
55 MI_Boolean synchronous;
56 };
57
58 static struct Options opts =
59 { MI_FALSE, MI_FALSE, MI_FALSE, MI_FALSE, MI_FALSE, MI_FALSE, 1, NULL, NULL, NULL, NULL, NULL, NULL, 90 * 1000 * 1000, CONFIG_HTTPPORT, CONFIG_HTTPSPORT, MI_FALSE, MI_T("wql"), NULL, MI_FALSE };
60
61 static void err(const ZChar* fmt, ...)
62 {
63 va_list ap;
64 krisbash 1.1
65 Ftprintf(serr, PAL_T("%T: "), tcs(arg0));
66
67 va_start(ap, fmt);
68 Vftprintf(serr, fmt, ap);
69 va_end(ap);
70
71 Ftprintf(serr, PAL_T("\n"));
72 }
73
74 static MI_Uint64 s_numInstances = 0;
75 static ptrdiff_t s_startTime;
76 static MI_Result s_finalResult = MI_RESULT_FAILED;
77 static ptrdiff_t s_finished = 0;
78
79 static void PrintSummary()
80 {
81 ptrdiff_t now = CPU_GetTimeStamp();
82 MI_Uint64 msec = (now - s_startTime) / 1000;
83 MI_Real64 seconds = (MI_Real64)msec / (MI_Real64)1000.0;
84
85 krisbash 1.1 Tprintf(PAL_T("number of instances: %u\n"), s_numInstances);
86 Tprintf(PAL_T("seconds: %.3lf\n"), seconds);
87 Tprintf(PAL_T("instances per second: %.3lf\n"), s_numInstances / seconds);
88 Tprintf(PAL_T("\n"));
89 }
90
91 static MI_Result Encode(int argc, const MI_Char* argv[])
92 {
93 MI_Instance *inst;
94 if (argc < 3)
95 {
96 Ftprintf(serr, PAL_T("Usage: %s noop CLASSNAME KEYBINDING\n\n"), tcs(arg0));
97 return MI_RESULT_INVALID_PARAMETER;
98 }
99
100 argc -= 2;
101 argv += 2;
102
103 if (!ArgsToInstance(&argv, argv + argc, MI_FLAG_CLASS, MI_FALSE, &inst))
104 {
105 err(PAL_T("invalid instance name specification"));
106 krisbash 1.1 return MI_RESULT_INVALID_PARAMETER;
107 }
108
109 if (!opts.quiet)
110 {
111 Instance_Print(inst, sout, 0, opts.nulls, MI_FALSE);
112 }
113
114 MI_Instance_Delete(inst);
115
116 s_numInstances++;
117
118 return MI_RESULT_OK;
119 }
120
121
122
123 // Find closing brace (assuming *p points to an opening brace).
124 static const MI_Char** FindClosingBrace(const MI_Char** p)
125 {
126 int nesting = 1;
127 krisbash 1.1
128 if (Tcscmp(*p, MI_T("{")) != 0)
129 return NULL;
130
131 p++;
132
133 while (*p)
134 {
135 if (Tcscmp(*p, MI_T("{")) == 0)
136 nesting++;
137 else if (Tcscmp(*p, MI_T("}")) == 0)
138 nesting--;
139
140 p++;
141
142 if (nesting == 0)
143 return p;
144 }
145
146 return NULL;
147 }
148 krisbash 1.1
149 static void MI_MAIN_CALL _DeleteInstance(void* inst)
150 {
151 MI_Instance_Delete((MI_Instance*)inst);
152 }
153
154 static MI_Boolean ArgsToInstance(
155 const MI_Char*** _p,
156 const MI_Char** end,
157 MI_Uint32 metaType,
158 MI_Boolean key,
159 MI_Instance **instanceOut)
160 {
161 MI_Instance *instance;
162 MI_Uint32 keyFlag = 0;
163 const MI_Char **p = *_p;
164
165 if (key)
166 keyFlag = MI_FLAG_KEY;
167
168 if (p == end)
169 krisbash 1.1 return MI_FALSE;
170
171 // Consume opening brace:
172 if (Tcscmp(*p++, MI_T("{")) != 0)
173 return MI_FALSE;
174
175 if (p == end)
176 return MI_FALSE;
177
178
179 if (metaType == MI_FLAG_METHOD)
180 {
181 if (Instance_NewDynamic(&instance, MI_T("Parameters"), MI_FLAG_METHOD, NULL) != MI_RESULT_OK)
182 return MI_FALSE;
183 }
184 else
185 {
186 if (Instance_NewDynamic(&instance, *p++, MI_FLAG_CLASS, NULL) != MI_RESULT_OK)
187 return MI_FALSE;
188
189 if (p == end)
190 krisbash 1.1 {
191 MI_Instance_Delete(instance);
192 return MI_FALSE;
193 }
194 }
195
196 // Consume name/value pairs:
197 for (;;)
198 {
199 const MI_Char *name;
200 if (Tcscmp(*p, MI_T("}")) == 0)
201 {
202 p++;
203 break;
204 }
205
206 // Get name:
207 name = *p++;
208
209 if (p == end)
210 {
211 krisbash 1.1 MI_Instance_Delete(instance);
212 return MI_FALSE;
213 }
214
215 // Get value:
216 if (Tcscmp(*p, MI_T("{")) == 0)
217 {
218 const MI_Char** q = FindClosingBrace(p);
219 MI_Instance *tmpInst;
220 MI_Value value;
221
222 if (!q || q == end)
223 {
224 MI_Instance_Delete(instance);
225 return MI_FALSE;
226 }
227
228 // Recursively call to obtain reference or embedded instance.
229
230 if (!ArgsToInstance(&p, q, MI_FLAG_CLASS, key, &tmpInst))
231 {
232 krisbash 1.1 MI_Instance_Delete(instance);
233 return MI_FALSE;
234 }
235
236 value.instance = tmpInst;
237 if (MI_Instance_AddElement(instance, name, &value, MI_INSTANCE, keyFlag | MI_FLAG_ADOPT) != MI_RESULT_OK)
238 //!instance.AddInstance(name, tmpInst, MI_FALSE, key))
239 {
240 MI_Instance_Delete(tmpInst);
241 MI_Instance_Delete(instance);
242 return MI_FALSE;
243 }
244 }
245 else if (Tcscmp(*p, MI_T("[")) == 0)
246 {
247 MI_Char** strArray = ZArr();
248 PtrArray instanceArray;
249
250 if (strArray == NULL)
251 {
252 MI_Instance_Delete(instance);
253 krisbash 1.1 return MI_FALSE;
254 }
255 if (PtrArray_Construct(&instanceArray, 5, _DeleteInstance) != 0)
256 {
257 ZArrFree(strArray);
258 MI_Instance_Delete(instance);
259 return MI_FALSE;
260 }
261
262 p++;
263
264 // Find closing brace:
265 while (*p && Tcscmp(*p, MI_T("]")) != 0)
266 {
267 if (Tcscmp(*p, MI_T("{")) == 0)
268 {
269 const MI_Char** q = FindClosingBrace(p);
270 MI_Instance *tmpInst = NULL;
271
272 if (!q || q == end)
273 {
274 krisbash 1.1 if (strArray)
275 {
276 #ifdef _PREFAST_
277 #pragma prefast(push)
278 #pragma prefast(disable:26018)
279 #endif
280 ZArrFree(strArray);
281 #ifdef _PREFAST_
282 #pragma prefast(pop)
283 #endif
284 }
285 PtrArray_Destruct(&instanceArray);
286 MI_Instance_Delete(instance);
287 return MI_FALSE;
288 }
289
290 if (!ArgsToInstance(&p, q, MI_FLAG_CLASS, key, &tmpInst))
291 {
292 if (strArray)
293 {
294 #ifdef _PREFAST_
295 krisbash 1.1 #pragma prefast(push)
296 #pragma prefast(disable:26018)
297 #endif
298 ZArrFree(strArray);
299 #ifdef _PREFAST_
300 #pragma prefast(pop)
301 #endif
302 }
303 PtrArray_Destruct(&instanceArray);
304 MI_Instance_Delete(instance);
305 return MI_FALSE;
306 }
307 if (PtrArray_Append(&instanceArray, tmpInst) != 0)
308 {
309 if (strArray)
310 {
311 #ifdef _PREFAST_
312 #pragma prefast(push)
313 #pragma prefast(disable:26018)
314 #endif
315 ZArrFree(strArray);
316 krisbash 1.1 #ifdef _PREFAST_
317 #pragma prefast(pop)
318 #endif
319 }
320 PtrArray_Destruct(&instanceArray);
321 MI_Instance_Delete(instance);
322 MI_Instance_Delete(tmpInst);
323 return MI_FALSE;
324 }
325 }
326 else
327 {
328 MI_Char **_strArray = strArray;
329 ZArrCat(&_strArray, *p++);
330 if (_strArray == NULL)
331 {
332 /* Failed */
333 if (strArray)
334 {
335 #ifdef _PREFAST_
336 #pragma prefast(push)
337 krisbash 1.1 #pragma prefast(disable:26018)
338 #endif
339 ZArrFree(strArray);
340 #ifdef _PREFAST_
341 #pragma prefast(pop)
342 #endif
343 }
344 PtrArray_Destruct(&instanceArray);
345 MI_Instance_Delete(instance);
346 return MI_FALSE;
347 }
348 strArray = _strArray;
349 }
350 }
351
352 // Handle missing closing brace:
353 if (p == end)
354 {
355 if (strArray)
356 {
357 #ifdef _PREFAST_
358 krisbash 1.1 #pragma prefast(push)
359 #pragma prefast(disable:26018)
360 #endif
361 ZArrFree(strArray);
362 #ifdef _PREFAST_
363 #pragma prefast(pop)
364 #endif
365 }
366 PtrArray_Destruct(&instanceArray);
367 MI_Instance_Delete(instance);
368 return MI_FALSE;
369 }
370
371 if (instanceArray.size)
372 {
373 MI_Value value;
374 MI_Uint32 flags = 0;
375 value.instancea.data = (MI_Instance**) instanceArray.data;
376 value.instancea.size = instanceArray.size;
377 if (key)
378 flags = MI_FLAG_KEY;
379 krisbash 1.1
380 if (MI_Instance_AddElement(instance, name, &value, MI_INSTANCEA, flags) != MI_RESULT_OK)
381 {
382 if (strArray)
383 {
384 #ifdef _PREFAST_
385 #pragma prefast(push)
386 #pragma prefast(disable:26018)
387 #endif
388 ZArrFree(strArray);
389 #ifdef _PREFAST_
390 #pragma prefast(pop)
391 #endif
392 }
393 PtrArray_Destruct(&instanceArray);
394 MI_Instance_Delete(instance);
395 return MI_FALSE;
396 }
397 }
398 else
399 {
400 krisbash 1.1 MI_Uint32 arrLength = ZArrLen(strArray);
401 if (arrLength)
402 {
403 MI_Value value;
404 MI_Uint32 flags = 0;
405 value.stringa.data = strArray;
406 value.stringa.size = arrLength;
407 if (key)
408 flags = MI_FLAG_KEY;
409
410 if (MI_Instance_AddElement(instance, name, &value, MI_STRINGA, flags) != MI_RESULT_OK)
411 {
412 if (strArray)
413 {
414 #ifdef _PREFAST_
415 #pragma prefast(push)
416 #pragma prefast(disable:26018)
417 #endif
418 ZArrFree(strArray);
419 #ifdef _PREFAST_
420 #pragma prefast(pop)
421 krisbash 1.1 #endif
422 }
423 PtrArray_Destruct(&instanceArray);
424 MI_Instance_Delete(instance);
425 return MI_FALSE;
426 }
427 }
428 }
429
430 if (strArray)
431 {
432 #ifdef _PREFAST_
433 #pragma prefast(push)
434 #pragma prefast(disable:26018)
435 #endif
436 ZArrFree(strArray);
437 #ifdef _PREFAST_
438 #pragma prefast(pop)
439 #endif
440 }
441 PtrArray_Destruct(&instanceArray);
442 krisbash 1.1 p++;
443 }
444 else
445 {
446 MI_Value value;
447
448 value.string = (MI_Char *)*p++;
449
450 // Add property:
451 if (MI_Instance_AddElement(instance, name, &value, MI_STRING, keyFlag | MI_FLAG_BORROW) != MI_RESULT_OK)
452 {
453 MI_Instance_Delete(instance);
454 return MI_FALSE;
455 }
456
457 if (p == end)
458 break;
459 }
460 }
461
462 *_p = p;
463 krisbash 1.1 *instanceOut = instance;
464 return MI_TRUE;
465 }
466
467 MI_Result CreateOperationOptions(_Inout_ MI_Session *session, _Out_ MI_OperationOptions *options)
468 {
469 MI_Application application;
470 MI_Result miResult;
471 MI_Interval timeoutInterval;
472 MI_Uint64 currentTimeout = opts.timeOut;
473
474
475 miResult = MI_Session_GetApplication(session, &application);
476 if (miResult != MI_RESULT_OK)
477 return miResult;
478
479 miResult = MI_Application_NewOperationOptions(&application, MI_FALSE, options);
480 if (miResult != MI_RESULT_OK)
481 return miResult;
482
483 memset(&timeoutInterval, 0, sizeof(timeoutInterval));
484 krisbash 1.1
485 timeoutInterval.microseconds = currentTimeout % 1000000;
486 currentTimeout /= 1000000;
487
488 timeoutInterval.seconds = currentTimeout % 60;
489 currentTimeout /= 60;
490
491 timeoutInterval.minutes = currentTimeout % 60;
492 currentTimeout /= 60;
493
494 timeoutInterval.hours = currentTimeout % 24;
495 currentTimeout /= 24;
496
497 timeoutInterval.days = (MI_Uint32) currentTimeout;
498
499 miResult = MI_OperationOptions_SetTimeout(options, &timeoutInterval);
500 if (miResult != MI_RESULT_OK)
501 {
502 goto cleanup;
503 }
504
505 krisbash 1.1 return miResult;
506
507 cleanup:
508 MI_OperationOptions_Delete(options);
509 memset(options, 0, sizeof(*options));
510 return miResult;
511 }
512
513 void MI_CALL InstanceResults(
514 _In_opt_ MI_Operation *operation,
515 _In_ void *callbackContext,
516 _In_opt_ const MI_Instance *instance,
517 MI_Boolean moreResults,
518 _In_ MI_Result resultCode,
519 _In_opt_z_ const MI_Char *errorString,
520 _In_opt_ const MI_Instance *errorDetails,
521 _In_opt_ MI_Result (MI_CALL * resultAcknowledgement)(_In_ MI_Operation *operation))
522 {
523 if (instance)
524 {
525 s_numInstances++;
526 krisbash 1.1
527 if (!opts.quiet)
528 {
529 Instance_Print(instance, sout, 0, opts.nulls, MI_FALSE);
530 }
531 }
532
533 if (moreResults == MI_FALSE)
534 {
535 if (resultCode != MI_RESULT_OK)
536 {
537 if (!opts.suppressResults)
538 {
539 err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
540 if (errorString)
541 {
542 err(PAL_T("result: %T"), tcs(errorString));
543 }
544 if (errorDetails)
545 {
546 Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
547 krisbash 1.1 }
548 }
549 }
550 s_finalResult = resultCode;
551 s_finished = 1;
552 CondLock_Broadcast((ptrdiff_t)callbackContext);
553 }
554 }
555
556 void MI_CALL IndicationResult(
557 _In_opt_ MI_Operation *operation,
558 _In_ void *callbackContext,
559 _In_opt_ const MI_Instance *instance,
560 _In_opt_z_ const MI_Char *bookmark,
561 _In_opt_z_ const MI_Char *machineID,
562 MI_Boolean moreResults,
563 _In_ MI_Result resultCode,
564 _In_opt_z_ const MI_Char *errorString,
565 _In_opt_ const MI_Instance *errorDetails,
566 _In_opt_ MI_Result (MI_CALL * resultAcknowledgement)(_In_ MI_Operation *operation))
567 {
568 krisbash 1.1 if (instance)
569 {
570 s_numInstances++;
571
572 if (!opts.quiet)
573 {
574 Ftprintf(sout, PAL_T("Async subscribe. Bookmark: %T; MachineID: %T\n"), tcs(bookmark), tcs(machineID));
575 Instance_Print(instance, sout, 0, opts.nulls, MI_FALSE);
576 }
577 }
578
579 if (moreResults == MI_FALSE)
580 {
581 if (resultCode != MI_RESULT_OK)
582 {
583 if (!opts.suppressResults)
584 {
585 err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
586 if (errorString)
587 {
588 err(PAL_T("result: %T"), tcs(errorString));
589 krisbash 1.1 }
590 if (errorDetails)
591 {
592 Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
593 }
594 }
595 }
596 s_finalResult = resultCode;
597 s_finished = 1;
598 CondLock_Broadcast((ptrdiff_t)callbackContext);
599 }
600 }
601
602 static MI_Result ConsumeInstanceResults(MI_Operation *miOperation)
603 {
604 MI_Result miResult;
605
606 if (opts.synchronous == MI_TRUE)
607 {
608 MI_Boolean moreResults = MI_FALSE;
609 do
610 krisbash 1.1 {
611 const MI_Instance *miInstanceResult = NULL;
612 MI_Result _miResult;
613 const MI_Char *errorString = NULL;
614 const MI_Instance *errorDetails = NULL;
615
616 _miResult = MI_Operation_GetInstance(miOperation, &miInstanceResult, &moreResults, &miResult, &errorString, &errorDetails);
617 if (_miResult != MI_RESULT_OK)
618 {
619 miResult = _miResult;
620 }
621 if (miInstanceResult)
622 {
623 s_numInstances++;
624
625 if (!opts.quiet)
626 {
627 Instance_Print(miInstanceResult, sout, 0, opts.nulls, MI_FALSE);
628 }
629 }
630
631 krisbash 1.1 if (moreResults == MI_FALSE)
632 {
633 if (miResult != MI_RESULT_OK)
634 {
635 if (!opts.suppressResults)
636 {
637 err(PAL_T("result: %T"), tcs(Result_ToString(miResult)));
638 if (errorString)
639 {
640 err(PAL_T("result: %T"), tcs(errorString));
641 }
642 if (errorDetails)
643 {
644 Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
645 }
646 }
647 }
648 s_finalResult = miResult;
649 s_finished = 1;
650 }
651
652 krisbash 1.1 } while ((miResult == MI_RESULT_OK) && (moreResults == MI_TRUE));
653 }
654 else
655 {
656 ptrdiff_t finished;
657 finished = s_finished;
658 while (!finished)
659 {
660 CondLock_Wait((ptrdiff_t)&s_finished, &s_finished, finished, CONDLOCK_DEFAULT_SPINCOUNT);
661 finished = s_finished;
662 }
663 miResult = s_finalResult;
664 }
665
666 return miResult;
667 }
668
669
670 static MI_Result ConsumeIndicationsResults(MI_Operation *miOperation)
671 {
672 MI_Result miResult;
673 krisbash 1.1
674 if (opts.synchronous == MI_TRUE)
675 {
676 MI_Boolean moreResults = MI_FALSE;
677 do
678 {
679 const MI_Instance *miInstanceResult = NULL;
680 MI_Result _miResult;
681 const MI_Char *errorString = NULL;
682 const MI_Instance *errorDetails = NULL;
683 const MI_Char *bookmark;
684 const MI_Char *machineid;
685
686 _miResult = MI_Operation_GetIndication(miOperation, &miInstanceResult, &bookmark, &machineid, &moreResults, &miResult, &errorString, &errorDetails);
687 if (_miResult != MI_RESULT_OK)
688 {
689 miResult = _miResult;
690 }
691
692 if (miInstanceResult)
693 {
694 krisbash 1.1 s_numInstances++;
695
696 if (!opts.quiet)
697 {
698 Ftprintf(sout, PAL_T("Sync subscribe. Bookmark: %T; MachineID: %T\n"), tcs(bookmark), tcs(machineid));
699 Instance_Print(miInstanceResult, sout, 0, opts.nulls, MI_FALSE);
700 }
701 }
702
703 if (moreResults == MI_FALSE)
704 {
705 if (miResult != MI_RESULT_OK)
706 {
707 if (!opts.suppressResults)
708 {
709 err(PAL_T("result: %T"), tcs(Result_ToString(miResult)));
710 if (errorString)
711 {
712 err(PAL_T("result: %T"), tcs(errorString));
713 }
714 if (errorDetails)
715 krisbash 1.1 {
716 Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
717 }
718 }
719 }
720 s_finalResult = miResult;
721 s_finished = 1;
722 }
723
724 } while ((miResult == MI_RESULT_OK) && (moreResults == MI_TRUE));
725 }
726 else
727 {
728 ptrdiff_t finished;
729 finished = s_finished;
730 while (!finished)
731 {
732 CondLock_Wait((ptrdiff_t)&s_finished, &s_finished, finished, CONDLOCK_DEFAULT_SPINCOUNT);
733 finished = s_finished;
734 }
735 miResult = s_finalResult;
736 krisbash 1.1 }
737
738 return miResult;
739 }
740
741 void MI_CALL ClassResults(
742 _In_opt_ MI_Operation *operation,
743 _In_ void *callbackContext,
744 _In_opt_ const MI_Class *classObject,
745 MI_Boolean moreResults,
746 _In_ MI_Result resultCode,
747 _In_opt_z_ const MI_Char *errorString,
748 _In_opt_ const MI_Instance *errorDetails,
749 _In_opt_ MI_Result (MI_CALL * resultAcknowledgement)(_In_ MI_Operation *operation))
750 {
751 if (classObject)
752 {
753 s_numInstances++;
754
755 if (!opts.quiet)
756 {
757 krisbash 1.1 MI_Instance *instance;
758 if (Instance_New(&instance, classObject->classDecl, NULL) == MI_RESULT_OK)
759 {
760 Instance_Print(instance, sout, 0, MI_TRUE, MI_TRUE);
761
762 MI_Instance_Delete(instance);
763 }
764 }
765 }
766
767 if (moreResults == MI_FALSE)
768 {
769 if (resultCode != MI_RESULT_OK)
770 {
771 if (!opts.suppressResults)
772 {
773 err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
774 if (errorString)
775 {
776 err(PAL_T("result: %T"), tcs(errorString));
777 }
778 krisbash 1.1 if (errorDetails)
779 {
780 Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
781 }
782 }
783 }
784 s_finalResult = resultCode;
785 s_finished = 1;
786 CondLock_Broadcast((ptrdiff_t)callbackContext);
787 }
788 }
789
790 static MI_Result ConsumeClassResults(MI_Operation *miOperation)
791 {
792 MI_Result miResult;
793
794 if (opts.synchronous == MI_TRUE)
795 {
796 MI_Boolean moreResults = MI_FALSE;
797 do
798 {
799 krisbash 1.1 const MI_Class *miClassResult = NULL;
800 MI_Result _miResult;
801 const MI_Char *errorString = NULL;
802 const MI_Instance *errorDetails = NULL;
803
804 _miResult = MI_Operation_GetClass(miOperation, &miClassResult, &moreResults, &miResult, &errorString, &errorDetails);
805 if (_miResult != MI_RESULT_OK)
806 {
807 miResult = _miResult;
808 }
809 if (miClassResult)
810 {
811 s_numInstances++;
812
813 if (!opts.quiet)
814 {
815 MI_Instance *instance;
816 if (Instance_New(&instance, miClassResult->classDecl, NULL) == MI_RESULT_OK)
817 {
818 Instance_Print(instance, sout, 0, MI_TRUE, MI_TRUE);
819
820 krisbash 1.1 MI_Instance_Delete(instance);
821 }
822 }
823 }
824
825 if (moreResults == MI_FALSE)
826 {
827 if (miResult != MI_RESULT_OK)
828 {
829 if (!opts.suppressResults)
830 {
831 err(PAL_T("result: %T"), tcs(Result_ToString(miResult)));
832 if (errorString)
833 {
834 err(PAL_T("result: %T"), tcs(errorString));
835 }
836 if (errorDetails)
837 {
838 Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
839 }
840 }
841 krisbash 1.1 }
842 s_finalResult = miResult;
843 s_finished = 1;
844 }
845
846 } while ((miResult == MI_RESULT_OK) && (moreResults == MI_TRUE));
847 }
848 else
849 {
850 ptrdiff_t finished;
851 finished = s_finished;
852 while (!finished)
853 {
854 CondLock_Wait((ptrdiff_t)&s_finished, &s_finished, finished, CONDLOCK_DEFAULT_SPINCOUNT);
855 finished = s_finished;
856 }
857 miResult = s_finalResult;
858 }
859
860 return miResult;
861 }
862 krisbash 1.1
863
864 void MI_CALL NoOpResults(
865 _In_opt_ MI_Operation *operation,
866 _In_ void *callbackContext,
867 _In_opt_ const MI_Instance *instance,
868 MI_Boolean moreResults,
869 _In_ MI_Result resultCode,
870 _In_opt_z_ const MI_Char *errorString,
871 _In_opt_ const MI_Instance *errorDetails,
872 _In_opt_ MI_Result (MI_CALL * resultAcknowledgement)(_In_ MI_Operation *operation))
873 {
874 if (instance)
875 {
876 s_numInstances++;
877
878 if (!opts.quiet)
879 {
880 Instance_Print(instance, sout, 0, opts.nulls, MI_FALSE);
881 }
882 }
883 krisbash 1.1
884 if (moreResults == MI_FALSE)
885 {
886 if (resultCode != MI_RESULT_OK)
887 {
888 if (!opts.suppressResults)
889 {
890 err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
891 if (errorString)
892 {
893 err(PAL_T("result: %T"), tcs(errorString));
894 }
895 if (errorDetails)
896 {
897 Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
898 }
899 }
900 }
901 else
902 {
903 Ftprintf(sout, PAL_T("got noop response\n"));
904 krisbash 1.1
905 }
906 s_finalResult = resultCode;
907 s_finished = 1;
908 CondLock_Broadcast((ptrdiff_t)callbackContext);
909 }
910 }
911
912
913 static MI_Result NoOp(MI_Session *miSession, int argc, const MI_Char* argv [])
914 {
915 MI_Result miResult;
916 MI_Operation miOperation = MI_OPERATION_NULL;
917 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
918 MI_OperationCallbacks *callbacks = NULL;
919 MI_Uint32 flags = 0;
920
921 MI_UNUSED(argv);
922
923 if (argc != 2)
924 {
925 krisbash 1.1 Ftprintf(serr, MI_T("Usage: %s noop\n\n"), tcs(arg0));
926 return MI_RESULT_INVALID_PARAMETER;
927 }
928
929 if (opts.synchronous == MI_FALSE)
930 {
931 _callbacks.callbackContext = &s_finished;
932 _callbacks.instanceResult = NoOpResults;
933 callbacks = &_callbacks;
934 s_finished = 0;
935 }
936
937
938 MI_Session_TestConnection(miSession, flags, callbacks, &miOperation);
939
940 miResult = ConsumeInstanceResults(&miOperation);
941
942 MI_Operation_Close(&miOperation);
943
944 return miResult;
945 }
946 krisbash 1.1
947 static MI_Result EnumerateInstances(MI_Session *miSession, int argc, const MI_Char* argv[])
948 {
949 MI_Result miResult;
950 MI_OperationOptions miOperationOptions;
951 MI_Operation miOperation = MI_OPERATION_NULL;
952 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
953 MI_OperationCallbacks *callbacks = NULL;
954 MI_Uint32 flags = 0;
955
956 if (argc != 4)
957 {
958 Ftprintf(serr, MI_T("Usage: %s ei NAMESPACE CLASSNAME\n\n"), tcs(arg0));
959 return MI_RESULT_INVALID_PARAMETER;
960 }
961
962 if (opts.shallow)
963 {
964 flags = MI_OPERATIONFLAGS_POLYMORPHISM_SHALLOW;
965 }
966
967 krisbash 1.1 if (opts.synchronous == MI_FALSE)
968 {
969 _callbacks.callbackContext = &s_finished;
970 _callbacks.instanceResult = InstanceResults;
971 callbacks = &_callbacks;
972 s_finished = 0;
973 }
974
975 miResult = CreateOperationOptions(miSession, &miOperationOptions);
976 if (miResult != MI_RESULT_OK)
977 return miResult;
978
979 MI_Session_EnumerateInstances(miSession, flags, &miOperationOptions, argv[2], argv[3], MI_FALSE, callbacks, &miOperation);
980
981 miResult = ConsumeInstanceResults(&miOperation);
982
983 MI_Operation_Close(&miOperation);
984
985 MI_OperationOptions_Delete(&miOperationOptions);
986
987 return miResult;
988 krisbash 1.1 }
989
990 static MI_Result QueryInstances(MI_Session *miSession, int argc, const MI_Char* argv[])
991 {
992 MI_Result miResult;
993 MI_OperationOptions miOperationOptions;
994 MI_Operation miOperation = MI_OPERATION_NULL;
995 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
996 MI_OperationCallbacks *callbacks = NULL;
997
998 if (argc != 4)
999 {
1000 Ftprintf(serr, MI_T("Usage: %s ei NAMESPACE CLASSNAME\n\n"), tcs(arg0));
1001 return MI_RESULT_INVALID_PARAMETER;
1002 }
1003
1004 if (opts.synchronous == MI_FALSE)
1005 {
1006 _callbacks.callbackContext = &s_finished;
1007 _callbacks.instanceResult = InstanceResults;
1008 callbacks = &_callbacks;
1009 krisbash 1.1 s_finished = 0;
1010 }
1011
1012 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1013 if (miResult != MI_RESULT_OK)
1014 return miResult;
1015
1016 MI_Session_QueryInstances(miSession, 0, &miOperationOptions, argv[2], opts.querylang, opts.queryexpr, callbacks, &miOperation);
1017
1018 miResult = ConsumeInstanceResults(&miOperation);
1019
1020 MI_Operation_Close(&miOperation);
1021
1022 MI_OperationOptions_Delete(&miOperationOptions);
1023
1024 return miResult;
1025 }
1026
1027 static MI_Result Query(MI_Session *miSession, int argc, const MI_Char* argv[])
1028 {
1029 MI_Result miResult;
1030 krisbash 1.1 MI_OperationOptions miOperationOptions;
1031 MI_Operation miOperation = MI_OPERATION_NULL;
1032 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1033 MI_OperationCallbacks *callbacks = NULL;
1034 const MI_Char* dialect = NULL;
1035
1036 if (argc != 4)
1037 {
1038 Ftprintf(serr, PAL_T("Usage: %T %T NAMESPACE QUERY\n\n"), tcs(arg0),
1039 tcs(argv[1]));
1040 return MI_RESULT_INVALID_PARAMETER;
1041 }
1042
1043 if (opts.synchronous == MI_FALSE)
1044 {
1045 _callbacks.callbackContext = &s_finished;
1046 _callbacks.instanceResult = InstanceResults;
1047 callbacks = &_callbacks;
1048 s_finished = 0;
1049 }
1050
1051 krisbash 1.1 // Determine query dialect:
1052 if (Tcscmp(argv[1], MI_T("wql")) == 0)
1053 {
1054 dialect = MI_T("WQL");
1055 }
1056 else if (Tcscmp(argv[1], MI_T("cql")) == 0)
1057 {
1058 dialect = MI_T("CQL");
1059 }
1060 else
1061 {
1062 err(MI_T("invalid query dialect: %T"), tcs(argv[1]));
1063 }
1064
1065 // Extract query options.
1066 opts.queryexpr = argv[3];
1067
1068 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1069 if (miResult != MI_RESULT_OK)
1070 return miResult;
1071
1072 krisbash 1.1 MI_Session_QueryInstances(miSession, 0, &miOperationOptions, argv[2], dialect, argv[3], callbacks, &miOperation);
1073
1074 miResult = ConsumeInstanceResults(&miOperation);
1075
1076 MI_Operation_Close(&miOperation);
1077
1078 MI_OperationOptions_Delete(&miOperationOptions);
1079
1080 return miResult;
1081 }
1082
1083 static MI_Result GetInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1084 {
1085 MI_Result miResult;
1086 MI_OperationOptions miOperationOptions;
1087 MI_Operation miOperation = MI_OPERATION_NULL;
1088 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1089 MI_OperationCallbacks *callbacks = NULL;
1090 MI_Instance *instance;
1091 const MI_Char *nameSpace;
1092 const MI_Char** p;
1093 krisbash 1.1 const MI_Char** end;
1094
1095 if (argc < 4)
1096 {
1097 Ftprintf(serr, MI_T("Usage: %s gi NAMESPACE INSTANCENAME\n\n"), tcs(arg0));
1098 return MI_RESULT_INVALID_PARAMETER;
1099 }
1100
1101 nameSpace = argv[2];
1102 argc -= 3;
1103 argv += 3;
1104 p = argv;
1105 end = p + argc;
1106
1107 if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1108 {
1109 err(MI_T("invalid instance name specification"));
1110 return MI_RESULT_FAILED;
1111 }
1112
1113 if (p != end)
1114 krisbash 1.1 {
1115 err(MI_T("extraneous arguments after instance name"));
1116 return MI_RESULT_INVALID_PARAMETER;
1117 }
1118
1119
1120 if (opts.synchronous == MI_FALSE)
1121 {
1122 _callbacks.callbackContext = &s_finished;
1123 _callbacks.instanceResult = InstanceResults;
1124 callbacks = &_callbacks;
1125 s_finished = 0;
1126 }
1127
1128 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1129 if (miResult != MI_RESULT_OK)
1130 return miResult;
1131
1132 MI_Session_GetInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1133
1134 miResult = ConsumeInstanceResults(&miOperation);
1135 krisbash 1.1
1136 MI_Operation_Close(&miOperation);
1137
1138 MI_Instance_Delete(instance);
1139
1140 MI_OperationOptions_Delete(&miOperationOptions);
1141
1142 return miResult;
1143 }
1144
1145
1146 static MI_Result CreateInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1147 {
1148 MI_Result miResult;
1149 MI_OperationOptions miOperationOptions;
1150 MI_Operation miOperation = MI_OPERATION_NULL;
1151 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1152 MI_OperationCallbacks *callbacks = NULL;
1153 MI_Instance *instance;
1154 const MI_Char *nameSpace;
1155 const MI_Char** p;
1156 krisbash 1.1 const MI_Char** end;
1157
1158 if (argc < 4)
1159 {
1160 Ftprintf(serr, MI_T("Usage: %s ci NAMESPACE INSTANCE\n\n"), tcs(arg0));
1161 return MI_RESULT_INVALID_PARAMETER;
1162 }
1163
1164 nameSpace = argv[2];
1165 argc -= 3;
1166 argv += 3;
1167 p = argv;
1168 end = p + argc;
1169
1170 if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1171 {
1172 err(PAL_T("invalid instance name specification"));
1173 return MI_RESULT_FAILED;
1174 }
1175
1176 if (p != end)
1177 krisbash 1.1 {
1178 err(PAL_T("extraneous arguments after instance name"));
1179 return MI_RESULT_INVALID_PARAMETER;
1180 }
1181
1182 if (opts.synchronous == MI_FALSE)
1183 {
1184 _callbacks.callbackContext = &s_finished;
1185 _callbacks.instanceResult = InstanceResults;
1186 callbacks = &_callbacks;
1187 s_finished = 0;
1188 }
1189
1190 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1191 if (miResult != MI_RESULT_OK)
1192 return miResult;
1193
1194 MI_Session_CreateInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1195
1196 miResult = ConsumeInstanceResults(&miOperation);
1197
1198 krisbash 1.1 MI_Operation_Close(&miOperation);
1199
1200 MI_Instance_Delete(instance);
1201
1202 MI_OperationOptions_Delete(&miOperationOptions);
1203
1204 return miResult;
1205
1206 }
1207
1208 static MI_Result ModifyInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1209 {
1210 MI_Result miResult;
1211 MI_OperationOptions miOperationOptions;
1212 MI_Operation miOperation = MI_OPERATION_NULL;
1213 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1214 MI_OperationCallbacks *callbacks = NULL;
1215 MI_Instance *instance;
1216 const MI_Char *nameSpace;
1217 const MI_Char** p;
1218 const MI_Char** end;
1219 krisbash 1.1
1220 if (argc < 4)
1221 {
1222 Ftprintf(serr, MI_T("Usage: %s mi NAMESPACE INSTANCE\n\n"), tcs(arg0));
1223 return MI_RESULT_INVALID_PARAMETER;
1224 }
1225
1226 nameSpace = argv[2];
1227 argc -= 3;
1228 argv += 3;
1229 p = argv;
1230 end = p + argc;
1231
1232 if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1233 {
1234 err(PAL_T("invalid instance name specification"));
1235 return MI_RESULT_FAILED;
1236 }
1237
1238 if (p != end)
1239 {
1240 krisbash 1.1 err(PAL_T("extraneous arguments after instance name"));
1241 return MI_RESULT_INVALID_PARAMETER;
1242 }
1243
1244 if (opts.synchronous == MI_FALSE)
1245 {
1246 _callbacks.callbackContext = &s_finished;
1247 _callbacks.instanceResult = InstanceResults;
1248 callbacks = &_callbacks;
1249 s_finished = 0;
1250 }
1251
1252
1253 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1254 if (miResult != MI_RESULT_OK)
1255 return miResult;
1256
1257 MI_Session_ModifyInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1258
1259 miResult = ConsumeInstanceResults(&miOperation);
1260
1261 krisbash 1.1 MI_Operation_Close(&miOperation);
1262
1263 MI_Instance_Delete(instance);
1264
1265 MI_OperationOptions_Delete(&miOperationOptions);
1266
1267 return miResult;
1268
1269 }
1270
1271 static MI_Result DeleteInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1272 {
1273 MI_Result miResult;
1274 MI_OperationOptions miOperationOptions;
1275 MI_Operation miOperation = MI_OPERATION_NULL;
1276 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1277 MI_OperationCallbacks *callbacks = NULL;
1278 MI_Instance *instance;
1279 const MI_Char *nameSpace;
1280 const MI_Char** p;
1281 const MI_Char** end;
1282 krisbash 1.1
1283 if (argc < 4)
1284 {
1285 Ftprintf(serr, MI_T("Usage: %s di NAMESPACE INSTANCE\n\n"), tcs(arg0));
1286 return MI_RESULT_INVALID_PARAMETER;
1287 }
1288
1289 nameSpace = argv[2];
1290 argc -= 3;
1291 argv += 3;
1292 p = argv;
1293 end = p + argc;
1294
1295 if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1296 {
1297 err(PAL_T("invalid instance name specification"));
1298 return MI_RESULT_FAILED;
1299 }
1300
1301 if (p != end)
1302 {
1303 krisbash 1.1 err(PAL_T("extraneous arguments after instance name"));
1304 return MI_RESULT_INVALID_PARAMETER;
1305 }
1306
1307 if (opts.synchronous == MI_FALSE)
1308 {
1309 _callbacks.callbackContext = &s_finished;
1310 _callbacks.instanceResult = InstanceResults;
1311 callbacks = &_callbacks;
1312 s_finished = 0;
1313 }
1314
1315
1316 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1317 if (miResult != MI_RESULT_OK)
1318 return miResult;
1319
1320 MI_Session_DeleteInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1321
1322 miResult = ConsumeInstanceResults(&miOperation);
1323
1324 krisbash 1.1 MI_Operation_Close(&miOperation);
1325
1326 MI_Instance_Delete(instance);
1327
1328 MI_OperationOptions_Delete(&miOperationOptions);
1329
1330 return miResult;
1331
1332 }
1333
1334 static MI_Result Associators(MI_Session *miSession, int argc, const MI_Char* argv[])
1335 {
1336 MI_Result miResult;
1337 MI_OperationOptions miOperationOptions;
1338 MI_Operation miOperation = MI_OPERATION_NULL;
1339 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1340 MI_OperationCallbacks *callbacks = NULL;
1341 MI_Instance *instance;
1342 const MI_Char *nameSpace;
1343 const MI_Char** p;
1344 const MI_Char** end;
1345 krisbash 1.1
1346 if (argc < 4)
1347 {
1348 Ftprintf(serr, MI_T("Usage: %s a NAMESPACE INSTANCE\n\n"), tcs(arg0));
1349 return MI_RESULT_INVALID_PARAMETER;
1350 }
1351
1352 nameSpace = argv[2];
1353 argc -= 3;
1354 argv += 3;
1355 p = argv;
1356 end = p + argc;
1357
1358 if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1359 {
1360 err(PAL_T("invalid instance name specification"));
1361 return MI_RESULT_FAILED;
1362 }
1363
1364 if (p != end)
1365 {
1366 krisbash 1.1 err(PAL_T("extraneous arguments after instance name"));
1367 return MI_RESULT_INVALID_PARAMETER;
1368 }
1369
1370 if (opts.synchronous == MI_FALSE)
1371 {
1372 _callbacks.callbackContext = &s_finished;
1373 _callbacks.instanceResult = InstanceResults;
1374 callbacks = &_callbacks;
1375 s_finished = 0;
1376 }
1377
1378
1379 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1380 if (miResult != MI_RESULT_OK)
1381 return miResult;
1382
1383 MI_Session_AssociatorInstances(miSession, 0, &miOperationOptions, nameSpace, instance, opts.assocClass, opts.resultClass, opts.role, opts.resultRole, MI_FALSE, callbacks, &miOperation);
1384
1385 miResult = ConsumeInstanceResults(&miOperation);
1386
1387 krisbash 1.1 MI_Operation_Close(&miOperation);
1388
1389 MI_Instance_Delete(instance);
1390
1391 MI_OperationOptions_Delete(&miOperationOptions);
1392
1393 return miResult;
1394 }
1395
1396 static MI_Result References(MI_Session *miSession, int argc, const MI_Char* argv[])
1397 {
1398 MI_Result miResult;
1399 MI_OperationOptions miOperationOptions;
1400 MI_Operation miOperation = MI_OPERATION_NULL;
1401 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1402 MI_OperationCallbacks *callbacks = NULL;
1403 MI_Instance *instance;
1404 const MI_Char *nameSpace;
1405 const MI_Char** p;
1406 const MI_Char** end;
1407
1408 krisbash 1.1 if (argc < 4)
1409 {
1410 Ftprintf(serr, MI_T("Usage: %T d NAMESPACE INSTANCE\n\n"), tcs(arg0));
1411 return MI_RESULT_INVALID_PARAMETER;
1412 }
1413
1414 nameSpace = argv[2];
1415 argc -= 3;
1416 argv += 3;
1417 p = argv;
1418 end = p + argc;
1419
1420 if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1421 {
1422 err(PAL_T("invalid instance name specification"));
1423 return MI_RESULT_FAILED;
1424 }
1425
1426 if (p != end)
1427 {
1428 err(PAL_T("extraneous arguments after instance name"));
1429 krisbash 1.1 return MI_RESULT_INVALID_PARAMETER;
1430 }
1431
1432 if (opts.synchronous == MI_FALSE)
1433 {
1434 _callbacks.callbackContext = &s_finished;
1435 _callbacks.instanceResult = InstanceResults;
1436 callbacks = &_callbacks;
1437 s_finished = 0;
1438 }
1439
1440
1441 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1442 if (miResult != MI_RESULT_OK)
1443 return miResult;
1444
1445 MI_Session_ReferenceInstances(miSession, 0, &miOperationOptions, nameSpace, instance, opts.resultClass, opts.role, MI_FALSE, callbacks, &miOperation);
1446
1447 miResult = ConsumeInstanceResults(&miOperation);
1448
1449 MI_Operation_Close(&miOperation);
1450 krisbash 1.1
1451 MI_Instance_Delete(instance);
1452
1453 MI_OperationOptions_Delete(&miOperationOptions);
1454
1455 return miResult;
1456 }
1457
1458 static MI_Result Invoke(MI_Session *miSession, int argc, const MI_Char* argv[])
1459 {
1460 MI_Result miResult;
1461 MI_OperationOptions miOperationOptions;
1462 MI_Operation miOperation = MI_OPERATION_NULL;
1463 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1464 MI_OperationCallbacks *callbacks = NULL;
1465 MI_Instance *instance;
1466 MI_Instance *inParams = NULL;
1467 const MI_Char *nameSpace;
1468 const MI_Char *methodName;
1469 const MI_Char** p;
1470 const MI_Char** end;
1471 krisbash 1.1 MI_Uint32 elementCount = 0;
1472
1473 if (argc < 5)
1474 {
1475 Ftprintf(serr,
1476 PAL_T("Usage: %s iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\n"),
1477 tcs(arg0));
1478 return MI_RESULT_INVALID_PARAMETER;
1479 }
1480
1481 nameSpace = argv[2];
1482 argc -= 3;
1483 argv += 3;
1484 p = argv;
1485 end = p + argc;
1486
1487 if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1488 {
1489 err(PAL_T("invalid instance name specification"));
1490 return MI_RESULT_FAILED;
1491 }
1492 krisbash 1.1
1493 if (p == end)
1494 {
1495 err(PAL_T("expected method name"));
1496 MI_Instance_Delete(instance);
1497 return MI_RESULT_INVALID_PARAMETER;
1498 }
1499
1500 methodName = *p;
1501 p++;
1502
1503 if (p != end)
1504 {
1505 if (!ArgsToInstance(&p, end, MI_FLAG_METHOD, MI_TRUE, &inParams))
1506 {
1507 err(PAL_T("invalid instance name specification"));
1508 MI_Instance_Delete(instance);
1509 return MI_RESULT_FAILED;
1510 }
1511 }
1512
1513 krisbash 1.1 if (opts.synchronous == MI_FALSE)
1514 {
1515 _callbacks.callbackContext = &s_finished;
1516 _callbacks.instanceResult = InstanceResults;
1517 callbacks = &_callbacks;
1518 s_finished = 0;
1519 }
1520
1521 if (MI_Instance_GetElementCount(instance, &elementCount) != MI_RESULT_OK)
1522 {
1523 err(PAL_T("Failed to get element count for instance"));
1524 MI_Instance_Delete(instance);
1525 MI_Instance_Delete(inParams);
1526 return MI_RESULT_FAILED;
1527 }
1528
1529 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1530 if (miResult != MI_RESULT_OK)
1531 {
1532 MI_Instance_Delete(instance);
1533 MI_Instance_Delete(inParams);
1534 krisbash 1.1 return miResult;
1535 }
1536
1537 if (elementCount)
1538 {
1539 MI_Session_Invoke(miSession, 0, NULL, nameSpace, instance->classDecl->name, methodName, instance, inParams, callbacks, &miOperation);
1540 }
1541 else
1542 {
1543 /* Static method */
1544 MI_Session_Invoke(miSession, 0, &miOperationOptions, nameSpace, instance->classDecl->name, methodName, NULL, inParams, callbacks, &miOperation);
1545 }
1546
1547 miResult = ConsumeInstanceResults(&miOperation);
1548
1549 MI_Operation_Close(&miOperation);
1550
1551 MI_Instance_Delete(instance);
1552 if (inParams)
1553 MI_Instance_Delete(inParams);
1554 MI_OperationOptions_Delete(&miOperationOptions);
1555 krisbash 1.1
1556 return miResult;
1557 }
1558
1559 static MI_Result GetClass(MI_Session *miSession, int argc, const MI_Char* argv[])
1560 {
1561 MI_Result miResult;
1562 MI_OperationOptions miOperationOptions;
1563 MI_Operation miOperation = MI_OPERATION_NULL;
1564 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1565 MI_OperationCallbacks *callbacks = NULL;
1566 const MI_Char *nameSpace;
1567 const MI_Char *className;
1568
1569 if (argc != 4)
1570 {
1571 Ftprintf(serr, MI_T("Usage: %s gc NAMESPACE CLASSNAME\n\n"), tcs(arg0));
1572 return MI_RESULT_INVALID_PARAMETER;
1573 }
1574
1575 nameSpace = argv[2];
1576 krisbash 1.1 className = argv[3];
1577
1578 if (opts.synchronous == MI_FALSE)
1579 {
1580 _callbacks.callbackContext = &s_finished;
1581 _callbacks.classResult = ClassResults;
1582 callbacks = &_callbacks;
1583 s_finished = 0;
1584 }
1585
1586
1587 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1588 if (miResult != MI_RESULT_OK)
1589 return miResult;
1590
1591 MI_Session_GetClass(miSession, 0, &miOperationOptions, nameSpace, className, callbacks, &miOperation);
1592
1593 miResult = ConsumeClassResults(&miOperation);
1594
1595 MI_Operation_Close(&miOperation);
1596
1597 krisbash 1.1 MI_OperationOptions_Delete(&miOperationOptions);
1598
1599 return miResult;
1600 }
1601
1602 static MI_Result Subscribe(MI_Session *miSession, int argc, const MI_Char* argv[])
1603 {
1604 MI_Result miResult;
1605 MI_OperationOptions miOperationOptions;
1606 MI_Operation miOperation = MI_OPERATION_NULL;
1607 MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1608 MI_OperationCallbacks *callbacks = NULL;
1609 const MI_Char *nameSpace;
1610
1611 if (argc != 3 || opts.querylang == NULL || opts.queryexpr == NULL)
1612 {
1613 Ftprintf(serr, MI_T("Usage: %s [--querylang 'WQL/CQL' --queryexpr ] sub NAMESPACE\n\n"), tcs(arg0));
1614 return MI_RESULT_INVALID_PARAMETER;
1615 }
1616
1617 if (opts.synchronous == MI_FALSE)
1618 krisbash 1.1 {
1619 _callbacks.callbackContext = &s_finished;
1620 _callbacks.indicationResult = IndicationResult;
1621 callbacks = &_callbacks;
1622 s_finished = 0;
1623 }
1624
1625 nameSpace = argv[2];
1626
1627 miResult = CreateOperationOptions(miSession, &miOperationOptions);
1628 if (miResult != MI_RESULT_OK)
1629 {
1630 Ftprintf(serr, MI_T("Failed to create MI_OperationOptions, error code(%d)\n\n"), miResult);
1631 return miResult;
1632 }
1633
1634 MI_Session_Subscribe(miSession, 0, &miOperationOptions, nameSpace, opts.querylang, opts.queryexpr, NULL, callbacks, &miOperation);
1635
1636 /* Duplicate operation */
1637 memcpy(&gop, &miOperation, sizeof(MI_Operation));
1638
1639 krisbash 1.1 miResult = ConsumeIndicationsResults(&miOperation);
1640
1641 /* Cleanup global operation since it is done */
1642 memset(&gop, 0, sizeof(MI_Operation));
1643
1644 MI_Operation_Close(&miOperation);
1645
1646 MI_OperationOptions_Delete(&miOperationOptions);
1647
1648 return miResult;
1649 }
1650
1651 static MI_Result FindConfigFile(_Pre_writable_size_(PAL_MAX_PATH_SIZE) char path[PAL_MAX_PATH_SIZE])
1652 {
1653 char* home;
1654 /* Look in current directory */
1655 {
1656 Strlcpy(path, "./.omiclirc", PAL_MAX_PATH_SIZE);
1657
1658 if (access(path, R_OK) == 0)
1659 return MI_RESULT_OK;
1660 krisbash 1.1 }
1661
1662 /* Look in HOME directory */
1663 home = getenv("HOME");
1664 if (home)
1665 {
1666 Strlcpy(path, home, PAL_MAX_PATH_SIZE);
1667 Strlcat(path, "/.omiclirc", PAL_MAX_PATH_SIZE);
1668
1669 if (access(path, R_OK) == 0)
1670 {
1671 return MI_RESULT_OK;
1672 }
1673 }
1674
1675 /* Look in system config directory */
1676 {
1677 Strlcpy(path, OMI_GetPath(ID_SYSCONFDIR), PAL_MAX_PATH_SIZE);
1678 Strlcat(path, "/omicli.conf", PAL_MAX_PATH_SIZE);
1679
1680 if (access(path, R_OK) == 0)
1681 krisbash 1.1 return MI_RESULT_OK;
1682 }
1683
1684 /* Not found */
1685 return MI_RESULT_FAILED;
1686 }
1687
1688 static MI_Result GetConfigFileOptions()
1689 {
1690 char path[PAL_MAX_PATH_SIZE];
1691 Conf* conf;
1692 MI_Result miResult = MI_RESULT_OK;
1693
1694 /* Form the configuration file path (silently ignore if not found) */
1695 if (FindConfigFile(path) != 0)
1696 return MI_RESULT_OK;
1697
1698 /* Open the configuration file */
1699 conf = Conf_Open(path);
1700 if (!conf)
1701 {
1702 krisbash 1.1 err(PAL_T("failed to open configuration file: %s"), scs(path));
1703 return MI_RESULT_FAILED;
1704 }
1705
1706 /* For each key=value pair in configuration file */
1707 for (;;)
1708 {
1709 const char* key;
1710 const char* value;
1711 int r = Conf_Read(conf, &key, &value);
1712
1713 if (r == -1)
1714 {
1715 err(PAL_T("%s: %s\n"), scs(path), scs(Conf_Error(conf)));
1716 miResult = MI_RESULT_FAILED;
1717 goto cleanup;
1718 }
1719
1720 if (r == 1)
1721 break;
1722
1723 krisbash 1.1 if (strcmp(key, "httpport") == 0)
1724 {
1725 char* end;
1726 unsigned long x = Strtoul(value, &end, 10);
1727
1728 if (*end != '\0' || x > USHRT_MAX)
1729 {
1730 err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path),
1731 Conf_Line(conf), scs(key), scs(value));
1732 miResult = MI_RESULT_FAILED;
1733 goto cleanup;
1734 }
1735
1736 opts.httpport = (unsigned short)x;
1737 }
1738 else if (strcmp(key, "httpsport") == 0)
1739 {
1740 char* end;
1741 unsigned long x = Strtoul(value, &end, 10);
1742
1743 if (*end != '\0' || x > USHRT_MAX)
1744 krisbash 1.1 {
1745 err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path),
1746 Conf_Line(conf), scs(key), scs(value));
1747 miResult = MI_RESULT_FAILED;
1748 goto cleanup;
1749 }
1750
1751 opts.httpsport = (unsigned short)x;
1752 }
1753 else if (strcmp(key, "trace") == 0)
1754 {
1755 if (Strcasecmp(value, "MI_TRUE") == 0)
1756 {
1757 opts.trace = MI_TRUE;
1758 }
1759 else if (Strcasecmp(value, "MI_FALSE") == 0)
1760 {
1761 opts.trace = MI_FALSE;
1762 }
1763 else
1764 {
1765 krisbash 1.1 err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path),
1766 Conf_Line(conf), scs(key), scs(value));
1767 miResult = MI_RESULT_FAILED;
1768 goto cleanup;
1769 }
1770 }
1771 else if (strcmp(key, "protocolhandler") == 0)
1772 {
1773 /* This is used in the miapi itself */
1774 }
1775 if (strcmp(key, "loglevel") == 0)
1776 {
1777 if (Log_SetLevelFromString(value) != 0)
1778 {
1779 err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path),
1780 Conf_Line(conf), scs(key), scs(value));
1781 miResult = MI_RESULT_FAILED;
1782 goto cleanup;
1783 }
1784 }
1785 else if (strcmp(key, "logpath") == 0)
1786 krisbash 1.1 {
1787 /* TODO - this is just a test tool? */
1788 }
1789 else if (strcmp(key, "logfile") == 0)
1790 {
1791 /* TODO - this is just a test tool? */
1792 }
1793 else if (IsNickname(key))
1794 {
1795 if (SetPathFromNickname(key, value) != 0)
1796 {
1797 err(PAL_T("SetPathFromNickname() failed"));
1798 miResult = MI_RESULT_FAILED;
1799 goto cleanup;
1800 }
1801 }
1802 else
1803 {
1804 err(PAL_T("%s(%u): unknown key: %s"), scs(path), Conf_Line(conf),
1805 scs(key));
1806 miResult = MI_RESULT_FAILED;
1807 krisbash 1.1 goto cleanup;
1808 }
1809 }
1810
1811 cleanup:
1812 /* Close configuration file */
1813 Conf_Close(conf);
1814 return miResult;
1815 }
1816
1817 static MI_Result GetCommandLineDestDirOption(
1818 int* argc_,
1819 const MI_Char* argv[])
1820 {
1821 int argc = *argc_;
1822 int i;
1823 const MI_Char* destdir = NULL;
1824 const MI_Char* socketfile = NULL;
1825
1826 for (i = 1; i < argc; )
1827 {
1828 krisbash 1.1 if (Tcscmp(argv[i], MI_T("--destdir")) == 0)
1829 {
1830 if (i + 1 == argc)
1831 {
1832 err(PAL_T("missing argument for --destdir option"));
1833 return MI_RESULT_INVALID_PARAMETER;
1834 }
1835
1836 destdir = argv[i+1];
1837 memmove((char*)&argv[i], (char*)&argv[i+2],
1838 sizeof(char*) * (argc-i-1));
1839 argc -= 2;
1840 }
1841 else if (Tcsncmp(argv[i], MI_T("--destdir="), 10) == 0)
1842 {
1843 destdir = argv[i] + 10;
1844 memmove((char*)&argv[i], (char*)&argv[i+1],
1845 sizeof(char*) * (argc-i));
1846
1847 argc -= 1;
1848 }
1849 krisbash 1.1 if (Tcscmp(argv[i], MI_T("--socketfile")) == 0)
1850 {
1851 if (i + 1 == argc)
1852 {
1853 err(PAL_T("missing argument for --socketfile option"));
1854 return MI_RESULT_INVALID_PARAMETER;
1855 }
1856
1857 socketfile = argv[i+1];
1858 memmove((char*)&argv[i], (char*)&argv[i+2],
1859 sizeof(char*) * (argc-i-1));
1860 argc -= 2;
1861 }
1862 else if (Tcsncmp(argv[i], MI_T("--socketfile="), 13) == 0)
1863 {
1864 socketfile = argv[i] + 13;
1865 memmove((char*)&argv[i], (char*)&argv[i+1],
1866 sizeof(char*) * (argc-i));
1867
1868 argc -= 1;
1869 }
1870 krisbash 1.1 else
1871 i++;
1872 }
1873
1874 if (destdir)
1875 {
1876 #if defined(CONFIG_ENABLE_WCHAR)
1877 char _destdir[PAL_MAX_PATH_SIZE];
1878 StrWcslcpy(_destdir, destdir, PAL_MAX_PATH_SIZE);
1879 if (SetPath(ID_DESTDIR, _destdir) != 0)
1880 #else
1881 if (SetPath(ID_DESTDIR, destdir) != 0)
1882 #endif
1883 {
1884 err(PAL_T("failed to set destdir"));
1885 return MI_RESULT_FAILED;
1886 }
1887 }
1888
1889 if (socketfile)
1890 {
1891 krisbash 1.1 #if defined(CONFIG_ENABLE_WCHAR)
1892 char _socketfile[PAL_MAX_PATH_SIZE];
1893 StrWcslcpy(_socketfile, socketfile, PAL_MAX_PATH_SIZE);
1894 if (SetPath(ID_SOCKETFILE, _socketfile) != 0)
1895 #else
1896 if (SetPath(ID_SOCKETFILE, socketfile) != 0)
1897 #endif
1898 {
1899 err(PAL_T("failed to set socketfile"));
1900 return MI_RESULT_FAILED;
1901 }
1902 }
1903
1904 *argc_ = argc;
1905
1906 return MI_RESULT_OK;
1907 }
1908
1909 #define GETOPTSTATE_INITIALIZER { 0, { '\0' }, NULL, { '\0' } }
1910 #define GETOPT_OPT_SIZE 512
1911 #define GETOPT_ERR_SIZE 512
1912 krisbash 1.1
1913 typedef struct _GetOptState
1914 {
1915 int index;
1916 MI_Char opt[GETOPT_OPT_SIZE];
1917 const MI_Char* arg;
1918 MI_Char err[GETOPT_ERR_SIZE];
1919 }
1920 GetOptState;
1921
1922 static int GetOpt(
1923 int* argc,
1924 const MI_Char* argv[],
1925 const MI_Char* opts[],
1926 GetOptState* state)
1927 {
1928 int i;
1929 int j;
1930
1931 /* Clear state */
1932 state->opt[0] = '\0';
1933 krisbash 1.1 state->arg = NULL;
1934 state->err[0] = '\0';
1935
1936 for (i = state->index; i < *argc; i++)
1937 {
1938 if (argv[i][0] != '-')
1939 {
1940 state->index++;
1941 continue;
1942 }
1943
1944 /* Find option argv[i] */
1945 for (j = 0; opts[j]; j++)
1946 {
1947 MI_Char opt[GETOPT_OPT_SIZE];
1948 size_t n;
1949 int hasArg;
1950
1951 /* Copy option name */
1952 n = Tcslcpy(opt, opts[j], sizeof(opt)/sizeof(opt[0]));
1953
1954 krisbash 1.1 /* If option name too long */
1955 if (n >= sizeof(opt))
1956 {
1957 Tcslcpy(state->err, MI_T("bad parameter"), sizeof(state->err)/sizeof(state->err[0]));
1958 return -1;
1959 }
1960
1961 /* If option name zero-length */
1962 if (n == 0)
1963 {
1964 Tcslcpy(state->err, MI_T("bad parameter"), sizeof(state->err)/sizeof(state->err[0]));
1965 return -1;
1966 }
1967
1968 /* If option has argument */
1969 #ifdef _PREFAST_
1970 #pragma prefast(push)
1971 #pragma prefast(disable:26014)
1972 #endif
1973 if (opt[n-1] == ':')
1974 {
1975 krisbash 1.1 hasArg = 1;
1976 opt[n-1] = '\0';
1977 }
1978 else
1979 hasArg = 0;
1980 #ifdef _PREFAST_
1981 #pragma prefast(pop)
1982 #endif
1983
1984 /* Does argv[i] match this option? */
1985 if (Tcscmp(argv[i], opt) == 0)
1986 {
1987 if (hasArg)
1988 {
1989 if (i + 1 == *argc)
1990 {
1991 Tcslcpy(state->err, MI_T("missing option argument: "),
1992 sizeof(state->err)/sizeof(state->err[0]));
1993 Tcslcat(state->err, opt, sizeof(state->err)/sizeof(state->err[0]));
1994 return -1;
1995 }
1996 krisbash 1.1
1997 Tcslcpy(state->opt, argv[i], sizeof(state->opt)/sizeof(state->opt[0]));
1998 state->arg = argv[i+1];
1999 memmove((void*)&argv[i], (void*)&argv[i+2],
2000 sizeof(char*) * ((*argc) - i - 1));
2001 *argc -= 2;
2002 return 0;
2003 }
2004 else
2005 {
2006 Tcslcpy(state->opt, argv[i], sizeof(state->opt)/sizeof(state->opt[0]));
2007 memmove((void*)&argv[i], (void*)&argv[i+1],
2008 sizeof(char*) * ((*argc) - i));
2009 *argc -= 1;
2010 return 0;
2011 }
2012 }
2013 else if (hasArg &&
2014 Tcsncmp(argv[i], opt, n-1) == 0 && argv[i][n-1] == '=')
2015 {
2016 Tcslcpy(state->opt, argv[i], sizeof(state->opt)/sizeof(state->opt[0]));
2017 krisbash 1.1 state->opt[n-1] = '\0';
2018 state->arg = &argv[i][n];
2019 memmove((void*)&argv[i], (void*)&argv[i+1],
2020 sizeof(char*) * ((*argc) - i));
2021 *argc -= 1;
2022 return 0;
2023 }
2024 }
2025
2026 /* Unknown option */
2027 Tcslcpy(state->err, MI_T("unknown option: "), sizeof(state->err)/sizeof(state->err[0]));
2028 Tcslcat(state->err, argv[i], sizeof(state->err)/sizeof(state->err[0]));
2029 return -1;
2030 }
2031
2032 /* Done */
2033 return 1;
2034 }
2035 static MI_Result GetCommandLineOptions(
2036 int* argc,
2037 const MI_Char* argv[])
2038 krisbash 1.1 {
2039 GetOptState state = GETOPTSTATE_INITIALIZER;
2040 const MI_Char* supportedOptions[] =
2041 {
2042 MI_T("-h"),
2043 MI_T("--help"),
2044 MI_T("-q"),
2045 MI_T("-t"),
2046 MI_T("-s"),
2047 MI_T("-shallow"),
2048 MI_T("-synchronous"),
2049 MI_T("-n"),
2050 MI_T("-R:"),
2051 MI_T("-ac:"),
2052 MI_T("-rc:"),
2053 MI_T("-r:"),
2054 MI_T("-rr:"),
2055 MI_T("-rc:"),
2056 MI_T("-u:"),
2057 MI_T("-p:"),
2058 MI_T("-S"),
2059 krisbash 1.1 MI_T("--summary"),
2060 MI_T("--prefix:"),
2061 MI_T("--libdir:"),
2062 MI_T("--bindir:"),
2063 MI_T("--localstatedir:"),
2064 MI_T("--sysconfdir:"),
2065 MI_T("--providerdir:"),
2066 MI_T("--certsdir:"),
2067 MI_T("--rundir:"),
2068 MI_T("--logdir:"),
2069 MI_T("--pidfile:"),
2070 MI_T("--logfile:"),
2071 MI_T("--registerdir:"),
2072 MI_T("--socketfile:"),
2073 MI_T("--pemfile:"),
2074 MI_T("--keyfile:"),
2075 MI_T("--agentprogram:"),
2076 MI_T("--serverprogram:"),
2077 MI_T("--stdout:"),
2078 MI_T("--stderr:"),
2079 MI_T("--querylang:"),
2080 krisbash 1.1 MI_T("--queryexpr:"),
2081 NULL,
2082 };
2083
2084 for (;;)
2085 {
2086 int r = GetOpt(argc, argv, supportedOptions, &state);
2087
2088 if (r == 1)
2089 break;
2090
2091 if (r == -1)
2092 {
2093 Ftprintf(serr, PAL_T("error: %T\n"), tcs(state.err));
2094 Ftprintf(serr, PAL_T("Try -h for help\n"));
2095 return MI_RESULT_INVALID_PARAMETER;
2096 }
2097
2098 if (Tcscmp(state.opt, PAL_T("-h")) == 0 || Tcscmp(state.opt, PAL_T("--help")) == 0)
2099 {
2100 opts.help = MI_TRUE;
2101 krisbash 1.1 }
2102 else if (Tcscmp(state.opt, PAL_T("-q")) == 0)
2103 {
2104 opts.quiet = MI_TRUE;
2105 }
2106 else if (Tcscmp(state.opt, PAL_T("-t")) == 0)
2107 {
2108 opts.trace = MI_TRUE;
2109 }
2110 else if (Tcscmp(state.opt, PAL_T("-s")) == 0)
2111 {
2112 opts.suppressResults = MI_TRUE;
2113 }
2114 else if (Tcscmp(state.opt, PAL_T("-shallow")) == 0)
2115 {
2116 opts.shallow = MI_TRUE;
2117 }
2118 else if (Tcscmp(state.opt, PAL_T("-synchronous")) == 0)
2119 {
2120 opts.synchronous = MI_TRUE;
2121 }
2122 krisbash 1.1 else if (Tcscmp(state.opt, PAL_T("-n")) == 0)
2123 {
2124 opts.nulls = MI_TRUE;
2125 }
2126 else if (Tcscmp(state.opt, PAL_T("-R")) == 0)
2127 {
2128 MI_Char *end;
2129 opts.repeat = Tcstol(state.arg, &end, 10);
2130
2131 if (opts.repeat <= 0)
2132 {
2133 err(PAL_T("bad value for -R: %T"), tcs(state.arg));
2134 return MI_RESULT_INVALID_PARAMETER;
2135 }
2136 }
2137 else if (Tcscmp(state.opt, PAL_T("-ac")) == 0)
2138 {
2139 opts.assocClass = state.arg;
2140 }
2141 else if (Tcscmp(state.opt, PAL_T("-rc")) == 0)
2142 {
2143 krisbash 1.1 opts.resultClass = state.arg;
2144 }
2145 else if (Tcscmp(state.opt, PAL_T("-r")) == 0)
2146 {
2147 opts.role = state.arg;
2148 }
2149 else if (Tcscmp(state.opt, PAL_T("-rr")) == 0)
2150 {
2151 opts.resultRole = state.arg;
2152 }
2153 else if (Tcscmp(state.opt, PAL_T("-u")) == 0)
2154 {
2155 opts.user = state.arg;
2156 }
2157 else if (Tcscmp(state.opt, PAL_T("-p")) == 0)
2158 {
2159 opts.password = state.arg;
2160 }
2161 else if (Tcscmp(state.opt, PAL_T("--stdout")) == 0)
2162 {
2163 FILE* os;
2164 krisbash 1.1 #if defined(_MSC_VER)
2165 FILE* fp;
2166 os = (_wfopen_s(&fp, state.arg, PAL_T("wb")) == 0 ? fp : NULL);
2167 #else
2168 {
2169 #if defined(CONFIG_ENABLE_WCHAR)
2170 char tmp[PAL_MAX_PATH_SIZE];
2171 StrWcslcpy(tmp, state.arg, sizeof(tmp));
2172 os = File_Open(tmp, "wb");
2173 #else
2174 os = File_Open(state.arg, "wb");
2175 #endif
2176 }
2177 #endif
2178
2179 if (!os)
2180 err(PAL_T("failed to open: %T"), tcs(state.arg));
2181
2182 sout = os;
2183 }
2184 else if (Tcscmp(state.opt, PAL_T("--stderr")) == 0)
2185 krisbash 1.1 {
2186 FILE* os;
2187 #if defined(_MSC_VER)
2188 FILE* fp;
2189 os = (_wfopen_s(&fp, state.arg, PAL_T("wb")) == 0 ? fp : NULL);
2190 #else
2191 {
2192 #if defined(CONFIG_ENABLE_WCHAR)
2193 char tmp[PAL_MAX_PATH_SIZE];
2194 StrWcslcpy(tmp, state.arg, sizeof(tmp));
2195 os = File_Open(tmp, "wb");
2196 #else
2197 os = File_Open(state.arg, "wb");
2198 #endif
2199 }
2200 #endif
2201
2202 if (!os)
2203 err(PAL_T("failed to open: %T"), tcs(state.arg));
2204
2205 serr = os;
2206 krisbash 1.1 }
2207 else if (Tcscmp(state.opt, PAL_T("--querylang")) == 0)
2208 {
2209 opts.querylang = state.arg;
2210 }
2211 else if (Tcscmp(state.opt, PAL_T("--queryexpr")) == 0)
2212 {
2213 opts.queryexpr = state.arg;
2214 }
2215 else if (Tcscmp(state.opt, PAL_T("--summary")) == 0 ||
2216 Tcscmp(state.opt, PAL_T("-S")) == 0)
2217 {
2218 opts.summary = MI_TRUE;
2219 }
2220 #if 0
2221 else if (Tcsncmp(state.opt, PAL_T("--"), 2) == 0 && IsNickname(state.opt+2))
2222 {
2223 if (SetPathFromNickname(state.opt+2, state.arg) != 0)
2224 err(PAL_T("SetPathFromNickname() failed"));
2225 }
2226 #endif
2227 krisbash 1.1 }
2228
2229 return MI_RESULT_OK;
2230 }
2231
2232 const MI_Char USAGE[] = MI_T("\
2233 Usage: %T [OPTIONS] COMMAND ...\n\
2234 \n\
2235 This tool sends requests to the CIM server.\n\
2236 \n\
2237 OPTIONS:\n\
2238 -h, --help Print this help message.\n\
2239 -q Operate quietly.\n\
2240 -t Enable diagnostic tracing.\n\
2241 -R N Repeat command N times.\n\
2242 -shallow Use shallow inheritance (see 'ei' command).\n\
2243 -synchronous Executes command in synchronous mode.\n\
2244 -ac CLASSNAME Association class (see 'a' and 'r' commands).\n\
2245 -rc CLASSNAME Result class (see 'a' command).\n\
2246 -r ROLE Role (see 'a' and 'r' commands).\n\
2247 -rr ROLE Result role (see 'a' command).\n\
2248 krisbash 1.1 -n Show null properties.\n\
2249 -u USERNAME Username.\n\
2250 -p PASSWORD User's password.\n\
2251 -id Send identify request.\n\
2252 --socketfile PATH Talk to the server server whose socket file resides\n\
2253 at the location given by the path argument.\n\
2254 --httpport Connect on this port instead of default.\n\
2255 --httpsport Connect on this secure port instead of default.\n\
2256 --querylang Query language (for 'ei', 'sub' command).\n\
2257 --queryexpr Query expression (for 'ei', 'sub' command).\n\
2258 \n\
2259 COMMANDS:\n\
2260 noop\n\
2261 Perform a no-op operation.\n\
2262 gi NAMESPACE INSTANCENAME\n\
2263 Peform a CIM [g]et [i]nstance operation.\n\
2264 ci NAMESPACE NEWINSTANCE\n\
2265 Peform a CIM [c]reate [i]nstance operation.\n\
2266 mi NAMESPACE MODIFIEDINSTANCE\n\
2267 Peform a CIM [m]odify [i]nstance operation.\n\
2268 di NAMESPACE INSTANCENAME\n\
2269 krisbash 1.1 Peform a CIM [d]elete [i]nstance operation.\n\
2270 ei [-shallow] NAMESPACE CLASSNAME\n\
2271 Peform a CIM [e]numerate [i]nstances operation.\n\
2272 iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\
2273 Peform a CIM extrinisic method [i]nvocation operation.\n\
2274 a [-ac -rc -r -rr ] NAMESPACE INSTANCENAME\n\
2275 Perform a CIM [a]ssociator instances operation.\n\
2276 r [-rc -r] NAMESPACE INSTANCENAME (references)\n\
2277 Perform a CIM [r]eference instances operation.\n\
2278 gc NAMESPACE CLASSENAME\n\
2279 Peform a CIM [g]et [c]lass operation.\n\
2280 enc INSTANCE\n\
2281 Attempt to encode and print the given instance representation.\n\
2282 wql NAMESPACE WQLQUERY\n\
2283 Peform a WQL query operation.\n\
2284 cql NAMESPACE CQLQUERY\n\
2285 Peform a CQL query operation.\n\
2286 sub NAMESPACE\n\
2287 Peform a subscribe to indication operation.\n\
2288 \n\
2289 INSTANCENAME and PARAMETERS format:\n\
2290 krisbash 1.1 { class_name property_name property_value property_name property_value }\n\
2291 property_value is either a string value, or can be an INSTANCENAME.\n\
2292 property_value can also be an array taking the form [ property_value property_value ].\n\
2293 \n");
2294
2295 /*
2296 * Signal handler that catch SIGINT signal, the signal
2297 * is triggered by CTRL+C from console; In case of
2298 * SIGINT signal, need to cancel the active operation
2299 * and exit
2300 *
2301 */
2302 void MI_MAIN_CALL SignalHandler(int signo)
2303 {
2304 err(PAL_T("Quit program upon receiving ctrl+c"), signo);
2305 if (gop.ft)
2306 {
2307 if (s_finished == 0)
2308 {
2309 s_finished = 1;
2310 CondLock_Broadcast((ptrdiff_t)(&s_finished));
2311 krisbash 1.1 }
2312
2313 Ftprintf(sout, MI_T("Cancel the operation"));
2314 MI_Operation_Cancel(&gop, MI_REASON_SHUTDOWN);
2315 /* Close opeartion will be unresponsive due to */
2316 /* the operation is not get final result yet */
2317 /* need to enable this code after end to end cancel was completed */
2318 /* MI_Operation_Close(&gop); */
2319 /* Ftprintf(sout, MI_T("Closed the operation")); */
2320 Sleep_Milliseconds(200);
2321 }
2322 exit(1);
2323 }
2324
2325 /*
2326 * Set up signal handler to catch SIGINT signal
2327 *
2328 */
2329 void CatchCtrlC()
2330 {
2331 if (signal(SIGINT, SignalHandler) == SIG_ERR)
2332 krisbash 1.1 err(PAL_T("cannot catch signal: SIGINT\n"));
2333 }
2334
2335 MI_Result climain(int argc, const MI_Char* argv[])
2336 {
2337 MI_Application miApplication = MI_APPLICATION_NULL;
2338 MI_Session miSession = MI_SESSION_NULL;
2339 MI_Result miResult;
2340 MI_DestinationOptions _miDestinationOptions = MI_DESTINATIONOPTIONS_NULL;
2341 MI_DestinationOptions *miDestinationOptions = NULL;
2342 MI_UserCredentials miUserCredentials = {0};
2343
2344 /*Log_OpenStdErr();
2345 Log_SetLevel(LOG_VERBOSE);*/
2346 CatchCtrlC();
2347
2348 // Setup default stderr and stdout streams:
2349 serr = stderr;
2350 sout = stdout;
2351
2352 arg0 = argv[0];
2353 krisbash 1.1
2354 // const MI_Uint64 CONNECT_TIMEOUT_USEC = 10 * 1000 * 1000;
2355
2356 // Get the options:
2357 miResult = GetCommandLineDestDirOption(&argc, argv);
2358 if (miResult != MI_RESULT_OK)
2359 {
2360 return miResult;
2361 }
2362
2363 // Get configuration file options:
2364 miResult = GetConfigFileOptions();
2365 if (miResult != MI_RESULT_OK)
2366 {
2367 return miResult;
2368 }
2369
2370 // Get the options:
2371 miResult = GetCommandLineOptions(&argc, argv);
2372 if (miResult != MI_RESULT_OK)
2373 {
2374 krisbash 1.1 return miResult;
2375 }
2376 // There must be at least 1 argument left:
2377 if (argc < 2)
2378 {
2379 if (argc >= 1)
2380 {
2381 Ftprintf(sout, USAGE, tcs(argv[0]));
2382 if (opts.help)
2383 miResult = MI_RESULT_OK;
2384 else
2385 miResult = MI_RESULT_INVALID_PARAMETER;
2386 }
2387 else
2388 {
2389 Ftprintf(sout, USAGE, tcs(MI_T("omicli")));
2390 miResult = MI_RESULT_INVALID_PARAMETER;
2391 }
2392 return miResult;
2393 }
2394
2395 krisbash 1.1 if (Tcscmp(argv[1], MI_T("enc")) != 0)
2396 {
2397 miResult = MI_Application_Initialize(0, NULL, NULL, &miApplication);
2398 if (miResult != MI_RESULT_OK)
2399 return miResult;
2400 if (opts.user)
2401 {
2402 miDestinationOptions = &_miDestinationOptions;
2403 miResult = MI_Application_NewDestinationOptions(&miApplication, miDestinationOptions);
2404 if (miResult != MI_RESULT_OK)
2405 goto CleanupApplication;
2406
2407 miUserCredentials.authenticationType = MI_AUTH_TYPE_BASIC;
2408 miUserCredentials.credentials.usernamePassword.domain = MI_T("localhost");
2409 miUserCredentials.credentials.usernamePassword.username = opts.user;
2410 miUserCredentials.credentials.usernamePassword.password = opts.password;
2411
2412 miResult = MI_DestinationOptions_AddDestinationCredentials(miDestinationOptions, &miUserCredentials);
2413 if (miResult != MI_RESULT_OK)
2414 goto CleanupApplication;
2415 }
2416 krisbash 1.1
2417 miResult = MI_Application_NewSession(&miApplication, NULL, NULL, miDestinationOptions, NULL, NULL, &miSession);
2418 if (miResult != MI_RESULT_OK)
2419 goto CleanupApplication;
2420
2421 // Remember start time (will calculate total time in PrintSummary()
2422 s_startTime = CPU_GetTimeStamp();
2423 }
2424
2425 if (Tcscmp(argv[1], MI_T("ei")) == 0)
2426 {
2427 int i;
2428 for (i = 0; i < opts.repeat; i++)
2429 {
2430 if (opts.queryexpr)
2431 {
2432 miResult = QueryInstances(&miSession, argc, argv);
2433 if (miResult != MI_RESULT_OK)
2434 goto CleanupSession;
2435 }
2436 else
2437 krisbash 1.1 {
2438 miResult = EnumerateInstances(&miSession, argc, argv);
2439 if (miResult != MI_RESULT_OK)
2440 goto CleanupSession;
2441 }
2442 }
2443 }
2444 else if (Tcscmp(argv[1], MI_T("id")) == 0)
2445 {
2446 const MI_Char* args[5];
2447 int i;
2448
2449 if (argc != 2)
2450 {
2451 Ftprintf(serr, PAL_T("Usage: %T id\n\n"), tcs(arg0));
2452 miResult = MI_RESULT_INVALID_PARAMETER;
2453 goto CleanupSession;
2454 }
2455
2456 args[0]= argv[0];
2457 args[1]= MI_T("ei");
2458 krisbash 1.1 args[2]= MI_T("root/omi");
2459 args[3]= MI_T("OMI_Identify");
2460 args[4]= NULL;
2461
2462 for (i = 0; i < opts.repeat; i++)
2463 {
2464 miResult = EnumerateInstances(&miSession, 4, args);
2465 if (miResult != MI_RESULT_OK)
2466 goto CleanupSession;
2467 }
2468 }
2469 else if (Tcscmp(argv[1], MI_T("wql")) == 0 ||
2470 Tcscmp(argv[1], MI_T("cql")) == 0)
2471 {
2472 int i;
2473 for (i = 0; i < opts.repeat; i++)
2474 {
2475 miResult = Query(&miSession, argc, argv);
2476 if (miResult != MI_RESULT_OK)
2477 goto CleanupSession;
2478 }
2479 krisbash 1.1 }
2480 else if (Tcscmp(argv[1], MI_T("noop")) == 0)
2481 {
2482 int i;
2483 for (i = 0; i < opts.repeat; i++)
2484 {
2485 miResult = NoOp(&miSession, argc, argv);
2486 if (miResult != MI_RESULT_OK)
2487 goto CleanupSession;
2488 }
2489 }
2490 else if (Tcscmp(argv[1], MI_T("enc")) == 0)
2491 {
2492 miResult = Encode(argc, argv);
2493 goto CleanupApplication;
2494 }
2495 else if (Tcscmp(argv[1], MI_T("gi")) == 0)
2496 {
2497 int i;
2498 for (i = 0; i < opts.repeat; i++)
2499 {
2500 krisbash 1.1 miResult = GetInstance(&miSession, argc, argv);
2501 if (miResult != MI_RESULT_OK)
2502 goto CleanupSession;
2503 }
2504 }
2505 else if (Tcscmp(argv[1], MI_T("ci")) == 0)
2506 {
2507 int i;
2508 for (i = 0; i < opts.repeat; i++)
2509 {
2510 miResult = CreateInstance(&miSession, argc, argv);
2511 if (miResult != MI_RESULT_OK)
2512 goto CleanupSession;
2513 }
2514 }
2515 else if (Tcscmp(argv[1], MI_T("mi")) == 0)
2516 {
2517 int i;
2518 for (i = 0; i < opts.repeat; i++)
2519 {
2520 miResult = ModifyInstance(&miSession, argc, argv);
2521 krisbash 1.1 if (miResult != MI_RESULT_OK)
2522 goto CleanupSession;
2523 }
2524 }
2525 else if (Tcscmp(argv[1], MI_T("di")) == 0)
2526 {
2527 int i;
2528 for (i = 0; i < opts.repeat; i++)
2529 {
2530 miResult = DeleteInstance(&miSession, argc, argv);
2531 if (miResult != MI_RESULT_OK)
2532 goto CleanupSession;
2533 }
2534 }
2535 else if (Tcscmp(argv[1], MI_T("iv")) == 0)
2536 {
2537 int i;
2538 for (i = 0; i < opts.repeat; i++)
2539 {
2540 miResult = Invoke(&miSession, argc, argv);
2541 if (miResult != MI_RESULT_OK)
2542 krisbash 1.1 goto CleanupSession;
2543 }
2544 }
2545 else if (Tcscmp(argv[1], MI_T("a")) == 0)
2546 {
2547 int i;
2548 for (i = 0; i < opts.repeat; i++)
2549 {
2550 miResult = Associators(&miSession, argc, argv);
2551 if (miResult != MI_RESULT_OK)
2552 goto CleanupSession;
2553 }
2554 }
2555 else if (Tcscmp(argv[1], MI_T("r")) == 0)
2556 {
2557 int i;
2558 for (i = 0; i < opts.repeat; i++)
2559 {
2560 miResult = References(&miSession, argc, argv);
2561 if (miResult != MI_RESULT_OK)
2562 goto CleanupSession;
2563 krisbash 1.1 }
2564 }
2565 else if (Tcscmp(argv[1], MI_T("gc")) == 0)
2566 {
2567 int i;
2568 for (i = 0; i < opts.repeat; i++)
2569 {
2570 miResult = GetClass(&miSession, argc, argv);
2571 if (miResult != MI_RESULT_OK)
2572 goto CleanupSession;
2573 }
2574 }
2575 else if (Tcscmp(argv[1], MI_T("sub")) == 0)
2576 {
2577 int i;
2578 for (i = 0; i < opts.repeat; i++)
2579 {
2580 miResult = Subscribe(&miSession, argc, argv);
2581 if (miResult != MI_RESULT_OK)
2582 goto CleanupSession;
2583 }
2584 krisbash 1.1 }
2585 else
2586 {
2587 err(PAL_T("unknown command: %T"), tcs(argv[1]));
2588 miResult = MI_RESULT_INVALID_PARAMETER;
2589 goto CleanupSession;
2590 }
2591
2592 if (opts.summary)
2593 PrintSummary();
2594
2595 CleanupSession:
2596 MI_Session_Close(&miSession, NULL, NULL);
2597
2598 CleanupApplication:
2599 if (miDestinationOptions)
2600 MI_DestinationOptions_Delete(miDestinationOptions);
2601
2602 MI_Application_Close(&miApplication);
2603
2604 if (sout != stdout)
2605 krisbash 1.1 fclose(sout);
2606
2607 if (serr != stdout)
2608 fclose(serr);
2609
2610 return miResult;
2611 }
|