(file) Return to cli_c.c CVS log (file) (dir) Up to [OMI] / omi / cli

   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              }

ViewCVS 0.9.2