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

   1 mike  1.1 /*
   2           **==============================================================================
   3           **
   4           ** Open Management Infrastructure (OMI)
   5           **
   6           ** Copyright (c) Microsoft Corporation
   7           ** 
   8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
   9           ** use this file except in compliance with the License. You may obtain a copy 
  10           ** of the License at 
  11           **
  12           **     http://www.apache.org/licenses/LICENSE-2.0 
  13           **
  14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
  16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
  17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
  18           **
  19           ** See the Apache 2 License for the specific language governing permissions 
  20           ** and limitations under the License.
  21           **
  22 mike  1.1 **==============================================================================
  23           */
  24           
  25           #include <climits>
  26           #include <cassert>
  27           #include <cstdlib>
  28           #include <cstdio>
  29           #include <string>
  30           #include <omiclient/client.h>
  31           #include <base/args.h>
  32           #include <base/result.h>
  33           #include <wql/wql.h>
  34           #include <base/strings.h>
  35           #include <base/paths.h>
  36           #include <base/conf.h>
  37           #include <base/env.h>
  38           #include <base/getopt.h>
  39           #include <base/io.h>
  40           #include <base/time.h>
  41           
  42           #define T MI_T
  43 mike  1.1 
  44           #if (MI_CHAR_TYPE == 1)
  45           #define STRF "%s"
  46           #else
  47           #define STRF "%S"
  48           #endif
  49           
  50           using namespace mi;
  51           
  52           const char* arg0;
  53           
  54           struct Options
  55           {
  56               bool help;
  57               bool quiet;
  58               bool suppressResults;
  59               bool trace;
  60               bool shallow;
  61               int repeat;
  62               String assocClass;
  63               String resultClass;
  64 mike  1.1     String role;
  65               String resultRole;
  66               String user;
  67               String password;
  68               Uint64 timeOut;
  69               unsigned int httpport;
  70               unsigned int httpsport;
  71               bool nulls;
  72               String querylang;
  73               String queryexpr;
  74           
  75               Options()
  76               {
  77                   Clear();
  78               }
  79           
  80               void Clear()
  81               {
  82                   help = false;
  83                   quiet = false;
  84                   suppressResults = false;
  85 mike  1.1         trace = false;
  86                   shallow = false;
  87                   repeat = 1;
  88                   assocClass.Clear();
  89                   resultClass.Clear();
  90                   role.Clear();
  91                   resultRole.Clear();
  92                   user.Clear();
  93                   password.Clear();
  94                   timeOut = 90 * 1000 * 1000;
  95                   httpport = CONFIG_HTTPPORT;
  96                   httpsport = CONFIG_HTTPSPORT;
  97                   nulls = false;
  98                   querylang.Clear();
  99                   queryexpr.Clear();
 100               }
 101           };
 102           
 103           static Options opts;
 104           
 105           static FILE* sout = stdout;
 106 mike  1.1 static FILE* serr = stderr;
 107           
 108           PRINTF_FORMAT(1, 2)
 109           static void err(const char* fmt, ...)
 110           {
 111               fprintf(serr, "%s: ", arg0);
 112           
 113               va_list ap;
 114               va_start(ap, fmt);
 115               vfprintf(serr, fmt, ap);
 116               va_end(ap);
 117           
 118               fputc('\n', serr);
 119           }
 120           
 121           static String MakeString(const char* str)
 122           {
 123               String s;
 124               while (*str)
 125                   s += MI_Char(*str++);
 126           
 127 mike  1.1     return s;
 128           }
 129           
 130           static std::string ZToStr(const MI_Char* str)
 131           {
 132               std::string r;
 133           
 134               while (*str)
 135                   r += char(*str++);
 136           
 137               return r;
 138           }
 139           
 140           static int FindConfigFile(char path[MAX_PATH_SIZE])
 141           {
 142               /* Look in current directory */
 143               {
 144                   Strlcpy(path, "./.omiclirc", MAX_PATH_SIZE);
 145           
 146                   if (access(path, R_OK) == 0)
 147                       return 0;
 148 mike  1.1     }
 149           
 150               /* Look in HOME directory */
 151               char* home = Dupenv("HOME");
 152               if (home)
 153               {
 154                   Strlcpy(path, home, MAX_PATH_SIZE);
 155                   Strlcat(path, "/.omiclirc", MAX_PATH_SIZE);
 156           
 157                   if (access(path, R_OK) == 0)
 158                   {
 159                       free(home);
 160                       return 0;
 161                   }
 162                   free(home);
 163               }
 164           
 165               /* Look in system config directory */
 166               {
 167                   Strlcpy(path, GetPath(ID_SYSCONFDIR), MAX_PATH_SIZE);
 168                   Strlcat(path, "/omicli.conf", MAX_PATH_SIZE);
 169 mike  1.1 
 170                   if (access(path, R_OK) == 0)
 171                       return 0;
 172               }
 173           
 174               /* Not found */
 175               return -1;
 176           }
 177           
 178           static int GetConfigFileOptions()
 179           {
 180               char path[MAX_PATH_SIZE];
 181               Conf* conf;
 182           
 183               /* Form the configuration file path (silently ignore if not found) */
 184               if (FindConfigFile(path) != 0)
 185                   return 0;
 186           
 187               /* Open the configuration file */
 188               conf = Conf_Open(path);
 189               if (!conf)
 190 mike  1.1     {
 191                   err("failed to open configuration file: %s", path);
 192                   return 1;
 193               }
 194           
 195               /* For each key=value pair in configuration file */
 196               for (;;)
 197               {
 198                   const char* key;
 199                   const char* value;
 200                   int r = Conf_Read(conf, &key, &value);
 201           
 202                   if (r == -1)
 203                   {
 204                       err("%s: %s\n", path, Conf_Error(conf));
 205                       return 1;
 206                   }
 207           
 208                   if (r == 1)
 209                       break;
 210           
 211 mike  1.1         if (strcmp(key, "httpport") == 0)
 212                   {
 213                       char* end;
 214                       unsigned long x = Strtoul(value, &end, 10);
 215           
 216                       if (*end != '\0' || x > USHRT_MAX)
 217                       {
 218                           err("%s(%u): invalid value for '%s': %s", path, 
 219                               Conf_Line(conf), key, value);
 220                           return 1;
 221                       }
 222           
 223                       opts.httpport = (unsigned short)x;
 224                   }
 225                   else if (strcmp(key, "httpsport") == 0)
 226                   {
 227                       char* end;
 228                       unsigned long x = Strtoul(value, &end, 10);
 229           
 230                       if (*end != '\0' || x > USHRT_MAX)
 231                       {
 232 mike  1.1                 err("%s(%u): invalid value for '%s': %s", path, 
 233                               Conf_Line(conf), key, value);
 234                           return 1;
 235                       }
 236           
 237                       opts.httpsport = (unsigned short)x;
 238                   }
 239                   else if (strcmp(key, "trace") == 0)
 240                   {
 241                       if (Strcasecmp(value, "true") == 0)
 242                       {
 243                           opts.trace = MI_TRUE;
 244                       }
 245                       else if (Strcasecmp(value, "false") == 0)
 246                       {
 247                           opts.trace = MI_FALSE;
 248                       }
 249                       else
 250                       {
 251                           err("%s(%u): invalid value for '%s': %s", path, 
 252                               Conf_Line(conf), key, value);
 253 mike  1.1                 return 1;
 254                       }
 255                   }
 256                   else if (IsNickname(key))
 257                   {
 258                       if (SetPathFromNickname(key, value) != 0)
 259                       {
 260                           err("SetPathFromNickname() failed");
 261                           return 1;
 262                       }
 263                   }
 264                   else
 265                   {
 266                       err("%s(%u): unknown key: %s", path, Conf_Line(conf), key);
 267                       return 1;
 268                   }
 269               }
 270           
 271               /* Close configuration file */
 272               Conf_Close(conf);
 273               return 0;
 274 mike  1.1 }
 275           
 276           static void GetCommandLineDestDirOption(
 277               int* argc_,
 278               const char* argv[])
 279           {
 280               int argc = *argc_;
 281               int i;
 282               const char* destdir = NULL;
 283           
 284               for (i = 1; i < argc; )
 285               {
 286                   if (strcmp(argv[i], "--destdir") == 0)
 287                   {
 288                       if (i + 1 == argc)
 289                           err("missing argument for --destdir option");
 290           
 291                       destdir = argv[i+1];
 292                       memmove((char*)&argv[i], (char*)&argv[i+2], 
 293                           sizeof(char*) * (argc-i-1));
 294                       argc -= 2;
 295 mike  1.1         }
 296                   else if (strncmp(argv[i], "--destdir=", 10) == 0)
 297                   {
 298                       destdir = argv[i] + 10;
 299                       memmove((char*)&argv[i], (char*)&argv[i+1], 
 300                           sizeof(char*) * (argc-i));
 301           
 302                       argc -= 1;
 303                   }
 304                   else
 305                       i++;
 306               }
 307           
 308               if (destdir)
 309               {
 310                   if (SetPath(ID_DESTDIR, destdir) != 0)
 311                       err("failed to set destdir");
 312               }
 313           
 314               *argc_ = argc;
 315           }
 316 mike  1.1 
 317           static int GetCommandLineOptions(
 318               int& argc,
 319               const char* argv[],
 320               Options& options)
 321           {
 322               GetOptState state = GETOPTSTATE_INITIALIZER;
 323               const char* supportedOptions[] =
 324               {
 325                   "-h",
 326                   "-q",
 327                   "-t",
 328                   "-s",
 329                   "-shallow",
 330                   "-n",
 331                   "-R:",
 332                   "-ac:",
 333                   "-rc:",
 334                   "-r:",
 335                   "-rr:",
 336                   "-rc:",
 337 mike  1.1         "-u:",
 338                   "-p:",
 339                   "--prefix:",
 340                   "--libdir:",
 341                   "--bindir:",
 342                   "--localstatedir:",
 343                   "--sysconfdir:",
 344                   "--providerdir:",
 345                   "--certsdir:",
 346                   "--rundir:",
 347                   "--logdir:",
 348                   "--pidfile:",
 349                   "--logfile:",
 350                   "--registerdir:",
 351                   "--socketfile:",
 352                   "--pemfile:",
 353                   "--keyfile:",
 354                   "--agentprogram:",
 355                   "--serverprogram:",
 356                   "--stdout:",
 357                   "--stderr:",
 358 mike  1.1         "--querylang:",
 359                   "--queryexpr:",
 360                   NULL,
 361               };
 362           
 363               for (;;)
 364               {
 365                   int r = GetOpt(&argc, argv, supportedOptions, &state);
 366           
 367                   if (r == 1)
 368                       break;
 369           
 370                   if (r == -1)
 371                   {
 372                       fprintf(serr, "error: %s\n", state.err);
 373                       fprintf(serr, "Try -h for help\n");
 374                       return 1;
 375                   }
 376           
 377                   if (strcmp(state.opt, "-h") == 0)
 378                   {
 379 mike  1.1             options.help = true;
 380                   }
 381                   else if (strcmp(state.opt, "-q") == 0)
 382                   {
 383                       options.quiet = true;
 384                   }
 385                   else if (strcmp(state.opt, "-t") == 0)
 386                   {
 387                       options.trace = true;
 388                   }
 389                   else if (strcmp(state.opt, "-s") == 0)
 390                   {
 391                       options.suppressResults = true;
 392                   }
 393                   else if (strcmp(state.opt, "-shallow") == 0)
 394                   {
 395                       options.shallow = true;
 396                   }
 397                   else if (strcmp(state.opt, "-n") == 0)
 398                   {
 399                       options.nulls = true;
 400 mike  1.1         }
 401                   else if (strcmp(state.opt, "-R") == 0)
 402                   {
 403                       options.repeat = atoi(state.arg);
 404           
 405                       if (options.repeat <= 0)
 406                       {
 407                           err("bad value for -R: %s", state.arg);
 408                           return 1;
 409                       }
 410                   }
 411                   else if (strcmp(state.opt, "-ac") == 0)
 412                   {
 413                       options.assocClass = MakeString(state.arg);
 414                   }
 415                   else if (strcmp(state.opt, "-rc") == 0)
 416                   {
 417                       options.resultClass = MakeString(state.arg);
 418                   }
 419                   else if (strcmp(state.opt, "-r") == 0)
 420                   {
 421 mike  1.1             options.role = MakeString(state.arg);
 422                   }
 423                   else if (strcmp(state.opt, "-rr") == 0)
 424                   {
 425                       options.resultRole = MakeString(state.arg);
 426                   }
 427                   else if (strcmp(state.opt, "-u") == 0)
 428                   {
 429                       options.user = MakeString(state.arg);
 430                   }
 431                   else if (strcmp(state.opt, "-p") == 0)
 432                   {
 433                       options.password = MakeString(state.arg);
 434                   }
 435                   else if (strcmp(state.opt, "--stdout") == 0)
 436                   {
 437                       FILE* os = Fopen(state.arg, "wb");
 438           
 439                       if (!os)
 440                           err("failed to open: %s", state.arg);
 441           
 442 mike  1.1             sout = os;
 443                   }
 444                   else if (strcmp(state.opt, "--stderr") == 0)
 445                   {
 446                       FILE* os = Fopen(state.arg, "wb");
 447           
 448                       if (!os)
 449                           err("failed to open: %s", state.arg);
 450           
 451                       serr = os;
 452                   }
 453                   else if (strcmp(state.opt, "--querylang") == 0)
 454                   {
 455                       options.querylang = MakeString(state.arg);
 456                   }
 457                   else if (strcmp(state.opt, "--queryexpr") == 0)
 458                   {
 459                       options.queryexpr = MakeString(state.arg);
 460                   }
 461                   else if (strncmp(state.opt, "--", 2) == 0 && IsNickname(state.opt+2))
 462                   {
 463 mike  1.1             if (SetPathFromNickname(state.opt+2, state.arg) != 0)
 464                           err("SetPathFromNickname() failed");
 465                   }
 466               }
 467           
 468               return 0;
 469           }
 470           
 471           const char USAGE[] = "\
 472           Usage: %s [OPTIONS] COMMAND ...\n\
 473           \n\
 474           This tool sends requests to the CIM server.\n\
 475           \n\
 476           OPTIONS:\n\
 477               -h                  Print this help message.\n\
 478               -q                  Operate quietly.\n\
 479               -t                  Enable diagnostic tracing.\n\
 480               -R N                Repeat command N times.\n\
 481               -shallow            Use shallow inheritance (see 'ei' command).\n\
 482               -ac CLASSNAME       Association class (see 'a' and 'r' commands).\n\
 483               -rc CLASSNAME       Result class (see 'a' command).\n\
 484 mike  1.1     -r ROLE             Role (see 'a' and 'r' commands).\n\
 485               -rr ROLE            Result role (see 'a' command).\n\
 486               -n                  Show null properties.\n\
 487               -u USERNAME         Username.\n\
 488               -p PASSWORD         User's password.\n\
 489               -id			Send identify request.\n\
 490               --socketfile PATH   Talk to the server server whose socket file resides\n\
 491                                   at the location given by the path argument.\n\
 492               --httpport		Connect on this port instead of default.\n\
 493               --httpsport		Connect on this secure port instead of default.\n\
 494               --querylang         Query language (for 'ei' command).\n\
 495               --queryexpr         Query expression (for 'ei' command).\n\
 496           \n\
 497           COMMANDS:\n\
 498               noop\n\
 499                   Perform a no-op operation.\n\
 500               gi NAMESPACE INSTANCENAME\n\
 501                   Peform a CIM [g]et [i]nstance operation.\n\
 502               ci NAMESPACE NEWINSTANCE\n\
 503                   Peform a CIM [c]create [i]nstance operation.\n\
 504               mi NAMESPACE MODIFIEDINSTANCE\n\
 505 mike  1.1         Peform a CIM [m]odify [i]nstance operation.\n\
 506               di NAMESPACE INSTANCENAME\n\
 507                   Peform a CIM [d]elete [i]nstance operation.\n\
 508               ei [-shallow] NAMESPACE CLASSNAME\n\
 509                   Peform a CIM [e]numerate [i]nstances operation.\n\
 510               iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\
 511                   Peform a CIM extrinisic method [i]nvocation operation.\n\
 512               a [-ac -rc -r -rr ] NAMESPACE INSTANCENAME\n\
 513                   Perform a CIM [a]ssociator instances operation.\n\
 514               r [-ac -r] NAMESPACE INSTANCENAME (references)\n\
 515                   Perform a CIM [r]eference instances operation.\n\
 516               enc INSTANCE\n\
 517                   Attempt to encode and print the given instance representation.\n\
 518               wql NAMESPACE WQLQUERY\n\
 519                   Peform a WQL query operation.\n\
 520           \n";
 521           
 522           // ATTN: support arrays.
 523           static bool ArgsToInstance(
 524               const char**& p, 
 525               const char** end, 
 526 mike  1.1     DInstance::MetaType metaType,
 527               bool key,
 528               DInstance& instanceOut)
 529           {
 530               if (p == end)
 531                   return false;
 532           
 533               // Consume opening brace:
 534               if (strcmp(*p++, "{") != 0)
 535                   return false;
 536           
 537               if (p == end)
 538                   return false;
 539           
 540               // Call the 'empty' constructor so that we can use placement operator.
 541               DInstance instance;
 542           
 543               if (metaType == DInstance::METHOD)
 544               {
 545                   instance = DInstance(T("Parameters"), DInstance::METHOD);
 546               }
 547 mike  1.1     else
 548               {
 549                   instance = DInstance(MakeString(*p++), DInstance::CLASS);
 550           
 551                   if (p == end)
 552                       return false;
 553               }
 554           
 555               // Consume name/value pairs:
 556               for (;;)
 557               {
 558                   if (strcmp(*p, "}") == 0)
 559                   {
 560                       p++;
 561                       break;
 562                   }
 563           
 564                   // Get name:
 565                   String name = MakeString(*p++);
 566           
 567                   if (p == end)
 568 mike  1.1             return false;
 569           
 570           
 571                   // Get value:
 572                   if (strcmp(*p, "{") == 0)
 573                   {
 574                       int nesting = 1;
 575                       const char** q = p;
 576                       q++;
 577           
 578                       // Find closing brace:
 579                       while (*q)
 580                       {
 581                           if (strcmp(*q, "{") == 0)
 582                               nesting++;
 583                           else if (strcmp(*q, "}") == 0)
 584                               nesting--;
 585           
 586                           q++;
 587           
 588                           if (nesting == 0)
 589 mike  1.1                     break;
 590                       }
 591           
 592                       // Handle missing closing brace:
 593                       if (q == end)
 594                           return false;
 595           
 596                       // Recursively call to obtain reference or embedded instance.
 597                       DInstance tmpInstance;
 598                       if (!ArgsToInstance(p, q, DInstance::CLASS, key, tmpInstance))
 599                       {
 600                           return false;
 601                       }
 602           
 603                       if (!instance.AddInstance(name, tmpInstance, false, key))
 604                           return false;
 605                   }
 606                   else if (strcmp(*p, "[") == 0)
 607                   {
 608                       Array<String> array;
 609                       p++;
 610 mike  1.1 
 611                       // Find closing brace:
 612                       while (*p && strcmp(*p, "]") != 0)
 613                       {
 614                           array.PushBack(MakeString(*p++));
 615                       }
 616           
 617                       // Handle missing closing brace:
 618                       if (p == end)
 619                           return false;
 620           
 621                       if (!instance.AddStringA(name, array, false, key))
 622                           return false;
 623           
 624                       p++;
 625                   }
 626                   else
 627                   {
 628                       // Get value:
 629                       String value = MakeString(*p++);
 630           
 631 mike  1.1             // Add property:
 632                       if (!instance.AddString(name, value, false, key))
 633                           return false;
 634           
 635                       if (p == end)
 636                           break;
 637                   }
 638               }
 639           
 640               instanceOut = instance;
 641               return true;
 642           }
 643           
 644           static int NoOp(Client& client, int argc, const char* argv[])
 645           {
 646               MI_UNUSED(argv);
 647           
 648               if (argc != 2)
 649               {
 650                   fprintf(serr, "Usage: %s noop\n\n", arg0);
 651                   return 1;
 652 mike  1.1     }
 653           
 654               if (!client.NoOp(opts.timeOut))
 655               {
 656                   err("noop request failed");
 657                   return 1;
 658               }
 659           
 660               if (!opts.quiet)
 661                   fprintf(sout, "got noop response\n");
 662           
 663               return 0;
 664           }
 665           
 666           static void PrintInstance(const DInstance& inst, bool nulls)
 667           {
 668               inst.Print(sout, 0, nulls);
 669           }
 670           
 671           static int Encode(int argc, const char* argv[])
 672           {
 673 mike  1.1     if (argc < 3)
 674               {
 675                   fprintf(serr, "Usage: %s noop CLASSNAME KEYBINDING\n\n", arg0);
 676                   return 1;
 677               }
 678           
 679               DInstance inst;
 680               argc -= 2;
 681               argv += 2;
 682           
 683               if (!ArgsToInstance(argv, argv + argc, DInstance::CLASS, false, inst))
 684               {
 685                   err("invalid instance name specification");
 686                   return 1;
 687               }
 688           
 689               if (!opts.quiet)
 690               {
 691                   PrintInstance(inst, opts.nulls);
 692               }
 693           
 694 mike  1.1     return 0;
 695           }
 696           
 697           static MI_Result s_result;
 698           static bool s_done;
 699           
 700           static int EnumerateInstances(Client& client, int argc, const char* argv[])
 701           {
 702               if (argc != 4)
 703               {
 704                   fprintf(serr, "Usage: %s ei NAMESPACE CLASSNAME\n\n", arg0);
 705                   return 1;
 706               }
 707           
 708               // Default to WQL query language.
 709               if (opts.querylang.GetSize() && opts.queryexpr.GetSize() == 0)
 710               {
 711                   opts.querylang = T("WQL");
 712               }
 713           
 714               // Reject if --querylang option present but not --queryexpr option.
 715 mike  1.1     if (opts.querylang.GetSize() && opts.queryexpr.GetSize() == 0)
 716               {
 717                   err("--querylang options requires --queryexpr option");
 718                   return 1;
 719               }
 720           
 721               const String nameSpace = MakeString(argv[2]);
 722               const String className = MakeString(argv[3]);
 723               Array<DInstance> instances;
 724               MI_Result result;
 725               Uint64 msgID = 0;
 726           
 727               s_result = MI_RESULT_OK;
 728               s_done = false;
 729           
 730               if (!client.EnumerateInstancesAsync(nameSpace, className, !opts.shallow, 
 731                   opts.querylang, opts.queryexpr,  msgID))
 732               {
 733                   err("communication failed (cannot connect/initiate command)");
 734                   return 1;
 735               }
 736 mike  1.1 
 737               Uint64 endTime, now;
 738           
 739               if (Time_Now(&now) != MI_RESULT_OK)
 740                   return 3;
 741           
 742               endTime = now + opts.timeOut;
 743           
 744               for (;!s_done && endTime >= now;)
 745               {
 746                   client.Run(1000);
 747           
 748                   if (Time_Now(&now) != MI_RESULT_OK)
 749                       break;
 750               }
 751           
 752               if (!s_done)
 753               {
 754                   err("communication failed (timeout)");
 755                   return 1;
 756               }
 757 mike  1.1 
 758               result = s_result;
 759           
 760               if (result != MI_RESULT_OK)
 761               {
 762                   return 2;
 763               }
 764           
 765               return 0;
 766           }
 767           
 768           static int Query(Client& client, int argc, const char* argv[])
 769           {
 770               // Check arguments
 771               if (argc != 4)
 772               {
 773                   fprintf(serr, "Usage: %s wql NAMESPACE QUERY\n\n", arg0);
 774                   return 1;
 775               }
 776           
 777               // Extract query options.
 778 mike  1.1     opts.querylang = T("WQL");
 779               opts.queryexpr = MakeString(argv[3]);
 780           
 781               // Always perform shallow query.
 782               opts.shallow = false;
 783           
 784               // Pre-compile the query (to get className).
 785               std::string className;
 786               {
 787                   WQL* wql = WQL_Parse(opts.queryexpr.Str(), NULL);
 788           
 789                   if (!wql)
 790                   {
 791                       fprintf(serr, "%s : invalid query: %s\n\n", arg0, argv[3]);
 792                       return 1;
 793                   }
 794           
 795                   className = ZToStr(wql->className);
 796                   WQL_Delete(wql);
 797               }
 798           
 799 mike  1.1     // Invoke enumerate with these arguments.
 800               const char* args[5];
 801               args[0] = argv[0];
 802               args[1] = "ei";
 803               args[2] = argv[2]; /* namespace */
 804               args[3] = className.c_str();
 805               args[4] = NULL;
 806           
 807               return EnumerateInstances(client, 4, args);
 808           }
 809           
 810           static int GetInstance(Client& client, int argc, const char* argv[])
 811           {
 812               if (argc < 4)
 813               {
 814                   fprintf(serr, "Usage: %s gi NAMESPACE INSTANCENAME\n\n", arg0);
 815                   return 1;
 816               }
 817           
 818               const String nameSpace = MakeString(argv[2]);
 819           
 820 mike  1.1     DInstance instanceName;
 821           
 822               argc -= 3;
 823               argv += 3;
 824               const char** p = argv;
 825               const char** end = p + argc;
 826           
 827               if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
 828               {
 829                   err("invalid instance name specification");
 830                   return 1;
 831               }
 832           
 833               if (p != end)
 834               {
 835                   err("extraneous arguments after instance name");
 836                   return 1;
 837               }
 838           
 839               DInstance instance;
 840               MI_Result result;
 841 mike  1.1 
 842               if (!client.GetInstance(nameSpace, instanceName, opts.timeOut, instance, 
 843                   result))
 844               {
 845                   err("communication failed");
 846                   return 1;
 847               }
 848           
 849               if (!opts.quiet && result == MI_RESULT_OK)
 850                   PrintInstance(instance, opts.nulls);
 851           
 852               if (result != MI_RESULT_OK)
 853               {
 854                   if (!opts.suppressResults)
 855                       err("result: " STRF , Result_ToString(result));
 856                   return 2;
 857               }
 858           
 859               return 0;
 860           }
 861           
 862 mike  1.1 static int CreateInstance(Client& client, int argc, const char* argv[])
 863           {
 864               if (argc < 4)
 865               {
 866                   fprintf(serr, "Usage: %s ci NAMESPACE INSTANCE\n\n", arg0);
 867                   return 1;
 868               }
 869           
 870               const String nameSpace = MakeString(argv[2]);
 871           
 872               DInstance instance;
 873           
 874               argc -= 3;
 875               argv += 3;
 876               const char** p = argv;
 877               const char** end = p + argc;
 878           
 879               if (!ArgsToInstance(p, end, DInstance::CLASS, true, instance))
 880               {
 881                   err("invalid instanceName name specification");
 882                   return 1;
 883 mike  1.1     }
 884           
 885               if (p != end)
 886               {
 887                   err("extraneous arguments after instanceName name");
 888                   return 1;
 889               }
 890           
 891               DInstance instanceName;
 892               MI_Result result;
 893           
 894               if (!client.CreateInstance(nameSpace, instance, opts.timeOut, instanceName, 
 895                   result))
 896               {
 897                   err("communication failed");
 898                   return 1;
 899               }
 900           
 901               if (!opts.quiet && result == MI_RESULT_OK)
 902                   PrintInstance(instanceName, true);
 903           
 904 mike  1.1     if (result != MI_RESULT_OK)
 905               {
 906                   if (!opts.suppressResults)
 907                       err("result: " STRF, Result_ToString(result));
 908                   return 2;
 909               }
 910           
 911               return 0;
 912           }
 913           
 914           static int ModifyInstance(Client& client, int argc, const char* argv[])
 915           {
 916               if (argc < 4)
 917               {
 918                   fprintf(serr, "Usage: %s mi NAMESPACE INSTANCE\n\n", arg0);
 919                   return 1;
 920               }
 921           
 922               const String nameSpace = MakeString(argv[2]);
 923           
 924               DInstance instance;
 925 mike  1.1 
 926               argc -= 3;
 927               argv += 3;
 928               const char** p = argv;
 929               const char** end = p + argc;
 930           
 931               if (!ArgsToInstance(p, end, DInstance::CLASS, true, instance))
 932               {
 933                   err("invalid instanceName name specification");
 934                   return 1;
 935               }
 936           
 937               if (p != end)
 938               {
 939                   err("extraneous arguments after instanceName name");
 940                   return 1;
 941               }
 942           
 943               MI_Result result;
 944           
 945               if (!client.ModifyInstance(nameSpace, instance, opts.timeOut, result))
 946 mike  1.1     {
 947                   err("communication failed");
 948                   return 1;
 949               }
 950           
 951               if (result != MI_RESULT_OK)
 952               {
 953                   if (!opts.suppressResults)
 954                       err("result: " STRF, Result_ToString(result));
 955                   return 2;
 956               }
 957           
 958               return 0;
 959           }
 960           
 961           static int DeleteInstance(Client& client, int argc, const char* argv[])
 962           {
 963               if (argc < 4)
 964               {
 965                   fprintf(serr, "Usage: %s gi NAMESPACE INSTANCENAME\n\n", arg0);
 966                   return 1;
 967 mike  1.1     }
 968           
 969               const String nameSpace = MakeString(argv[2]);
 970           
 971               DInstance instanceName;
 972           
 973               argc -= 3;
 974               argv += 3;
 975               const char** p = argv;
 976               const char** end = p + argc;
 977           
 978               if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
 979               {
 980                   err("invalid instance name specification");
 981                   return 1;
 982               }
 983           
 984               if (p != end)
 985               {
 986                   err("extraneous arguments after instance name");
 987                   return 1;
 988 mike  1.1     }
 989           
 990               DInstance instance;
 991               MI_Result result;
 992           
 993               if (!client.DeleteInstance(nameSpace, instanceName, opts.timeOut, result))
 994               {
 995                   err("communication failed");
 996                   return 1;
 997               }
 998           
 999               if (result != MI_RESULT_OK)
1000               {
1001                   if (!opts.suppressResults)
1002                       err("result: " STRF, Result_ToString(result));
1003                   return 2;
1004               }
1005           
1006               return 0;
1007           }
1008           
1009 mike  1.1 static int Associators(Client& client, int argc, const char* argv[])
1010           {
1011               if (argc < 4)
1012               {
1013                   fprintf(serr, "Usage: %s a NAMESPACE INSTANCENAME\n\n", arg0);
1014                   return 1;
1015               }
1016           
1017               const String nameSpace = MakeString(argv[2]);
1018           
1019               DInstance instanceName;
1020           
1021               argc -= 3;
1022               argv += 3;
1023               const char** p = argv;
1024               const char** end = p + argc;
1025           
1026               if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
1027               {
1028                   err("invalid instance name specification");
1029                   return 1;
1030 mike  1.1     }
1031           
1032               if (p != end)
1033               {
1034                   err("extraneous arguments after instance name");
1035                   return 1;
1036               }
1037           
1038               Array<DInstance> instances;
1039               MI_Result result;
1040           
1041               if (!client.AssociatorInstances(
1042                   nameSpace, 
1043                   instanceName, 
1044                   opts.assocClass,
1045                   opts.resultClass,
1046                   opts.role,
1047                   opts.resultRole,
1048                   opts.timeOut, 
1049                   instances, 
1050                   result))
1051 mike  1.1     {
1052                   err("communication failed");
1053                   return 1;
1054               }
1055           
1056               if (!opts.quiet)
1057               {
1058                   for (Uint32 i = 0; i < instances.GetSize(); i++)
1059                       PrintInstance(instances[i], opts.nulls);
1060               }
1061           
1062               if (result != MI_RESULT_OK)
1063               {
1064                   if (!opts.suppressResults)
1065                       err("result: " STRF, Result_ToString(result));
1066                   return 2;
1067               }
1068           
1069               return 0;
1070           }
1071           
1072 mike  1.1 static int References(Client& client, int argc, const char* argv[])
1073           {
1074               if (argc < 4)
1075               {
1076                   fprintf(serr, "Usage: %s a NAMESPACE INSTANCENAME\n\n", arg0);
1077                   return 1;
1078               }
1079           
1080               const String nameSpace = MakeString(argv[2]);
1081           
1082               DInstance instanceName;
1083           
1084               argc -= 3;
1085               argv += 3;
1086               const char** p = argv;
1087               const char** end = p + argc;
1088           
1089               if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
1090               {
1091                   err("invalid instance name specification");
1092                   return 1;
1093 mike  1.1     }
1094           
1095               if (p != end)
1096               {
1097                   err("extraneous arguments after instance name");
1098                   return 1;
1099               }
1100           
1101               Array<DInstance> instances;
1102               MI_Result result;
1103           
1104               if (!client.ReferenceInstances(
1105                   nameSpace, 
1106                   instanceName, 
1107                   opts.assocClass,
1108                   opts.role,
1109                   opts.timeOut, 
1110                   instances, 
1111                   result))
1112               {
1113                   err("communication failed");
1114 mike  1.1         return 1;
1115               }
1116           
1117               if (!opts.quiet)
1118               {
1119                   for (Uint32 i = 0; i < instances.GetSize(); i++)
1120                       PrintInstance(instances[i], opts.nulls);
1121               }
1122           
1123               if (result != MI_RESULT_OK)
1124               {
1125                   if (!opts.suppressResults)
1126                       err("result: " STRF, Result_ToString(result));
1127                   return 2;
1128               }
1129           
1130               return 0;
1131           }
1132           
1133           static int Invoke(Client& client, int argc, const char* argv[])
1134           {
1135 mike  1.1     if (argc < 5)
1136               {
1137                   fprintf(serr, 
1138                       "Usage: %s iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\n", 
1139                       arg0);
1140                   return 1;
1141               }
1142           
1143               const String nameSpace = MakeString(argv[2]);
1144           
1145               // Skip over first 3 args:
1146               argc -= 3;
1147               argv += 3;
1148               const char** p = argv;
1149               const char** end = p + argc;
1150           
1151               // Get instanceName parameter:
1152               DInstance instanceName;
1153               {
1154                   if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
1155                   {
1156 mike  1.1             err("invalid instance name specification");
1157                       return 1;
1158                   }
1159               }
1160           
1161               // Get methodName parameter:
1162               if (p == end)
1163               {
1164                   err("expected method name");
1165                   return 1;
1166               }
1167           
1168               String methodName = MakeString(*p);
1169               p++;
1170           
1171               // Get method parameters:
1172               DInstance in(T("Parameters"), DInstance::METHOD);
1173           
1174               if (p != end)
1175               {
1176                   if (!ArgsToInstance(p, end, DInstance::METHOD, true, in))
1177 mike  1.1         {
1178                       err("invalid parameters specification");
1179                       return 1;
1180                   }
1181               }
1182           
1183               // Invoke the method:
1184               DInstance out;
1185               MI_Result result;
1186           
1187               if (!client.Invoke(nameSpace, instanceName, methodName, in, opts.timeOut, 
1188                   out, result))
1189               {
1190                   err("communication failed");
1191                   return 1;
1192               }
1193           
1194               if (!opts.quiet && result == MI_RESULT_OK)
1195                   PrintInstance(out, opts.nulls);
1196           
1197               if (result != MI_RESULT_OK)
1198 mike  1.1     {
1199                   if (!opts.suppressResults)
1200                       err("result: " STRF, Result_ToString(result));
1201                   return 2;
1202               }
1203           
1204               return 0;
1205           }
1206           
1207           class CliHandler : public Handler
1208           {
1209           public:
1210           
1211               /*virtual void HandleConnect();
1212           
1213           
1214               virtual void HandleNoOp(Uint64 msgID);*/
1215               virtual void HandleConnectFailed()
1216               {
1217                   if (!opts.suppressResults)
1218                       err("connect failed...");
1219 mike  1.1         s_result = MI_RESULT_FAILED;
1220                   s_done = true;
1221               }
1222           
1223               virtual void HandleDisconnect()
1224               {
1225                   if (!opts.suppressResults)
1226                       err("disconnected...");
1227                   s_result = MI_RESULT_FAILED;
1228                   s_done = true;
1229               }
1230           
1231               virtual void HandleInstance(Uint64 msgID, const DInstance& instance)
1232               {
1233                   MI_UNUSED(msgID);
1234           
1235                   if (!opts.quiet)
1236                   {
1237                       PrintInstance(instance, opts.nulls);
1238                   }
1239               }
1240 mike  1.1 
1241               virtual void HandleResult(Uint64 msgID, MI_Result result)
1242               {
1243                   MI_UNUSED(msgID);
1244           
1245                   if (result != MI_RESULT_OK)
1246                   {
1247                       if (!opts.suppressResults)
1248                           err("result: " STRF, Result_ToString(result));
1249                   }
1250                   s_result = result;
1251                   s_done = true;
1252               }
1253           };
1254           
1255           int climain(int argc, const char* argv[])
1256           {
1257               arg0 = argv[0];
1258               const Uint64 CONNECT_TIMEOUT_USEC = 10 * 1000 * 1000;
1259               int r = 0;
1260               Client client( new CliHandler );
1261 mike  1.1 
1262               // Setup default stderr and stdout streams:
1263               serr = stderr;
1264               sout = stdout;
1265           
1266               // Initialize options:
1267               opts.Clear();
1268           
1269               // Get the options:
1270               GetCommandLineDestDirOption(&argc, argv);
1271           
1272               // Get configuration file options:
1273               if (GetConfigFileOptions() != 0)
1274               {
1275                   r = 1;
1276                   goto done;
1277               }
1278           
1279               // Get the options:
1280               if (GetCommandLineOptions(argc, argv, opts) != 0)
1281               {
1282 mike  1.1         r = 1;
1283                   goto done;
1284               }
1285           
1286               // There must be at least 1 argument left:
1287               if (argc < 2)
1288               {
1289                   fprintf(sout, "%s", USAGE);
1290                   r = 1;
1291                   goto done;
1292               }
1293           
1294               // Connect to server:
1295           
1296               if (strcmp(argv[1], "enc") != 0)
1297               {
1298           #if defined(CONFIG_OS_WINDOWS)
1299                   if (!client.Connect(T("7777"), opts.user, opts.password, CONNECT_TIMEOUT_USEC))
1300           #else
1301                   if (!client.Connect(GetPath(ID_SOCKETFILE), opts.user, opts.password, CONNECT_TIMEOUT_USEC))
1302           #endif
1303 mike  1.1         {
1304           #if defined(CONFIG_OS_WINDOWS)
1305                       err("failed to connect on port 7777");
1306           #else
1307                       err("failed to connect to %s", GetPath(ID_SOCKETFILE));
1308           #endif
1309                       r = 1;
1310                       goto done;
1311                   }
1312               }
1313           
1314               if (strcmp(argv[1], "noop") == 0)
1315               {
1316                   for (int i = 0; i < opts.repeat; i++)
1317                   {
1318                       r = NoOp(client, argc, argv);
1319                       if (r != 0)
1320                           goto done;
1321                   }
1322               }
1323               else if (strcmp(argv[1], "enc") == 0)
1324 mike  1.1     {
1325                   r = Encode(argc, argv);
1326                   goto done;
1327               }
1328               else if (strcmp(argv[1], "ei") == 0)
1329               {
1330                   for (int i = 0; i < opts.repeat; i++)
1331                   {
1332                       r = EnumerateInstances(client, argc, argv);
1333                       if (r != 0)
1334                           goto done;
1335                   }
1336               }
1337               else if (strcmp(argv[1], "id") == 0)
1338               {
1339           	if (argc != 2)
1340           	{
1341           	    fprintf(serr, "Usage: %s id\n\n", arg0);
1342           	    r = 1;
1343                       goto done;
1344           	}
1345 mike  1.1 
1346           	const char* args[5];
1347           	args[0]= argv[0];
1348           	args[1]= (char*)"ei";
1349           	args[2]= (char*)"root/omi";
1350           	args[3]= (char*)"OMI_Identify";
1351           	args[4]= NULL;
1352           
1353                   for (int i = 0; i < opts.repeat; i++)
1354                   {
1355                       r = EnumerateInstances(client, 4, args);
1356                       if (r != 0)
1357                           goto done;
1358                   }
1359               }
1360               else if (strcmp(argv[1], "gi") == 0)
1361               {
1362                   for (int i = 0; i < opts.repeat; i++)
1363                   {
1364                       r = GetInstance(client, argc, argv);
1365                       if (r != 0)
1366 mike  1.1                 goto done;
1367                   }
1368               }
1369               else if (strcmp(argv[1], "ci") == 0)
1370               {
1371                   for (int i = 0; i < opts.repeat; i++)
1372                   {
1373                       r = CreateInstance(client, argc, argv);
1374                       if (r != 0)
1375                           goto done;
1376                   }
1377               }
1378               else if (strcmp(argv[1], "mi") == 0)
1379               {
1380                   for (int i = 0; i < opts.repeat; i++)
1381                   {
1382                       r = ModifyInstance(client, argc, argv);
1383                       if (r != 0)
1384                           goto done;
1385                   }
1386               }
1387 mike  1.1     else if (strcmp(argv[1], "di") == 0)
1388               {
1389                   for (int i = 0; i < opts.repeat; i++)
1390                   {
1391                       r = DeleteInstance(client, argc, argv);
1392                       if (r != 0)
1393                           goto done;
1394                   }
1395               }
1396               else if (strcmp(argv[1], "iv") == 0)
1397               {
1398                   for (int i = 0; i < opts.repeat; i++)
1399                   {
1400                       r = Invoke(client, argc, argv);
1401                       if (r != 0)
1402                           goto done;
1403                   }
1404               }
1405               else if (strcmp(argv[1], "a") == 0)
1406               {
1407                   for (int i = 0; i < opts.repeat; i++)
1408 mike  1.1         {
1409                       r = Associators(client, argc, argv);
1410                       if (r != 0)
1411                           goto done;
1412                   }
1413               }
1414               else if (strcmp(argv[1], "r") == 0)
1415               {
1416                   for (int i = 0; i < opts.repeat; i++)
1417                   {
1418                       r = References(client, argc, argv);
1419                       if (r != 0)
1420                           goto done;
1421                   }
1422               }
1423               else if (strcmp(argv[1], "wql") == 0)
1424               {
1425                   for (int i = 0; i < opts.repeat; i++)
1426                   {
1427                       r = Query(client, argc, argv);
1428                       if (r != 0)
1429 mike  1.1                 goto done;
1430                   }
1431               }
1432               else
1433               {
1434                   err("unknown command: %s", argv[1]);
1435                   r = 1;
1436                   goto done;
1437               }
1438           
1439           done:
1440           
1441               if (sout != stdout)
1442                   fclose(sout);
1443           
1444               if (serr != stdout)
1445                   fclose(serr);
1446           
1447               return r;
1448           }

ViewCVS 0.9.2