(file) Return to cli_c.c.bkp 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 brach (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                              DEBUG_ASSERT(PAL_FALSE);
 540                              err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
 541                              if (errorString)
 542                              {
 543                                  err(PAL_T("result: %T"), tcs(errorString));
 544                              }
 545                              if (errorDetails)
 546                              {
 547 krisbash 1.1                     Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
 548                              }
 549                          }
 550                      }
 551                      s_finalResult = resultCode;
 552                      s_finished = 1;
 553                      CondLock_Broadcast((ptrdiff_t)callbackContext);
 554                  }
 555              }
 556              
 557              void MI_CALL IndicationResult(
 558                  _In_opt_     MI_Operation *operation,
 559                  _In_     void *callbackContext, 
 560                  _In_opt_ const MI_Instance *instance,
 561                  _In_opt_z_ const MI_Char *bookmark,
 562                  _In_opt_z_ const MI_Char *machineID,
 563                           MI_Boolean moreResults,
 564                  _In_     MI_Result resultCode,
 565                  _In_opt_z_ const MI_Char *errorString,
 566                  _In_opt_ const MI_Instance *errorDetails,
 567                  _In_opt_ MI_Result (MI_CALL * resultAcknowledgement)(_In_ MI_Operation *operation))
 568 krisbash 1.1 {
 569                  if (instance)
 570                  {
 571                      s_numInstances++;
 572              
 573                      if (!opts.quiet)
 574                      {
 575                          Ftprintf(sout, PAL_T("Async suscribe. Bookmark: %T; MachineID: %T\n"), tcs(bookmark), tcs(machineID));
 576                          Instance_Print(instance, sout, 0, opts.nulls, MI_FALSE);
 577                      }
 578                  }
 579              
 580                  if (moreResults == MI_FALSE)
 581                  {
 582                      if (resultCode != MI_RESULT_OK)
 583                      {
 584                          if (!opts.suppressResults)
 585                          {
 586                              err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
 587                              if (errorString)
 588                              {
 589 krisbash 1.1                     err(PAL_T("result: %T"), tcs(errorString));
 590                              }
 591                              if (errorDetails)
 592                              {
 593                                  Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
 594                              }
 595                          }
 596                      }
 597                      s_finalResult = resultCode;
 598                      s_finished = 1;
 599                      CondLock_Broadcast((ptrdiff_t)callbackContext);
 600                  }
 601              }
 602              
 603              static MI_Result ConsumeInstanceResults(MI_Operation *miOperation)
 604              {
 605                  MI_Result miResult;
 606              
 607                  if (opts.synchronous == MI_TRUE)
 608                  {
 609                      MI_Boolean moreResults = MI_FALSE;
 610 krisbash 1.1         do
 611                      {
 612                          const MI_Instance *miInstanceResult = NULL;
 613                          MI_Result _miResult;
 614                          const MI_Char *errorString = NULL;
 615                          const MI_Instance *errorDetails = NULL;
 616              
 617                          _miResult = MI_Operation_GetInstance(miOperation, &miInstanceResult, &moreResults, &miResult, &errorString, &errorDetails);
 618                          if (_miResult != MI_RESULT_OK)
 619                          {
 620                              miResult = _miResult;
 621                          }
 622                          if (miInstanceResult)
 623                          {
 624                              s_numInstances++;
 625              
 626                              if (!opts.quiet)
 627                              {
 628                                  Instance_Print(miInstanceResult, sout, 0, opts.nulls, MI_FALSE);
 629                              }
 630                          }
 631 krisbash 1.1 
 632                          if (moreResults == MI_FALSE)
 633                          {
 634                              if (miResult != MI_RESULT_OK)
 635                              {
 636                                  if (!opts.suppressResults)
 637                                  {
 638                                      DEBUG_ASSERT(PAL_FALSE);
 639                                      err(PAL_T("result: %T"), tcs(Result_ToString(miResult)));
 640                                      if (errorString)
 641                                      {
 642                                          err(PAL_T("result: %T"), tcs(errorString));
 643                                      }
 644                                      if (errorDetails)
 645                                      {
 646                                          Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
 647                                      }
 648                                  }
 649                              }
 650                              s_finalResult = miResult;
 651                              s_finished = 1;
 652 krisbash 1.1             }
 653              
 654                      } while ((miResult == MI_RESULT_OK) && (moreResults == MI_TRUE));
 655                  }
 656                  else
 657                  {
 658                      ptrdiff_t finished;
 659                      finished = s_finished;
 660                      while (!finished)
 661                      {
 662                          CondLock_Wait((ptrdiff_t)&s_finished, &s_finished, finished, CONDLOCK_DEFAULT_SPINCOUNT);
 663                          finished = s_finished;
 664                      }
 665                      miResult = s_finalResult;
 666                  }
 667              
 668                  return miResult;
 669              }
 670              
 671              
 672              static MI_Result ConsumeIndicationsResults(MI_Operation *miOperation)
 673 krisbash 1.1 {
 674                  MI_Result miResult;
 675              
 676                  if (opts.synchronous == MI_TRUE)
 677                  {
 678                      MI_Boolean moreResults = MI_FALSE;
 679                      do
 680                      {
 681                          const MI_Instance *miInstanceResult = NULL;
 682                          MI_Result _miResult;
 683                          const MI_Char *errorString = NULL;
 684                          const MI_Instance *errorDetails = NULL;
 685                          const MI_Char *bookmark;
 686                          const MI_Char *machineid;
 687              
 688                          _miResult = MI_Operation_GetIndication(miOperation, &miInstanceResult, &bookmark, &machineid, &moreResults, &miResult, &errorString, &errorDetails);
 689                          if (_miResult != MI_RESULT_OK)
 690                          {
 691                              miResult = _miResult;
 692                          }
 693              
 694 krisbash 1.1             if (miInstanceResult)
 695                          {
 696                              s_numInstances++;
 697              
 698                              if (!opts.quiet)
 699                              {
 700                                  Ftprintf(sout, PAL_T("Sync subscribe. Bookmark: %T; MachineID: %T\n"), tcs(bookmark), tcs(machineid));
 701                                  Instance_Print(miInstanceResult, sout, 0, opts.nulls, MI_FALSE);
 702                              }
 703                          }
 704              
 705                          if (moreResults == MI_FALSE)
 706                          {
 707                              if (miResult != MI_RESULT_OK)
 708                              {
 709                                  if (!opts.suppressResults)
 710                                  {
 711                                      err(PAL_T("result: %T"), tcs(Result_ToString(miResult)));
 712                                      if (errorString)
 713                                      {
 714                                          err(PAL_T("result: %T"), tcs(errorString));
 715 krisbash 1.1                         }
 716                                      if (errorDetails)
 717                                      {
 718                                          Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
 719                                      }
 720                                  }
 721                              }
 722                              s_finalResult = miResult;
 723                              s_finished = 1;
 724                          }
 725              
 726                      } while ((miResult == MI_RESULT_OK) && (moreResults == MI_TRUE));
 727                  }
 728                  else
 729                  {
 730                      ptrdiff_t finished;
 731                      finished = s_finished;
 732                      while (!finished)
 733                      {
 734                          CondLock_Wait((ptrdiff_t)&s_finished, &s_finished, finished, CONDLOCK_DEFAULT_SPINCOUNT);
 735                          finished = s_finished;
 736 krisbash 1.1         }
 737                      miResult = s_finalResult;
 738                  }
 739              
 740                  return miResult;
 741              }
 742              
 743              void MI_CALL ClassResults(
 744                  _In_opt_     MI_Operation *operation,
 745                  _In_     void *callbackContext, 
 746                  _In_opt_ const MI_Class *classObject,
 747                           MI_Boolean moreResults,
 748                  _In_     MI_Result resultCode,
 749                  _In_opt_z_ const MI_Char *errorString,
 750                  _In_opt_ const MI_Instance *errorDetails,
 751                  _In_opt_ MI_Result (MI_CALL * resultAcknowledgement)(_In_ MI_Operation *operation))
 752              {
 753                  if (classObject)
 754                  {
 755                      s_numInstances++;
 756              
 757 krisbash 1.1         if (!opts.quiet)
 758                      {
 759                          MI_Instance *instance;
 760                          if (Instance_New(&instance, classObject->classDecl, NULL) == MI_RESULT_OK)
 761                          {
 762                              Instance_Print(instance, sout, 0, MI_TRUE, MI_TRUE);
 763              
 764                              MI_Instance_Delete(instance);
 765                          }
 766                      }
 767                  }
 768              
 769                  if (moreResults == MI_FALSE)
 770                  {
 771                      if (resultCode != MI_RESULT_OK)
 772                      {
 773                          if (!opts.suppressResults)
 774                          {
 775                              err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
 776                              if (errorString)
 777                              {
 778 krisbash 1.1                     err(PAL_T("result: %T"), tcs(errorString));
 779                              }
 780                              if (errorDetails)
 781                              {
 782                                  Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
 783                              }
 784                          }
 785                      }
 786                      s_finalResult = resultCode;
 787                      s_finished = 1;
 788                      CondLock_Broadcast((ptrdiff_t)callbackContext);
 789                  }
 790              }
 791              
 792              static MI_Result ConsumeClassResults(MI_Operation *miOperation)
 793              {
 794                  MI_Result miResult;
 795              
 796                  if (opts.synchronous == MI_TRUE)
 797                  {
 798                      MI_Boolean moreResults = MI_FALSE;
 799 krisbash 1.1         do
 800                      {
 801                          const MI_Class *miClassResult = NULL;
 802                          MI_Result _miResult;
 803                          const MI_Char *errorString = NULL;
 804                          const MI_Instance *errorDetails = NULL;
 805              
 806                          _miResult = MI_Operation_GetClass(miOperation, &miClassResult, &moreResults, &miResult, &errorString, &errorDetails);
 807                          if (_miResult != MI_RESULT_OK)
 808                          {
 809                              miResult = _miResult;
 810                          }
 811                          if (miClassResult)
 812                          {
 813                              s_numInstances++;
 814              
 815                              if (!opts.quiet)
 816                              {
 817                                  MI_Instance *instance;
 818                                  if (Instance_New(&instance, miClassResult->classDecl, NULL) == MI_RESULT_OK)
 819                                  {
 820 krisbash 1.1                         Instance_Print(instance, sout, 0, MI_TRUE, MI_TRUE);
 821              
 822                                      MI_Instance_Delete(instance);
 823                                  }
 824                              }
 825                          }
 826              
 827                          if (moreResults == MI_FALSE)
 828                          {
 829                              if (miResult != MI_RESULT_OK)
 830                              {
 831                                  if (!opts.suppressResults)
 832                                  {
 833                                      err(PAL_T("result: %T"), tcs(Result_ToString(miResult)));
 834                                      if (errorString)
 835                                      {
 836                                          err(PAL_T("result: %T"), tcs(errorString));
 837                                      }
 838                                      if (errorDetails)
 839                                      {
 840                                          Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
 841 krisbash 1.1                         }
 842                                  }
 843                              }
 844                              s_finalResult = miResult;
 845                              s_finished = 1;
 846                          }
 847              
 848                      } while ((miResult == MI_RESULT_OK) && (moreResults == MI_TRUE));
 849                  }
 850                  else
 851                  {
 852                      ptrdiff_t finished;
 853                      finished = s_finished;
 854                      while (!finished)
 855                      {
 856                          CondLock_Wait((ptrdiff_t)&s_finished, &s_finished, finished, CONDLOCK_DEFAULT_SPINCOUNT);
 857                          finished = s_finished;
 858                      }
 859                      miResult = s_finalResult;
 860                  }
 861              
 862 krisbash 1.1     return miResult;
 863              }
 864              
 865              
 866              void MI_CALL NoOpResults(
 867                  _In_opt_     MI_Operation *operation,
 868                  _In_     void *callbackContext, 
 869                  _In_opt_ const MI_Instance *instance,
 870                           MI_Boolean moreResults,
 871                  _In_     MI_Result resultCode,
 872                  _In_opt_z_ const MI_Char *errorString,
 873                  _In_opt_ const MI_Instance *errorDetails,
 874                  _In_opt_ MI_Result (MI_CALL * resultAcknowledgement)(_In_ MI_Operation *operation))
 875              {
 876                  if (instance)
 877                  {
 878                      s_numInstances++;
 879              
 880                      if (!opts.quiet)
 881                      {
 882                          Instance_Print(instance, sout, 0, opts.nulls, MI_FALSE);
 883 krisbash 1.1         }
 884                  }
 885              
 886                  if (moreResults == MI_FALSE)
 887                  {
 888                      if (resultCode != MI_RESULT_OK)
 889                      {
 890                          if (!opts.suppressResults)
 891                          {
 892                              err(PAL_T("result: %T"), tcs(Result_ToString(resultCode)));
 893                              if (errorString)
 894                              {
 895                                  err(PAL_T("result: %T"), tcs(errorString));
 896                              }
 897                              if (errorDetails)
 898                              {
 899                                  Instance_Print(errorDetails, sout, 0, opts.nulls, MI_FALSE);
 900                              }
 901                          }
 902                      }
 903                      else
 904 krisbash 1.1         {
 905                          Ftprintf(sout, PAL_T("got noop response\n"));
 906              
 907                      }
 908                      s_finalResult = resultCode;
 909                      s_finished = 1;
 910                      CondLock_Broadcast((ptrdiff_t)callbackContext);
 911                  }
 912              }
 913              
 914              
 915              static MI_Result NoOp(MI_Session *miSession, int argc, const MI_Char* argv [])
 916              {
 917                  MI_Result miResult;
 918                  MI_Operation miOperation = MI_OPERATION_NULL;
 919                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
 920                  MI_OperationCallbacks *callbacks = NULL;
 921                  MI_Uint32 flags = 0;
 922              
 923                  MI_UNUSED(argv);
 924              
 925 krisbash 1.1     if (argc != 2)
 926                  {
 927                      Ftprintf(serr, MI_T("Usage: %s noop\n\n"), tcs(arg0));
 928                      return MI_RESULT_INVALID_PARAMETER;
 929                  }
 930              
 931                  if (opts.synchronous == MI_FALSE)
 932                  {
 933                      _callbacks.callbackContext = &s_finished;
 934                      _callbacks.instanceResult = NoOpResults;
 935                      callbacks = &_callbacks;
 936                      s_finished = 0;
 937                  }
 938              
 939              
 940                  MI_Session_TestConnection(miSession, flags, callbacks, &miOperation);
 941              
 942                  miResult = ConsumeInstanceResults(&miOperation);
 943              
 944                  MI_Operation_Close(&miOperation);
 945              
 946 krisbash 1.1     return miResult;
 947              }
 948              
 949              static MI_Result EnumerateInstances(MI_Session *miSession, int argc, const MI_Char* argv[])
 950              {
 951                  MI_Result miResult;
 952                  MI_OperationOptions miOperationOptions;
 953                  MI_Operation miOperation = MI_OPERATION_NULL;
 954                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
 955                  MI_OperationCallbacks *callbacks = NULL;
 956                  MI_Uint32 flags = 0;
 957              
 958                  if (argc != 4)
 959                  {
 960                      Ftprintf(serr, MI_T("Usage: %s ei NAMESPACE CLASSNAME\n\n"), tcs(arg0));
 961                      return MI_RESULT_INVALID_PARAMETER;
 962                  }
 963              
 964                  if (opts.shallow)
 965                  {
 966                      flags = MI_OPERATIONFLAGS_POLYMORPHISM_SHALLOW;
 967 krisbash 1.1     }
 968              
 969                  if (opts.synchronous == MI_FALSE)
 970                  {
 971                      _callbacks.callbackContext = &s_finished;
 972                      _callbacks.instanceResult = InstanceResults;
 973                      callbacks = &_callbacks;
 974                      s_finished = 0;
 975                  }
 976              
 977              
 978                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
 979                  if (miResult != MI_RESULT_OK)
 980                      return miResult;
 981              
 982                  MI_Session_EnumerateInstances(miSession, flags, &miOperationOptions, argv[2], argv[3], MI_FALSE, callbacks, &miOperation);
 983              
 984                  miResult = ConsumeInstanceResults(&miOperation);
 985              
 986                  MI_Operation_Close(&miOperation);
 987              
 988 krisbash 1.1     MI_OperationOptions_Delete(&miOperationOptions);
 989              
 990                  return miResult;
 991              }
 992              
 993              static MI_Result QueryInstances(MI_Session *miSession, int argc, const MI_Char* argv[])
 994              {
 995                  MI_Result miResult;
 996                  MI_OperationOptions miOperationOptions;
 997                  MI_Operation miOperation = MI_OPERATION_NULL;
 998                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
 999                  MI_OperationCallbacks *callbacks = NULL;
1000              
1001                  if (argc != 4)
1002                  {
1003                      Ftprintf(serr, MI_T("Usage: %s ei NAMESPACE CLASSNAME\n\n"), tcs(arg0));
1004                      return MI_RESULT_INVALID_PARAMETER;
1005                  }
1006              
1007                  if (opts.synchronous == MI_FALSE)
1008                  {
1009 krisbash 1.1         _callbacks.callbackContext = &s_finished;
1010                      _callbacks.instanceResult = InstanceResults;
1011                      callbacks = &_callbacks;
1012                      s_finished = 0;
1013                  }
1014              
1015                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1016                  if (miResult != MI_RESULT_OK)
1017                      return miResult;
1018              
1019                  MI_Session_QueryInstances(miSession, 0, &miOperationOptions, argv[2], opts.querylang, opts.queryexpr, callbacks, &miOperation);
1020              
1021                  miResult = ConsumeInstanceResults(&miOperation);
1022                  
1023                  MI_Operation_Close(&miOperation);
1024              
1025                  MI_OperationOptions_Delete(&miOperationOptions);
1026              
1027                  return miResult;
1028              }
1029              
1030 krisbash 1.1 static MI_Result Query(MI_Session *miSession, int argc, const MI_Char* argv[])
1031              {
1032                  MI_Result miResult;
1033                  MI_OperationOptions miOperationOptions;
1034                  MI_Operation miOperation = MI_OPERATION_NULL;
1035                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1036                  MI_OperationCallbacks *callbacks = NULL;
1037                  const MI_Char* dialect = NULL;
1038              
1039                  if (argc != 4)
1040                  {
1041                      Ftprintf(serr, PAL_T("Usage: %T %T NAMESPACE QUERY\n\n"), tcs(arg0),
1042                          tcs(argv[1]));
1043                      return MI_RESULT_INVALID_PARAMETER;
1044                  }
1045              
1046                  if (opts.synchronous == MI_FALSE)
1047                  {
1048                      _callbacks.callbackContext = &s_finished;
1049                      _callbacks.instanceResult = InstanceResults;
1050                      callbacks = &_callbacks;
1051 krisbash 1.1         s_finished = 0;
1052                  }
1053              
1054                  // Determine query dialect:
1055                  if (Tcscmp(argv[1], MI_T("wql")) == 0)
1056                  {
1057                      dialect = MI_T("WQL");
1058                  }
1059                  else if (Tcscmp(argv[1], MI_T("cql")) == 0)
1060                  {
1061                      dialect = MI_T("CQL");
1062                  }
1063                  else
1064                  {
1065                      err(MI_T("invalid query dialecdt: %T"), tcs(argv[1]));
1066                  }
1067              
1068                  // Extract query options.
1069                  opts.queryexpr = argv[3];
1070              
1071                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1072 krisbash 1.1     if (miResult != MI_RESULT_OK)
1073                      return miResult;
1074              
1075                  MI_Session_QueryInstances(miSession, 0, &miOperationOptions, argv[2], dialect, argv[3], callbacks, &miOperation);
1076              
1077                  miResult = ConsumeInstanceResults(&miOperation);
1078                  
1079                  MI_Operation_Close(&miOperation);
1080              
1081                  MI_OperationOptions_Delete(&miOperationOptions);
1082              
1083                  return miResult;
1084              }
1085              
1086              static MI_Result GetInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1087              {
1088                  MI_Result miResult;
1089                  MI_OperationOptions miOperationOptions;
1090                  MI_Operation miOperation = MI_OPERATION_NULL;
1091                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1092                  MI_OperationCallbacks *callbacks = NULL;
1093 krisbash 1.1     MI_Instance *instance;
1094                  const MI_Char *nameSpace;
1095                  const MI_Char** p;
1096                  const MI_Char** end;
1097              
1098                  if (argc < 4)
1099                  {
1100                      Ftprintf(serr, MI_T("Usage: %s gi NAMESPACE INSTANCENAME\n\n"), tcs(arg0));
1101                      return MI_RESULT_INVALID_PARAMETER;
1102                  }
1103              
1104                  nameSpace = argv[2];
1105                  argc -= 3;
1106                  argv += 3;
1107                  p = argv;
1108                  end = p + argc;
1109              
1110                  if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1111                  {
1112                      err(MI_T("invalid instance name specification"));
1113                      return MI_RESULT_FAILED;
1114 krisbash 1.1     }
1115              
1116                  if (p != end)
1117                  {
1118                      err(MI_T("extraneous arguments after instance name"));
1119                      return MI_RESULT_INVALID_PARAMETER;
1120                  }
1121              
1122              
1123                  if (opts.synchronous == MI_FALSE)
1124                  {
1125                      _callbacks.callbackContext = &s_finished;
1126                      _callbacks.instanceResult = InstanceResults;
1127                      callbacks = &_callbacks;
1128                      s_finished = 0;
1129                  }
1130              
1131                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1132                  if (miResult != MI_RESULT_OK)
1133                      return miResult;
1134              
1135 krisbash 1.1     MI_Session_GetInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1136              
1137                  miResult = ConsumeInstanceResults(&miOperation);
1138                  
1139                  MI_Operation_Close(&miOperation);
1140              
1141                  MI_Instance_Delete(instance);
1142              
1143                  MI_OperationOptions_Delete(&miOperationOptions);
1144              
1145                  return miResult;
1146              }
1147              
1148              
1149              static MI_Result CreateInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1150              {
1151                  MI_Result miResult;
1152                  MI_OperationOptions miOperationOptions;
1153                  MI_Operation miOperation = MI_OPERATION_NULL;
1154                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1155                  MI_OperationCallbacks *callbacks = NULL;
1156 krisbash 1.1     MI_Instance *instance;
1157                  const MI_Char *nameSpace;
1158                  const MI_Char** p;
1159                  const MI_Char** end;
1160              
1161                  if (argc < 4)
1162                  {
1163                      Ftprintf(serr, MI_T("Usage: %s ci NAMESPACE INSTANCE\n\n"), tcs(arg0));
1164                      return MI_RESULT_INVALID_PARAMETER;
1165                  }
1166              
1167                  nameSpace = argv[2];
1168                  argc -= 3;
1169                  argv += 3;
1170                  p = argv;
1171                  end = p + argc;
1172              
1173                  if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1174                  {
1175                      err(PAL_T("invalid instance name specification"));
1176                      return MI_RESULT_FAILED;
1177 krisbash 1.1     }
1178              
1179                  if (p != end)
1180                  {
1181                      err(PAL_T("extraneous arguments after instance name"));
1182                      return MI_RESULT_INVALID_PARAMETER;
1183                  }
1184              
1185                  if (opts.synchronous == MI_FALSE)
1186                  {
1187                      _callbacks.callbackContext = &s_finished;
1188                      _callbacks.instanceResult = InstanceResults;
1189                      callbacks = &_callbacks;
1190                      s_finished = 0;
1191                  }
1192              
1193                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1194                  if (miResult != MI_RESULT_OK)
1195                      return miResult;
1196              
1197                  MI_Session_CreateInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1198 krisbash 1.1 
1199                  miResult = ConsumeInstanceResults(&miOperation);
1200                  
1201                  MI_Operation_Close(&miOperation);
1202              
1203                  MI_Instance_Delete(instance);
1204              
1205                  MI_OperationOptions_Delete(&miOperationOptions);
1206              
1207                  return miResult;
1208              
1209              }
1210              
1211              static MI_Result ModifyInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1212              {
1213                  MI_Result miResult;
1214                  MI_OperationOptions miOperationOptions;
1215                  MI_Operation miOperation = MI_OPERATION_NULL;
1216                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1217                  MI_OperationCallbacks *callbacks = NULL;
1218                  MI_Instance *instance;
1219 krisbash 1.1     const MI_Char *nameSpace;
1220                  const MI_Char** p;
1221                  const MI_Char** end;
1222              
1223                  if (argc < 4)
1224                  {
1225                      Ftprintf(serr, MI_T("Usage: %s mi NAMESPACE INSTANCE\n\n"), tcs(arg0));
1226                      return MI_RESULT_INVALID_PARAMETER;
1227                  }
1228              
1229                  nameSpace = argv[2];
1230                  argc -= 3;
1231                  argv += 3;
1232                  p = argv;
1233                  end = p + argc;
1234              
1235                  if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1236                  {
1237                      err(PAL_T("invalid instance name specification"));
1238                      return MI_RESULT_FAILED;
1239                  }
1240 krisbash 1.1 
1241                  if (p != end)
1242                  {
1243                      err(PAL_T("extraneous arguments after instance name"));
1244                      return MI_RESULT_INVALID_PARAMETER;
1245                  }
1246              
1247                  if (opts.synchronous == MI_FALSE)
1248                  {
1249                      _callbacks.callbackContext = &s_finished;
1250                      _callbacks.instanceResult = InstanceResults;
1251                      callbacks = &_callbacks;
1252                      s_finished = 0;
1253                  }
1254              
1255              
1256                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1257                  if (miResult != MI_RESULT_OK)
1258                      return miResult;
1259              
1260                  MI_Session_ModifyInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1261 krisbash 1.1 
1262                  miResult = ConsumeInstanceResults(&miOperation);
1263                  
1264                  MI_Operation_Close(&miOperation);
1265              
1266                  MI_Instance_Delete(instance);
1267              
1268                  MI_OperationOptions_Delete(&miOperationOptions);
1269              
1270                  return miResult;
1271              
1272              }
1273              
1274              static MI_Result DeleteInstance(MI_Session *miSession, int argc, const MI_Char* argv[])
1275              {
1276                  MI_Result miResult;
1277                  MI_OperationOptions miOperationOptions;
1278                  MI_Operation miOperation = MI_OPERATION_NULL;
1279                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1280                  MI_OperationCallbacks *callbacks = NULL;
1281                  MI_Instance *instance;
1282 krisbash 1.1     const MI_Char *nameSpace;
1283                  const MI_Char** p;
1284                  const MI_Char** end;
1285              
1286                  if (argc < 4)
1287                  {
1288                      Ftprintf(serr, MI_T("Usage: %s di NAMESPACE INSTANCE\n\n"), tcs(arg0));
1289                      return MI_RESULT_INVALID_PARAMETER;
1290                  }
1291              
1292                  nameSpace = argv[2];
1293                  argc -= 3;
1294                  argv += 3;
1295                  p = argv;
1296                  end = p + argc;
1297              
1298                  if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1299                  {
1300                      err(PAL_T("invalid instance name specification"));
1301                      return MI_RESULT_FAILED;
1302                  }
1303 krisbash 1.1 
1304                  if (p != end)
1305                  {
1306                      err(PAL_T("extraneous arguments after instance name"));
1307                      return MI_RESULT_INVALID_PARAMETER;
1308                  }
1309              
1310                  if (opts.synchronous == MI_FALSE)
1311                  {
1312                      _callbacks.callbackContext = &s_finished;
1313                      _callbacks.instanceResult = InstanceResults;
1314                      callbacks = &_callbacks;
1315                      s_finished = 0;
1316                  }
1317              
1318              
1319                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1320                  if (miResult != MI_RESULT_OK)
1321                      return miResult;
1322              
1323                  MI_Session_DeleteInstance(miSession, 0, &miOperationOptions, nameSpace, instance, callbacks, &miOperation);
1324 krisbash 1.1 
1325                  miResult = ConsumeInstanceResults(&miOperation);
1326                  
1327                  MI_Operation_Close(&miOperation);
1328              
1329                  MI_Instance_Delete(instance);
1330              
1331                  MI_OperationOptions_Delete(&miOperationOptions);
1332              
1333                  return miResult;
1334              
1335              }
1336              
1337              static MI_Result Associators(MI_Session *miSession, int argc, const MI_Char* argv[])
1338              {
1339                  MI_Result miResult;
1340                  MI_OperationOptions miOperationOptions;
1341                  MI_Operation miOperation = MI_OPERATION_NULL;
1342                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1343                  MI_OperationCallbacks *callbacks = NULL;
1344                  MI_Instance *instance;
1345 krisbash 1.1     const MI_Char *nameSpace;
1346                  const MI_Char** p;
1347                  const MI_Char** end;
1348              
1349                  if (argc < 4)
1350                  {
1351                      Ftprintf(serr, MI_T("Usage: %s a NAMESPACE INSTANCE\n\n"), tcs(arg0));
1352                      return MI_RESULT_INVALID_PARAMETER;
1353                  }
1354              
1355                  nameSpace = argv[2];
1356                  argc -= 3;
1357                  argv += 3;
1358                  p = argv;
1359                  end = p + argc;
1360              
1361                  if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1362                  {
1363                      err(PAL_T("invalid instance name specification"));
1364                      return MI_RESULT_FAILED;
1365                  }
1366 krisbash 1.1 
1367                  if (p != end)
1368                  {
1369                      err(PAL_T("extraneous arguments after instance name"));
1370                      return MI_RESULT_INVALID_PARAMETER;
1371                  }
1372              
1373                  if (opts.synchronous == MI_FALSE)
1374                  {
1375                      _callbacks.callbackContext = &s_finished;
1376                      _callbacks.instanceResult = InstanceResults;
1377                      callbacks = &_callbacks;
1378                      s_finished = 0;
1379                  }
1380              
1381              
1382                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1383                  if (miResult != MI_RESULT_OK)
1384                      return miResult;
1385              
1386                  MI_Session_AssociatorInstances(miSession, 0, &miOperationOptions, nameSpace, instance, opts.assocClass, opts.resultClass, opts.role, opts.resultRole, MI_FALSE, callbacks, &miOperation);
1387 krisbash 1.1 
1388                  miResult = ConsumeInstanceResults(&miOperation);
1389                  
1390                  MI_Operation_Close(&miOperation);
1391              
1392                  MI_Instance_Delete(instance);
1393              
1394                  MI_OperationOptions_Delete(&miOperationOptions);
1395              
1396                  return miResult;
1397              }
1398              
1399              static MI_Result References(MI_Session *miSession, int argc, const MI_Char* argv[])
1400              {
1401                  MI_Result miResult;
1402                  MI_OperationOptions miOperationOptions;
1403                  MI_Operation miOperation = MI_OPERATION_NULL;
1404                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1405                  MI_OperationCallbacks *callbacks = NULL;
1406                  MI_Instance *instance;
1407                  const MI_Char *nameSpace;
1408 krisbash 1.1     const MI_Char** p;
1409                  const MI_Char** end;
1410              
1411                  if (argc < 4)
1412                  {
1413                      Ftprintf(serr, MI_T("Usage: %T d NAMESPACE INSTANCE\n\n"), tcs(arg0));
1414                      return MI_RESULT_INVALID_PARAMETER;
1415                  }
1416              
1417                  nameSpace = argv[2];
1418                  argc -= 3;
1419                  argv += 3;
1420                  p = argv;
1421                  end = p + argc;
1422              
1423                  if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1424                  {
1425                      err(PAL_T("invalid instance name specification"));
1426                      return MI_RESULT_FAILED;
1427                  }
1428              
1429 krisbash 1.1     if (p != end)
1430                  {
1431                      err(PAL_T("extraneous arguments after instance name"));
1432                      return MI_RESULT_INVALID_PARAMETER;
1433                  }
1434              
1435                  if (opts.synchronous == MI_FALSE)
1436                  {
1437                      _callbacks.callbackContext = &s_finished;
1438                      _callbacks.instanceResult = InstanceResults;
1439                      callbacks = &_callbacks;
1440                      s_finished = 0;
1441                  }
1442              
1443              
1444                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1445                  if (miResult != MI_RESULT_OK)
1446                      return miResult;
1447              
1448                  MI_Session_ReferenceInstances(miSession, 0, &miOperationOptions, nameSpace, instance, opts.assocClass, opts.role, MI_FALSE, callbacks, &miOperation);
1449              
1450 krisbash 1.1     miResult = ConsumeInstanceResults(&miOperation);
1451                  
1452                  MI_Operation_Close(&miOperation);
1453              
1454                  MI_Instance_Delete(instance);
1455              
1456                  MI_OperationOptions_Delete(&miOperationOptions);
1457              
1458                  return miResult;
1459              }
1460              
1461              static MI_Result Invoke(MI_Session *miSession, int argc, const MI_Char* argv[])
1462              {
1463                  MI_Result miResult;
1464                  MI_OperationOptions miOperationOptions;
1465                  MI_Operation miOperation = MI_OPERATION_NULL;
1466                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1467                  MI_OperationCallbacks *callbacks = NULL;
1468                  MI_Instance *instance;
1469                  MI_Instance *inParams = NULL;
1470                  const MI_Char *nameSpace;
1471 krisbash 1.1     const MI_Char *methodName;
1472                  const MI_Char** p;
1473                  const MI_Char** end;
1474                  MI_Uint32 elementCount = 0;
1475              
1476                  if (argc < 5)
1477                  {
1478                      Ftprintf(serr, 
1479                          PAL_T("Usage: %s iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\n"), 
1480                          tcs(arg0));
1481                      return MI_RESULT_INVALID_PARAMETER;
1482                  }
1483              
1484                  nameSpace = argv[2];
1485                  argc -= 3;
1486                  argv += 3;
1487                  p = argv;
1488                  end = p + argc;
1489              
1490                  if (!ArgsToInstance(&p, end, MI_FLAG_CLASS, MI_TRUE, &instance))
1491                  {
1492 krisbash 1.1         err(PAL_T("invalid instance name specification"));
1493                      return MI_RESULT_FAILED;
1494                  }
1495              
1496                  if (p == end)
1497                  {
1498                      err(PAL_T("expected method name"));
1499                      return MI_RESULT_INVALID_PARAMETER;
1500                  }
1501              
1502                  methodName = *p;
1503                  p++;
1504              
1505                  if (p != end)
1506                  {
1507                      if (!ArgsToInstance(&p, end, MI_FLAG_METHOD, MI_TRUE, &inParams))
1508                      {
1509                          err(PAL_T("invalid instance name specification"));
1510                          return MI_RESULT_FAILED;
1511                      }
1512                  }
1513 krisbash 1.1 
1514                  if (opts.synchronous == MI_FALSE)
1515                  {
1516                      _callbacks.callbackContext = &s_finished;
1517                      _callbacks.instanceResult = InstanceResults;
1518                      callbacks = &_callbacks;
1519                      s_finished = 0;
1520                  }
1521              
1522                  if (MI_Instance_GetElementCount(instance, &elementCount) != MI_RESULT_OK)
1523                  {
1524                      err(PAL_T("Failed to get element count for instance"));
1525                      return MI_RESULT_FAILED;
1526                  }
1527              
1528                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1529                  if (miResult != MI_RESULT_OK)
1530                      return miResult;
1531              
1532                  if (elementCount)
1533                  {
1534 krisbash 1.1         MI_Session_Invoke(miSession, 0, NULL, nameSpace, instance->classDecl->name, methodName, instance, inParams, callbacks, &miOperation);
1535                  }
1536                  else
1537                  {
1538                      /* Static method */
1539                      MI_Session_Invoke(miSession, 0, &miOperationOptions, nameSpace, instance->classDecl->name, methodName, NULL, inParams, callbacks, &miOperation);
1540                  }
1541              
1542                  miResult = ConsumeInstanceResults(&miOperation);
1543                  
1544                  MI_Operation_Close(&miOperation);
1545              
1546                  MI_Instance_Delete(instance);
1547              
1548                  MI_OperationOptions_Delete(&miOperationOptions);
1549              
1550                  return miResult;
1551              }
1552              
1553              static MI_Result GetClass(MI_Session *miSession, int argc, const MI_Char* argv[])
1554              {
1555 krisbash 1.1     MI_Result miResult;
1556                  MI_OperationOptions miOperationOptions;
1557                  MI_Operation miOperation = MI_OPERATION_NULL;
1558                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1559                  MI_OperationCallbacks *callbacks = NULL;
1560                  const MI_Char *nameSpace;
1561                  const MI_Char *className;
1562              
1563                  if (argc != 4)
1564                  {
1565                      Ftprintf(serr, MI_T("Usage: %s gc NAMESPACE CLASSNAME\n\n"), tcs(arg0));
1566                      return MI_RESULT_INVALID_PARAMETER;
1567                  }
1568              
1569                  nameSpace = argv[2];
1570                  className = argv[3];
1571              
1572                  if (opts.synchronous == MI_FALSE)
1573                  {
1574                      _callbacks.callbackContext = &s_finished;
1575                      _callbacks.classResult = ClassResults;
1576 krisbash 1.1         callbacks = &_callbacks;
1577                      s_finished = 0;
1578                  }
1579              
1580              
1581                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1582                  if (miResult != MI_RESULT_OK)
1583                      return miResult;
1584              
1585                  MI_Session_GetClass(miSession, 0, &miOperationOptions, nameSpace, className, callbacks, &miOperation);
1586              
1587                  miResult = ConsumeClassResults(&miOperation);
1588                  
1589                  MI_Operation_Close(&miOperation);
1590              
1591                  MI_OperationOptions_Delete(&miOperationOptions);
1592              
1593                  return miResult;
1594              }
1595              
1596              static MI_Result Subscribe(MI_Session *miSession, int argc, const MI_Char* argv[])
1597 krisbash 1.1 {
1598                  MI_Result miResult;
1599                  MI_OperationOptions miOperationOptions;
1600                  MI_Operation miOperation = MI_OPERATION_NULL;
1601                  MI_OperationCallbacks _callbacks = MI_OPERATIONCALLBACKS_NULL;
1602                  MI_OperationCallbacks *callbacks = NULL;
1603                  const MI_Char *nameSpace;
1604              
1605                  if (argc != 3 || opts.querylang == NULL || opts.queryexpr == NULL)
1606                  {
1607                      Ftprintf(serr, MI_T("Usage: %s [--querylang 'WQL/CQL'  --queryexpr ] sub NAMESPACE\n\n"), tcs(arg0));
1608                      return MI_RESULT_INVALID_PARAMETER;
1609                  }
1610              
1611                  if (opts.synchronous == MI_FALSE)
1612                  {
1613                      _callbacks.callbackContext = &s_finished;
1614                      _callbacks.indicationResult = IndicationResult;
1615                      callbacks = &_callbacks;
1616                      s_finished = 0;
1617                  }
1618 krisbash 1.1 
1619                  nameSpace = argv[2];
1620              
1621                  miResult = CreateOperationOptions(miSession, &miOperationOptions);
1622                  if (miResult != MI_RESULT_OK)
1623                  {
1624                      Ftprintf(serr, MI_T("Failed to create MI_OperationOptions, error code(%d)\n\n"), miResult);
1625                      return miResult;
1626                  }
1627              
1628                  MI_Session_Subscribe(miSession, 0, &miOperationOptions, nameSpace, opts.querylang, opts.queryexpr, NULL, callbacks, &miOperation);
1629              
1630                  /* Duplicate operation */
1631                  memcpy(&gop, &miOperation, sizeof(MI_Operation));
1632              
1633                  miResult = ConsumeIndicationsResults(&miOperation);
1634              
1635                  /* Cleanup global operation since it is done */
1636                  memset(&gop, 0, sizeof(MI_Operation));
1637              
1638                  MI_Operation_Close(&miOperation);
1639 krisbash 1.1 
1640                  MI_OperationOptions_Delete(&miOperationOptions);
1641              
1642                  return miResult;
1643              }
1644              
1645              static MI_Result FindConfigFile(_Pre_writable_size_(PAL_MAX_PATH_SIZE) char path[PAL_MAX_PATH_SIZE])
1646              {
1647                  char* home;
1648                  /* Look in current directory */
1649                  {
1650                      Strlcpy(path, "./.omiclirc", PAL_MAX_PATH_SIZE);
1651              
1652                      if (access(path, R_OK) == 0)
1653                          return MI_RESULT_OK;
1654                  }
1655              
1656                  /* Look in HOME directory */
1657                  home = Dupenv("HOME");
1658                  if (home)
1659                  {
1660 krisbash 1.1         Strlcpy(path, home, PAL_MAX_PATH_SIZE);
1661                      Strlcat(path, "/.omiclirc", PAL_MAX_PATH_SIZE);
1662              
1663                      if (access(path, R_OK) == 0)
1664                      {
1665                          free(home);
1666                          return MI_RESULT_OK;
1667                      }
1668                      free(home);
1669                  }
1670              
1671                  /* Look in system config directory */
1672                  {
1673                      Strlcpy(path, OMI_GetPath(ID_SYSCONFDIR), PAL_MAX_PATH_SIZE);
1674                      Strlcat(path, "/omicli.conf", PAL_MAX_PATH_SIZE);
1675              
1676                      if (access(path, R_OK) == 0)
1677                          return MI_RESULT_OK;
1678                  }
1679              
1680                  /* Not found */
1681 krisbash 1.1     return MI_RESULT_FAILED;
1682              }
1683              
1684              static MI_Result GetConfigFileOptions()
1685              {
1686                  char path[PAL_MAX_PATH_SIZE];
1687                  Conf* conf;
1688                  MI_Result miResult = MI_RESULT_OK;
1689              
1690                  /* Form the configuration file path (silently ignore if not found) */
1691                  if (FindConfigFile(path) != 0)
1692                      return MI_RESULT_OK;
1693              
1694                  /* Open the configuration file */
1695                  conf = Conf_Open(path);
1696                  if (!conf)
1697                  {
1698                      err(PAL_T("failed to open configuration file: %s"), scs(path));
1699                      return MI_RESULT_FAILED;
1700                  }
1701              
1702 krisbash 1.1     /* For each key=value pair in configuration file */
1703                  for (;;)
1704                  {
1705                      const char* key;
1706                      const char* value;
1707                      int r = Conf_Read(conf, &key, &value);
1708              
1709                      if (r == -1)
1710                      {
1711                          err(PAL_T("%s: %s\n"), scs(path), scs(Conf_Error(conf)));
1712                          miResult = MI_RESULT_FAILED;
1713                          goto cleanup;
1714                      }
1715              
1716                      if (r == 1)
1717                          break;
1718              
1719                      if (strcmp(key, "httpport") == 0)
1720                      {
1721                          char* end;
1722                          unsigned long x = Strtoul(value, &end, 10);
1723 krisbash 1.1 
1724                          if (*end != '\0' || x > USHRT_MAX)
1725                          {
1726                              err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path), 
1727                                  Conf_Line(conf), scs(key), scs(value));
1728                              miResult = MI_RESULT_FAILED;
1729                              goto cleanup;
1730                          }
1731              
1732                          opts.httpport = (unsigned short)x;
1733                      }
1734                      else if (strcmp(key, "httpsport") == 0)
1735                      {
1736                          char* end;
1737                          unsigned long x = Strtoul(value, &end, 10);
1738              
1739                          if (*end != '\0' || x > USHRT_MAX)
1740                          {
1741                              err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path), 
1742                                  Conf_Line(conf), scs(key), scs(value));
1743                              miResult = MI_RESULT_FAILED;
1744 krisbash 1.1                 goto cleanup;
1745                          }
1746              
1747                          opts.httpsport = (unsigned short)x;
1748                      }
1749                      else if (strcmp(key, "trace") == 0)
1750                      {
1751                          if (Strcasecmp(value, "MI_TRUE") == 0)
1752                          {
1753                              opts.trace = MI_TRUE;
1754                          }
1755                          else if (Strcasecmp(value, "MI_FALSE") == 0)
1756                          {
1757                              opts.trace = MI_FALSE;
1758                          }
1759                          else
1760                          {
1761                              err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path), 
1762                                  Conf_Line(conf), scs(key), scs(value));
1763                              miResult = MI_RESULT_FAILED;
1764                              goto cleanup;
1765 krisbash 1.1             }
1766                      }
1767                      else if (strcmp(key, "protocolhandler") == 0)
1768                      {
1769                          /* This is used in the miapi itself */
1770                      }
1771                      if (strcmp(key, "loglevel") == 0)
1772                      {
1773                          if (Log_SetLevelFromString(value) != 0)
1774                          {
1775                              err(PAL_T("%s(%u): invalid value for '%s': %s"), scs(path), 
1776                                  Conf_Line(conf), scs(key), scs(value));
1777                              miResult = MI_RESULT_FAILED;
1778                              goto cleanup;
1779                          }
1780                      }        
1781                      else if (strcmp(key, "logpath") == 0)
1782                      {
1783                          /* TODO - this is just a test tool? */
1784                      }
1785                      else if (strcmp(key, "logfile") == 0)
1786 krisbash 1.1         {
1787                          /* TODO - this is just a test tool? */
1788                      }
1789                      else if (IsNickname(key))
1790                      {
1791                          if (SetPathFromNickname(key, value) != 0)
1792                          {
1793                              err(PAL_T("SetPathFromNickname() failed"));
1794                              miResult = MI_RESULT_FAILED;
1795                              goto cleanup;
1796                          }
1797                      }
1798                      else
1799                      {
1800                          err(PAL_T("%s(%u): unknown key: %s"), scs(path), Conf_Line(conf),
1801                              scs(key));
1802                          miResult = MI_RESULT_FAILED;
1803                          goto cleanup;
1804                      }
1805                  }
1806              
1807 krisbash 1.1 cleanup:
1808                  /* Close configuration file */
1809                  Conf_Close(conf);
1810                  return miResult;
1811              }
1812              
1813              static MI_Result GetCommandLineDestDirOption(
1814                  int* argc_,
1815                  const MI_Char* argv[])
1816              {
1817                  int argc = *argc_;
1818                  int i;
1819                  const MI_Char* destdir = NULL;
1820              
1821                  for (i = 1; i < argc; )
1822                  {
1823                      if (Tcscmp(argv[i], MI_T("--destdir")) == 0)
1824                      {
1825                          if (i + 1 == argc)
1826                          {
1827                              err(PAL_T("missing argument for --destdir option"));
1828 krisbash 1.1                 return MI_RESULT_INVALID_PARAMETER;
1829                          }
1830              
1831                          destdir = argv[i+1];
1832                          memmove((char*)&argv[i], (char*)&argv[i+2], 
1833                              sizeof(char*) * (argc-i-1));
1834                          argc -= 2;
1835                      }
1836                      else if (Tcsncmp(argv[i], MI_T("--destdir="), 10) == 0)
1837                      {
1838                          destdir = argv[i] + 10;
1839                          memmove((char*)&argv[i], (char*)&argv[i+1], 
1840                              sizeof(char*) * (argc-i));
1841              
1842                          argc -= 1;
1843                      }
1844                      else
1845                          i++;
1846                  }
1847              
1848                  if (destdir)
1849 krisbash 1.1     {
1850              #if defined(CONFIG_ENABLE_WCHAR)
1851                      char _destdir[PAL_MAX_PATH_SIZE];
1852                      StrWcslcpy(_destdir, destdir, PAL_MAX_PATH_SIZE);
1853                      if (SetPath(ID_DESTDIR, _destdir) != 0)
1854              #else
1855                      if (SetPath(ID_DESTDIR, destdir) != 0)
1856              #endif
1857                      {
1858                          err(PAL_T("failed to set destdir"));
1859                          return MI_RESULT_FAILED;
1860                      }
1861                  }
1862              
1863                  *argc_ = argc;
1864              
1865                  return MI_RESULT_OK;
1866              }
1867              
1868              #define GETOPTSTATE_INITIALIZER { 0, { '\0' }, NULL, { '\0' } }
1869              #define GETOPT_OPT_SIZE 512
1870 krisbash 1.1 #define GETOPT_ERR_SIZE 512
1871              
1872              typedef struct _GetOptState
1873              {
1874                  int index;
1875                  MI_Char opt[GETOPT_OPT_SIZE];
1876                  const MI_Char* arg;
1877                  MI_Char err[GETOPT_ERR_SIZE];
1878              }
1879              GetOptState;
1880              
1881              static int GetOpt(
1882                  int* argc, 
1883                  const MI_Char* argv[], 
1884                  const MI_Char* opts[],
1885                  GetOptState* state)
1886              {
1887                  int i;
1888                  int j;
1889              
1890                  /* Clear state */
1891 krisbash 1.1     state->opt[0] = '\0';
1892                  state->arg = NULL;
1893                  state->err[0] = '\0';
1894              
1895                  for (i = state->index; i < *argc; i++)
1896                  {
1897                      if (argv[i][0] != '-')
1898                      {
1899                          state->index++;
1900                          continue;
1901                      }
1902              
1903                      /* Find option argv[i] */
1904                      for (j = 0; opts[j]; j++)
1905                      {
1906                          MI_Char opt[GETOPT_OPT_SIZE];
1907                          size_t n;
1908                          int hasArg;
1909              
1910                          /* Copy option name */
1911                          n = Tcslcpy(opt, opts[j], sizeof(opt)/sizeof(opt[0]));
1912 krisbash 1.1 
1913                          /* If option name too long */
1914                          if (n >= sizeof(opt))
1915                          {
1916                              Tcslcpy(state->err, MI_T("bad parameter"), sizeof(state->err)/sizeof(state->err[0]));
1917                              return -1;
1918                          }
1919              
1920                          /* If option name zero-length */
1921                          if (n == 0)
1922                          {
1923                              Tcslcpy(state->err, MI_T("bad parameter"), sizeof(state->err)/sizeof(state->err[0]));
1924                              return -1;
1925                          }
1926              
1927                          /* If option has argument */
1928                  #ifdef _PREFAST_
1929                   #pragma prefast(push)
1930                   #pragma prefast(disable:26014) 
1931                  #endif
1932                          if (opt[n-1] == ':')
1933 krisbash 1.1             {
1934                              hasArg = 1;
1935                              opt[n-1] = '\0';
1936                          }
1937                          else
1938                              hasArg = 0;
1939                  #ifdef _PREFAST_
1940                   #pragma prefast(pop)
1941                  #endif
1942              
1943                          /* Does argv[i] match this option? */
1944                          if (Tcscmp(argv[i], opt) == 0)
1945                          {
1946                              if (hasArg)
1947                              {
1948                                  if (i + 1 == *argc)
1949                                  {
1950                                      Tcslcpy(state->err, MI_T("missing option argument: "), 
1951                                          sizeof(state->err)/sizeof(state->err[0]));
1952                                      Tcslcat(state->err, opt, sizeof(state->err)/sizeof(state->err[0]));
1953                                      return -1;
1954 krisbash 1.1                     }
1955              
1956                                  Tcslcpy(state->opt, argv[i], sizeof(state->opt)/sizeof(state->opt[0]));
1957                                  state->arg =  argv[i+1];
1958                                  memmove((void*)&argv[i], (void*)&argv[i+2],
1959                                      sizeof(char*) * ((*argc) - i - 1));
1960                                  *argc -= 2;
1961                                  return 0;
1962                              }
1963                              else
1964                              {
1965                                  Tcslcpy(state->opt, argv[i], sizeof(state->opt)/sizeof(state->opt[0]));
1966                                  memmove((void*)&argv[i], (void*)&argv[i+1], 
1967                                      sizeof(char*) * ((*argc) - i));
1968                                  *argc -= 1;
1969                                  return 0;
1970                              }
1971                          }
1972                          else if (hasArg && 
1973                              Tcsncmp(argv[i], opt, n-1) == 0 && argv[i][n-1] == '=')
1974                          {
1975 krisbash 1.1                 Tcslcpy(state->opt, argv[i], sizeof(state->opt)/sizeof(state->opt[0]));
1976                              state->opt[n-1] = '\0';
1977                              state->arg =  &argv[i][n];
1978                              memmove((void*)&argv[i], (void*)&argv[i+1], 
1979                                  sizeof(char*) * ((*argc) - i));
1980                              *argc -= 1;
1981                              return 0;
1982                          }
1983                      }
1984              
1985                      /* Unknown option */
1986                      Tcslcpy(state->err, MI_T("unknown option: "), sizeof(state->err)/sizeof(state->err[0]));
1987                      Tcslcat(state->err, argv[i], sizeof(state->err)/sizeof(state->err[0]));
1988                      return -1;
1989                  }
1990              
1991                  /* Done */
1992                  return 1;
1993              }
1994              static MI_Result GetCommandLineOptions(
1995                  int* argc,
1996 krisbash 1.1     const MI_Char* argv[])
1997              {
1998                  GetOptState state = GETOPTSTATE_INITIALIZER;
1999                  const MI_Char* supportedOptions[] =
2000                  {
2001                      MI_T("-h"),
2002                      MI_T("-q"),
2003                      MI_T("-t"),
2004                      MI_T("-s"),
2005                      MI_T("-shallow"),
2006                      MI_T("-synchronous"),
2007                      MI_T("-n"),
2008                      MI_T("-R:"),
2009                      MI_T("-ac:"),
2010                      MI_T("-rc:"),
2011                      MI_T("-r:"),
2012                      MI_T("-rr:"),
2013                      MI_T("-rc:"),
2014                      MI_T("-u:"),
2015                      MI_T("-p:"),
2016                      MI_T("-S"),
2017 krisbash 1.1         MI_T("--summary"),
2018                      MI_T("--prefix:"),
2019                      MI_T("--libdir:"),
2020                      MI_T("--bindir:"),
2021                      MI_T("--localstatedir:"),
2022                      MI_T("--sysconfdir:"),
2023                      MI_T("--providerdir:"),
2024                      MI_T("--certsdir:"),
2025                      MI_T("--rundir:"),
2026                      MI_T("--logdir:"),
2027                      MI_T("--pidfile:"),
2028                      MI_T("--logfile:"),
2029                      MI_T("--registerdir:"),
2030                      MI_T("--socketfile:"),
2031                      MI_T("--pemfile:"),
2032                      MI_T("--keyfile:"),
2033                      MI_T("--agentprogram:"),
2034                      MI_T("--serverprogram:"),
2035                      MI_T("--stdout:"),
2036                      MI_T("--stderr:"),
2037                      MI_T("--querylang:"),
2038 krisbash 1.1         MI_T("--queryexpr:"),
2039                      NULL,
2040                  };
2041              
2042                  for (;;)
2043                  {
2044                      int r = GetOpt(argc, argv, supportedOptions, &state);
2045              
2046                      if (r == 1)
2047                          break;
2048              
2049                      if (r == -1)
2050                      {
2051                          Ftprintf(serr, PAL_T("error: %T\n"), tcs(state.err));
2052                          Ftprintf(serr, PAL_T("Try -h for help\n"));
2053                          return MI_RESULT_INVALID_PARAMETER;
2054                      }
2055              
2056                      if (Tcscmp(state.opt, PAL_T("-h")) == 0)
2057                      {
2058                          opts.help = MI_TRUE;
2059 krisbash 1.1         }
2060                      else if (Tcscmp(state.opt,  PAL_T("-q")) == 0)
2061                      {
2062                          opts.quiet = MI_TRUE;
2063                      }
2064                      else if (Tcscmp(state.opt,  PAL_T("-t")) == 0)
2065                      {
2066                          opts.trace = MI_TRUE;
2067                      }
2068                      else if (Tcscmp(state.opt,  PAL_T("-s")) == 0)
2069                      {
2070                          opts.suppressResults = MI_TRUE;
2071                      }
2072                      else if (Tcscmp(state.opt,  PAL_T("-shallow")) == 0)
2073                      {
2074                          opts.shallow = MI_TRUE;
2075                      }
2076                      else if (Tcscmp(state.opt,  PAL_T("-synchronous")) == 0)
2077                      {
2078                          opts.synchronous = MI_TRUE;
2079                      }
2080 krisbash 1.1         else if (Tcscmp(state.opt,  PAL_T("-n")) == 0)
2081                      {
2082                          opts.nulls = MI_TRUE;
2083                      }
2084                      else if (Tcscmp(state.opt,  PAL_T("-R")) == 0)
2085                      {
2086                          MI_Char *end;
2087                          opts.repeat = Tcstol(state.arg, &end, 10);
2088              
2089                          if (opts.repeat <= 0)
2090                          {
2091                              err(PAL_T("bad value for -R: %T"), tcs(state.arg));
2092                              return MI_RESULT_INVALID_PARAMETER;
2093                          }
2094                      }
2095                      else if (Tcscmp(state.opt,  PAL_T("-ac")) == 0)
2096                      {
2097                          opts.assocClass = state.arg;
2098                      }
2099                      else if (Tcscmp(state.opt,  PAL_T("-rc")) == 0)
2100                      {
2101 krisbash 1.1             opts.resultClass = state.arg;
2102                      }
2103                      else if (Tcscmp(state.opt,  PAL_T("-r")) == 0)
2104                      {
2105                          opts.role = state.arg;
2106                      }
2107                      else if (Tcscmp(state.opt,  PAL_T("-rr")) == 0)
2108                      {
2109                          opts.resultRole = state.arg;
2110                      }
2111                      else if (Tcscmp(state.opt,  PAL_T("-u")) == 0)
2112                      {
2113                          opts.user = state.arg;
2114                      }
2115                      else if (Tcscmp(state.opt,  PAL_T("-p")) == 0)
2116                      {
2117                          opts.password = state.arg;
2118                      }
2119                      else if (Tcscmp(state.opt,  PAL_T("--stdout")) == 0)
2120                      {
2121                          FILE* os;
2122 krisbash 1.1 #if defined(_MSC_VER)
2123                          FILE* fp;
2124                          os = (_wfopen_s(&fp, state.arg, PAL_T("wb")) == 0 ? fp : NULL);
2125              #else
2126                          {
2127              #if defined(CONFIG_ENABLE_WCHAR)
2128                              char tmp[50];
2129                              StrWcslcpy(tmp, state.arg, sizeof(tmp));
2130                              os = File_Open(tmp, "wb");
2131              #else
2132                              os = File_Open(state.arg, "wb");
2133              #endif
2134                          }
2135              #endif
2136              
2137                          if (!os)
2138                              err(PAL_T("failed to open: %T"), tcs(state.arg));
2139              
2140                          sout = os;
2141                      }
2142                      else if (Tcscmp(state.opt, PAL_T("--stderr")) == 0)
2143 krisbash 1.1         {
2144                          FILE* os;
2145              #if defined(_MSC_VER)
2146                          FILE* fp;
2147                          os = (_wfopen_s(&fp, state.arg, PAL_T("wb")) == 0 ? fp : NULL);
2148              #else
2149                          {
2150              #if defined(CONFIG_ENABLE_WCHAR)
2151                              char tmp[50];
2152                              StrWcslcpy(tmp, state.arg, sizeof(tmp));
2153                              os = File_Open(tmp, "wb");
2154              #else
2155                              os = File_Open(state.arg, "wb");
2156              #endif
2157                          }
2158              #endif
2159              
2160                          if (!os)
2161                              err(PAL_T("failed to open: %T"), tcs(state.arg));
2162              
2163                          serr = os;
2164 krisbash 1.1         }
2165                      else if (Tcscmp(state.opt, PAL_T("--querylang")) == 0)
2166                      {
2167                          opts.querylang = state.arg;
2168                      }
2169                      else if (Tcscmp(state.opt, PAL_T("--queryexpr")) == 0)
2170                      {
2171                          opts.queryexpr = state.arg;
2172                      }
2173                      else if (Tcscmp(state.opt, PAL_T("--summary")) == 0 ||
2174                               Tcscmp(state.opt, PAL_T("-S")) == 0)
2175                      {
2176                          opts.summary = MI_TRUE;
2177                      }
2178              #if 0
2179                      else if (Tcsncmp(state.opt, PAL_T("--"), 2) == 0 && IsNickname(state.opt+2))
2180                      {
2181                          if (SetPathFromNickname(state.opt+2, state.arg) != 0)
2182                              err(PAL_T("SetPathFromNickname() failed"));
2183                      }
2184              #endif
2185 krisbash 1.1     }
2186              
2187                  return MI_RESULT_OK;
2188              }
2189              
2190              const MI_Char USAGE[] = MI_T("\
2191              Usage: %T [OPTIONS] COMMAND ...\n\
2192              \n\
2193              This tool sends requests to the CIM server.\n\
2194              \n\
2195              OPTIONS:\n\
2196                  -h                  Print this help message.\n\
2197                  -q                  Operate quietly.\n\
2198                  -t                  Enable diagnostic tracing.\n\
2199                  -R N                Repeat command N times.\n\
2200                  -shallow            Use shallow inheritance (see 'ei' command).\n\
2201                  -synchronous        Executes command in synchronous mode.\n\
2202                  -ac CLASSNAME       Association class (see 'a' and 'r' commands).\n\
2203                  -rc CLASSNAME       Result class (see 'a' command).\n\
2204                  -r ROLE             Role (see 'a' and 'r' commands).\n\
2205                  -rr ROLE            Result role (see 'a' command).\n\
2206 krisbash 1.1     -n                  Show null properties.\n\
2207                  -u USERNAME         Username.\n\
2208                  -p PASSWORD         User's password.\n\
2209                  -id                 Send identify request.\n\
2210                  --socketfile PATH   Talk to the server server whose socket file resides\n\
2211                                      at the location given by the path argument.\n\
2212                  --httpport          Connect on this port instead of default.\n\
2213                  --httpsport         Connect on this secure port instead of default.\n\
2214                  --querylang         Query language (for 'ei', 'sub' command).\n\
2215                  --queryexpr         Query expression (for 'ei', 'sub' command).\n\
2216              \n\
2217              COMMANDS:\n\
2218                  noop\n\
2219                      Perform a no-op operation.\n\
2220                  gi NAMESPACE INSTANCENAME\n\
2221                      Peform a CIM [g]et [i]nstance operation.\n\
2222                  ci NAMESPACE NEWINSTANCE\n\
2223                      Peform a CIM [c]reate [i]nstance operation.\n\
2224                  mi NAMESPACE MODIFIEDINSTANCE\n\
2225                      Peform a CIM [m]odify [i]nstance operation.\n\
2226                  di NAMESPACE INSTANCENAME\n\
2227 krisbash 1.1         Peform a CIM [d]elete [i]nstance operation.\n\
2228                  ei [-shallow] NAMESPACE CLASSNAME\n\
2229                      Peform a CIM [e]numerate [i]nstances operation.\n\
2230                  iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\
2231                      Peform a CIM extrinisic method [i]nvocation operation.\n\
2232                  a [-ac -rc -r -rr ] NAMESPACE INSTANCENAME\n\
2233                      Perform a CIM [a]ssociator instances operation.\n\
2234                  r [-ac -r] NAMESPACE INSTANCENAME (references)\n\
2235                      Perform a CIM [r]eference instances operation.\n\
2236                  gc NAMESPACE CLASSENAME\n\
2237                      Peform a CIM [g]et [c]lass operation.\n\
2238                  enc INSTANCE\n\
2239                      Attempt to encode and print the given instance representation.\n\
2240                  wql NAMESPACE WQLQUERY\n\
2241                      Peform a WQL query operation.\n\
2242                  cql NAMESPACE CQLQUERY\n\
2243                      Peform a CQL query operation.\n\
2244                  sub NAMESPACE\n\
2245                      Peform a subscribe to indication operation.\n\
2246              \n\
2247              INSTANCENAME and PARAMETERS format:\n\
2248 krisbash 1.1     { class_name property_name property_value property_name property_value }\n\
2249                      property_value is either a string value, or can be an INSTANCENAME.\n\
2250                      property_value can also be an array taking the form [ property_value property_value ].\n\
2251              \n");
2252              
2253              /*
2254               * Signal handler that catch SIGINT signal, the signal
2255               * is triggered by CTRL+C from console; In case of
2256               * SIGINT signal, need to cancel the active operation
2257               * and exit
2258               *
2259               */
2260              void MI_MAIN_CALL SignalHandler(int signo)
2261              {
2262                  err(PAL_T("Quit program upon receiving ctrl+c"), signo);
2263                  if (gop.ft)
2264                  {
2265                      if (s_finished == 0)
2266                      {
2267                          s_finished = 1;
2268                          CondLock_Broadcast((ptrdiff_t)(&s_finished));
2269 krisbash 1.1         }
2270              
2271                      Ftprintf(sout, MI_T("Cancel the operation"));
2272                      MI_Operation_Cancel(&gop, MI_REASON_SHUTDOWN);
2273                      /* Close opeartion will be hung due to */
2274                      /* the operation is not get final result yet */
2275                      /* need to enable this code after end to end cancel was completed */
2276                      /* MI_Operation_Close(&gop); */
2277                      /* Ftprintf(sout, MI_T("Closed the operation")); */
2278                      Sleep_Milliseconds(200);
2279                  }
2280                  exit(1);
2281              }
2282              
2283              /*
2284               * Set up signal handler to catch SIGINT signal
2285               *
2286               */
2287              void CatchCtrlC()
2288              {
2289                  if (signal(SIGINT, SignalHandler) == SIG_ERR)
2290 krisbash 1.1         err(PAL_T("cannot catch signal: SIGINT\n"));
2291              }
2292              
2293              MI_Result climain(int argc, const MI_Char* argv[])
2294              {
2295                  MI_Application miApplication = MI_APPLICATION_NULL;
2296                  MI_Session miSession = MI_SESSION_NULL;
2297                  MI_Result miResult;
2298                  MI_DestinationOptions _miDestinationOptions = MI_DESTINATIONOPTIONS_NULL;
2299                  MI_DestinationOptions *miDestinationOptions = NULL;
2300                  MI_UserCredentials miUserCredentials = {0};
2301              
2302                  /*Log_OpenStdErr();
2303                  Log_SetLevel(LOG_VERBOSE);*/
2304                  CatchCtrlC();
2305              
2306                  // Setup default stderr and stdout streams:
2307                  serr = stderr;
2308                  sout = stdout;
2309              
2310                  arg0 = argv[0];
2311 krisbash 1.1 
2312                  // const MI_Uint64 CONNECT_TIMEOUT_USEC = 10 * 1000 * 1000;
2313              
2314                  // Get the options:
2315                  miResult = GetCommandLineDestDirOption(&argc, argv);
2316                  if (miResult != MI_RESULT_OK)
2317                  {
2318                      return miResult;
2319                  }
2320              
2321                  // Get configuration file options:
2322                  miResult = GetConfigFileOptions();
2323                  if (miResult != MI_RESULT_OK)
2324                  {
2325                      return miResult;
2326                  }
2327              
2328                  // Get the options:
2329                  miResult = GetCommandLineOptions(&argc, argv);
2330                  if (miResult != MI_RESULT_OK)
2331                  {
2332 krisbash 1.1         return miResult;
2333                  }
2334                  // There must be at least 1 argument left:
2335                  if (argc < 2)
2336                  {
2337                      if (argc >= 1)
2338                      {
2339                          Ftprintf(sout, USAGE, tcs(argv[0]));
2340                          if (opts.help)
2341                              miResult = MI_RESULT_OK;
2342                          else
2343                              miResult = MI_RESULT_INVALID_PARAMETER;
2344                      }
2345                      else
2346                      {
2347                          Ftprintf(sout, USAGE, tcs(MI_T("omicli")));
2348                          miResult = MI_RESULT_INVALID_PARAMETER;
2349                      }
2350                      return miResult;
2351                  }
2352              
2353 krisbash 1.1     if (Tcscmp(argv[1], MI_T("enc")) != 0)
2354                  {
2355                      miResult = MI_Application_Initialize(0, NULL, NULL, &miApplication);
2356                      if (miResult != MI_RESULT_OK)
2357                          return miResult;
2358                      if (opts.user)
2359                      {
2360                          miDestinationOptions = &_miDestinationOptions;
2361                          miResult = MI_Application_NewDestinationOptions(&miApplication, miDestinationOptions);
2362                          if (miResult != MI_RESULT_OK)
2363                              goto CleanupApplication;
2364              
2365                          miUserCredentials.authenticationType = MI_AUTH_TYPE_BASIC;
2366                          miUserCredentials.credentials.usernamePassword.domain = MI_T("localhost");
2367                          miUserCredentials.credentials.usernamePassword.username = opts.user;
2368                          miUserCredentials.credentials.usernamePassword.password = opts.password;
2369              
2370                          miResult = MI_DestinationOptions_AddDestinationCredentials(miDestinationOptions, &miUserCredentials);
2371                          if (miResult != MI_RESULT_OK)
2372                              goto CleanupApplication;
2373                      }
2374 krisbash 1.1 
2375                      miResult = MI_Application_NewSession(&miApplication, NULL, NULL, miDestinationOptions, NULL, NULL, &miSession);
2376                      if (miResult != MI_RESULT_OK)
2377                          goto CleanupApplication;
2378              
2379                      // Remember start time (will calculate total time in PrintSummary()
2380                      s_startTime = CPU_GetTimeStamp();
2381                  }
2382              
2383                  if (Tcscmp(argv[1], MI_T("ei")) == 0)
2384                  {
2385                      int i;
2386                      for (i = 0; i < opts.repeat; i++)
2387                      {
2388                          if (opts.queryexpr)
2389                          {
2390                              miResult = QueryInstances(&miSession, argc, argv);
2391                              if (miResult != MI_RESULT_OK)
2392                                  goto CleanupSession;
2393                          }
2394                          else
2395 krisbash 1.1             {
2396                              miResult = EnumerateInstances(&miSession, argc, argv);
2397                              if (miResult != MI_RESULT_OK)
2398                                  goto CleanupSession;
2399                          }
2400                      }
2401                  }
2402                  else if (Tcscmp(argv[1], MI_T("id")) == 0)
2403                  {
2404                      const MI_Char* args[5];
2405                      int i;
2406              
2407                      if (argc != 2)
2408                      {
2409                          Ftprintf(serr, PAL_T("Usage: %T id\n\n"), tcs(arg0));
2410                          miResult = MI_RESULT_INVALID_PARAMETER;
2411                          goto CleanupSession;
2412                      }
2413              
2414                      args[0]= argv[0];
2415                      args[1]= MI_T("ei");
2416 krisbash 1.1         args[2]= MI_T("root/omi");
2417                      args[3]= MI_T("OMI_Identify");
2418                      args[4]= NULL;
2419              
2420                      for (i = 0; i < opts.repeat; i++)
2421                      {
2422                          miResult = EnumerateInstances(&miSession, 4, args);
2423                          if (miResult != MI_RESULT_OK)
2424                              goto CleanupSession;
2425                      }
2426                  }
2427                  else if (Tcscmp(argv[1], MI_T("wql")) == 0 ||
2428                           Tcscmp(argv[1], MI_T("cql")) == 0)
2429                  {
2430                      int i;
2431                      for (i = 0; i < opts.repeat; i++)
2432                      {
2433                          miResult = Query(&miSession, argc, argv);
2434                          if (miResult != MI_RESULT_OK)
2435                              goto CleanupSession;
2436                      }
2437 krisbash 1.1     }
2438                  else if (Tcscmp(argv[1], MI_T("noop")) == 0)
2439                  {
2440                      int i;
2441                      for (i = 0; i < opts.repeat; i++)
2442                      {
2443                          miResult = NoOp(&miSession, argc, argv);
2444                          if (miResult != MI_RESULT_OK)
2445                              goto CleanupSession;
2446                      }
2447                  }
2448                  else if (Tcscmp(argv[1], MI_T("enc")) == 0)
2449                  {
2450                      miResult = Encode(argc, argv);
2451                      goto CleanupApplication;
2452                  }
2453                  else if (Tcscmp(argv[1], MI_T("gi")) == 0)
2454                  {
2455                      int i;
2456                      for (i = 0; i < opts.repeat; i++)
2457                      {
2458 krisbash 1.1             miResult = GetInstance(&miSession, argc, argv);
2459                          if (miResult != MI_RESULT_OK)
2460                              goto CleanupSession;
2461                      }
2462                  }
2463                  else if (Tcscmp(argv[1], MI_T("ci")) == 0)
2464                  {
2465                      int i;
2466                      for (i = 0; i < opts.repeat; i++)
2467                      {
2468                          miResult = CreateInstance(&miSession, argc, argv);
2469                          if (miResult != MI_RESULT_OK)
2470                              goto CleanupSession;
2471                      }
2472                  }
2473                  else if (Tcscmp(argv[1], MI_T("mi")) == 0)
2474                  {
2475                      int i;
2476                      for (i = 0; i < opts.repeat; i++)
2477                      {
2478                          miResult = ModifyInstance(&miSession, argc, argv);
2479 krisbash 1.1             if (miResult != MI_RESULT_OK)
2480                              goto CleanupSession;
2481                      }
2482                  }
2483                  else if (Tcscmp(argv[1], MI_T("di")) == 0)
2484                  {
2485                      int i;
2486                      for (i = 0; i < opts.repeat; i++)
2487                      {
2488                          miResult = DeleteInstance(&miSession, argc, argv);
2489                          if (miResult != MI_RESULT_OK)
2490                              goto CleanupSession;
2491                      }
2492                  }
2493                  else if (Tcscmp(argv[1], MI_T("iv")) == 0)
2494                  {
2495                      int i;
2496                      for (i = 0; i < opts.repeat; i++)
2497                      {
2498                          miResult = Invoke(&miSession, argc, argv);
2499                          if (miResult != MI_RESULT_OK)
2500 krisbash 1.1                 goto CleanupSession;
2501                      }
2502                  }
2503                  else if (Tcscmp(argv[1], MI_T("a")) == 0)
2504                  {
2505                      int i;
2506                      for (i = 0; i < opts.repeat; i++)
2507                      {
2508                          miResult = Associators(&miSession, argc, argv);
2509                          if (miResult != MI_RESULT_OK)
2510                              goto CleanupSession;
2511                      }
2512                  }
2513                  else if (Tcscmp(argv[1], MI_T("r")) == 0)
2514                  {
2515                      int i;
2516                      for (i = 0; i < opts.repeat; i++)
2517                      {
2518                          miResult = References(&miSession, argc, argv);
2519                          if (miResult != MI_RESULT_OK)
2520                              goto CleanupSession;
2521 krisbash 1.1         }
2522                  }
2523                  else if (Tcscmp(argv[1], MI_T("gc")) == 0)
2524                  {
2525                      int i;
2526                      for (i = 0; i < opts.repeat; i++)
2527                      {
2528                          miResult = GetClass(&miSession, argc, argv);
2529                          if (miResult != MI_RESULT_OK)
2530                              goto CleanupSession;
2531                      }
2532                  }
2533                  else if (Tcscmp(argv[1], MI_T("sub")) == 0)
2534                  {
2535                      int i;
2536                      for (i = 0; i < opts.repeat; i++)
2537                      {
2538                          miResult = Subscribe(&miSession, argc, argv);
2539                          if (miResult != MI_RESULT_OK)
2540                              goto CleanupSession;
2541                      }
2542 krisbash 1.1     }
2543                  else
2544                  {
2545                      err(PAL_T("unknown command: %T"), tcs(argv[1]));
2546                      miResult = MI_RESULT_INVALID_PARAMETER;
2547                      goto CleanupSession;
2548                  }
2549              
2550                  if (opts.summary)
2551                      PrintSummary();
2552              
2553              CleanupSession:
2554                  MI_Session_Close(&miSession, NULL, NULL);
2555              
2556              CleanupApplication:
2557                  if (miDestinationOptions)
2558                      MI_DestinationOptions_Delete(miDestinationOptions);
2559              
2560                  MI_Application_Close(&miApplication);
2561              
2562                  if (sout != stdout)
2563 krisbash 1.1         fclose(sout);
2564              
2565                  if (serr != stdout)
2566                      fclose(serr);
2567              
2568                  return miResult;
2569              }

ViewCVS 0.9.2