File: [OMI] / omi / cli / Attic / cli.cpp
(download)
Revision: 1.1,
Wed May 30 21:47:49 2012 UTC (12 years, 1 month ago) by mike
Branch: MAIN
Initial revision
|
/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
**
** Licensed under the Apache License, Version 2.0 (the "License"); you may not
** use this file except in compliance with the License. You may obtain a copy
** of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABLITY OR NON-INFRINGEMENT.
**
** See the Apache 2 License for the specific language governing permissions
** and limitations under the License.
**
**==============================================================================
*/
#include <climits>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <omiclient/client.h>
#include <base/args.h>
#include <base/result.h>
#include <wql/wql.h>
#include <base/strings.h>
#include <base/paths.h>
#include <base/conf.h>
#include <base/env.h>
#include <base/getopt.h>
#include <base/io.h>
#include <base/time.h>
#define T MI_T
#if (MI_CHAR_TYPE == 1)
#define STRF "%s"
#else
#define STRF "%S"
#endif
using namespace mi;
const char* arg0;
struct Options
{
bool help;
bool quiet;
bool suppressResults;
bool trace;
bool shallow;
int repeat;
String assocClass;
String resultClass;
String role;
String resultRole;
String user;
String password;
Uint64 timeOut;
unsigned int httpport;
unsigned int httpsport;
bool nulls;
String querylang;
String queryexpr;
Options()
{
Clear();
}
void Clear()
{
help = false;
quiet = false;
suppressResults = false;
trace = false;
shallow = false;
repeat = 1;
assocClass.Clear();
resultClass.Clear();
role.Clear();
resultRole.Clear();
user.Clear();
password.Clear();
timeOut = 90 * 1000 * 1000;
httpport = CONFIG_HTTPPORT;
httpsport = CONFIG_HTTPSPORT;
nulls = false;
querylang.Clear();
queryexpr.Clear();
}
};
static Options opts;
static FILE* sout = stdout;
static FILE* serr = stderr;
PRINTF_FORMAT(1, 2)
static void err(const char* fmt, ...)
{
fprintf(serr, "%s: ", arg0);
va_list ap;
va_start(ap, fmt);
vfprintf(serr, fmt, ap);
va_end(ap);
fputc('\n', serr);
}
static String MakeString(const char* str)
{
String s;
while (*str)
s += MI_Char(*str++);
return s;
}
static std::string ZToStr(const MI_Char* str)
{
std::string r;
while (*str)
r += char(*str++);
return r;
}
static int FindConfigFile(char path[MAX_PATH_SIZE])
{
/* Look in current directory */
{
Strlcpy(path, "./.omiclirc", MAX_PATH_SIZE);
if (access(path, R_OK) == 0)
return 0;
}
/* Look in HOME directory */
char* home = Dupenv("HOME");
if (home)
{
Strlcpy(path, home, MAX_PATH_SIZE);
Strlcat(path, "/.omiclirc", MAX_PATH_SIZE);
if (access(path, R_OK) == 0)
{
free(home);
return 0;
}
free(home);
}
/* Look in system config directory */
{
Strlcpy(path, GetPath(ID_SYSCONFDIR), MAX_PATH_SIZE);
Strlcat(path, "/omicli.conf", MAX_PATH_SIZE);
if (access(path, R_OK) == 0)
return 0;
}
/* Not found */
return -1;
}
static int GetConfigFileOptions()
{
char path[MAX_PATH_SIZE];
Conf* conf;
/* Form the configuration file path (silently ignore if not found) */
if (FindConfigFile(path) != 0)
return 0;
/* Open the configuration file */
conf = Conf_Open(path);
if (!conf)
{
err("failed to open configuration file: %s", path);
return 1;
}
/* For each key=value pair in configuration file */
for (;;)
{
const char* key;
const char* value;
int r = Conf_Read(conf, &key, &value);
if (r == -1)
{
err("%s: %s\n", path, Conf_Error(conf));
return 1;
}
if (r == 1)
break;
if (strcmp(key, "httpport") == 0)
{
char* end;
unsigned long x = Strtoul(value, &end, 10);
if (*end != '\0' || x > USHRT_MAX)
{
err("%s(%u): invalid value for '%s': %s", path,
Conf_Line(conf), key, value);
return 1;
}
opts.httpport = (unsigned short)x;
}
else if (strcmp(key, "httpsport") == 0)
{
char* end;
unsigned long x = Strtoul(value, &end, 10);
if (*end != '\0' || x > USHRT_MAX)
{
err("%s(%u): invalid value for '%s': %s", path,
Conf_Line(conf), key, value);
return 1;
}
opts.httpsport = (unsigned short)x;
}
else if (strcmp(key, "trace") == 0)
{
if (Strcasecmp(value, "true") == 0)
{
opts.trace = MI_TRUE;
}
else if (Strcasecmp(value, "false") == 0)
{
opts.trace = MI_FALSE;
}
else
{
err("%s(%u): invalid value for '%s': %s", path,
Conf_Line(conf), key, value);
return 1;
}
}
else if (IsNickname(key))
{
if (SetPathFromNickname(key, value) != 0)
{
err("SetPathFromNickname() failed");
return 1;
}
}
else
{
err("%s(%u): unknown key: %s", path, Conf_Line(conf), key);
return 1;
}
}
/* Close configuration file */
Conf_Close(conf);
return 0;
}
static void GetCommandLineDestDirOption(
int* argc_,
const char* argv[])
{
int argc = *argc_;
int i;
const char* destdir = NULL;
for (i = 1; i < argc; )
{
if (strcmp(argv[i], "--destdir") == 0)
{
if (i + 1 == argc)
err("missing argument for --destdir option");
destdir = argv[i+1];
memmove((char*)&argv[i], (char*)&argv[i+2],
sizeof(char*) * (argc-i-1));
argc -= 2;
}
else if (strncmp(argv[i], "--destdir=", 10) == 0)
{
destdir = argv[i] + 10;
memmove((char*)&argv[i], (char*)&argv[i+1],
sizeof(char*) * (argc-i));
argc -= 1;
}
else
i++;
}
if (destdir)
{
if (SetPath(ID_DESTDIR, destdir) != 0)
err("failed to set destdir");
}
*argc_ = argc;
}
static int GetCommandLineOptions(
int& argc,
const char* argv[],
Options& options)
{
GetOptState state = GETOPTSTATE_INITIALIZER;
const char* supportedOptions[] =
{
"-h",
"-q",
"-t",
"-s",
"-shallow",
"-n",
"-R:",
"-ac:",
"-rc:",
"-r:",
"-rr:",
"-rc:",
"-u:",
"-p:",
"--prefix:",
"--libdir:",
"--bindir:",
"--localstatedir:",
"--sysconfdir:",
"--providerdir:",
"--certsdir:",
"--rundir:",
"--logdir:",
"--pidfile:",
"--logfile:",
"--registerdir:",
"--socketfile:",
"--pemfile:",
"--keyfile:",
"--agentprogram:",
"--serverprogram:",
"--stdout:",
"--stderr:",
"--querylang:",
"--queryexpr:",
NULL,
};
for (;;)
{
int r = GetOpt(&argc, argv, supportedOptions, &state);
if (r == 1)
break;
if (r == -1)
{
fprintf(serr, "error: %s\n", state.err);
fprintf(serr, "Try -h for help\n");
return 1;
}
if (strcmp(state.opt, "-h") == 0)
{
options.help = true;
}
else if (strcmp(state.opt, "-q") == 0)
{
options.quiet = true;
}
else if (strcmp(state.opt, "-t") == 0)
{
options.trace = true;
}
else if (strcmp(state.opt, "-s") == 0)
{
options.suppressResults = true;
}
else if (strcmp(state.opt, "-shallow") == 0)
{
options.shallow = true;
}
else if (strcmp(state.opt, "-n") == 0)
{
options.nulls = true;
}
else if (strcmp(state.opt, "-R") == 0)
{
options.repeat = atoi(state.arg);
if (options.repeat <= 0)
{
err("bad value for -R: %s", state.arg);
return 1;
}
}
else if (strcmp(state.opt, "-ac") == 0)
{
options.assocClass = MakeString(state.arg);
}
else if (strcmp(state.opt, "-rc") == 0)
{
options.resultClass = MakeString(state.arg);
}
else if (strcmp(state.opt, "-r") == 0)
{
options.role = MakeString(state.arg);
}
else if (strcmp(state.opt, "-rr") == 0)
{
options.resultRole = MakeString(state.arg);
}
else if (strcmp(state.opt, "-u") == 0)
{
options.user = MakeString(state.arg);
}
else if (strcmp(state.opt, "-p") == 0)
{
options.password = MakeString(state.arg);
}
else if (strcmp(state.opt, "--stdout") == 0)
{
FILE* os = Fopen(state.arg, "wb");
if (!os)
err("failed to open: %s", state.arg);
sout = os;
}
else if (strcmp(state.opt, "--stderr") == 0)
{
FILE* os = Fopen(state.arg, "wb");
if (!os)
err("failed to open: %s", state.arg);
serr = os;
}
else if (strcmp(state.opt, "--querylang") == 0)
{
options.querylang = MakeString(state.arg);
}
else if (strcmp(state.opt, "--queryexpr") == 0)
{
options.queryexpr = MakeString(state.arg);
}
else if (strncmp(state.opt, "--", 2) == 0 && IsNickname(state.opt+2))
{
if (SetPathFromNickname(state.opt+2, state.arg) != 0)
err("SetPathFromNickname() failed");
}
}
return 0;
}
const char USAGE[] = "\
Usage: %s [OPTIONS] COMMAND ...\n\
\n\
This tool sends requests to the CIM server.\n\
\n\
OPTIONS:\n\
-h Print this help message.\n\
-q Operate quietly.\n\
-t Enable diagnostic tracing.\n\
-R N Repeat command N times.\n\
-shallow Use shallow inheritance (see 'ei' command).\n\
-ac CLASSNAME Association class (see 'a' and 'r' commands).\n\
-rc CLASSNAME Result class (see 'a' command).\n\
-r ROLE Role (see 'a' and 'r' commands).\n\
-rr ROLE Result role (see 'a' command).\n\
-n Show null properties.\n\
-u USERNAME Username.\n\
-p PASSWORD User's password.\n\
-id Send identify request.\n\
--socketfile PATH Talk to the server server whose socket file resides\n\
at the location given by the path argument.\n\
--httpport Connect on this port instead of default.\n\
--httpsport Connect on this secure port instead of default.\n\
--querylang Query language (for 'ei' command).\n\
--queryexpr Query expression (for 'ei' command).\n\
\n\
COMMANDS:\n\
noop\n\
Perform a no-op operation.\n\
gi NAMESPACE INSTANCENAME\n\
Peform a CIM [g]et [i]nstance operation.\n\
ci NAMESPACE NEWINSTANCE\n\
Peform a CIM [c]create [i]nstance operation.\n\
mi NAMESPACE MODIFIEDINSTANCE\n\
Peform a CIM [m]odify [i]nstance operation.\n\
di NAMESPACE INSTANCENAME\n\
Peform a CIM [d]elete [i]nstance operation.\n\
ei [-shallow] NAMESPACE CLASSNAME\n\
Peform a CIM [e]numerate [i]nstances operation.\n\
iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\
Peform a CIM extrinisic method [i]nvocation operation.\n\
a [-ac -rc -r -rr ] NAMESPACE INSTANCENAME\n\
Perform a CIM [a]ssociator instances operation.\n\
r [-ac -r] NAMESPACE INSTANCENAME (references)\n\
Perform a CIM [r]eference instances operation.\n\
enc INSTANCE\n\
Attempt to encode and print the given instance representation.\n\
wql NAMESPACE WQLQUERY\n\
Peform a WQL query operation.\n\
\n";
// ATTN: support arrays.
static bool ArgsToInstance(
const char**& p,
const char** end,
DInstance::MetaType metaType,
bool key,
DInstance& instanceOut)
{
if (p == end)
return false;
// Consume opening brace:
if (strcmp(*p++, "{") != 0)
return false;
if (p == end)
return false;
// Call the 'empty' constructor so that we can use placement operator.
DInstance instance;
if (metaType == DInstance::METHOD)
{
instance = DInstance(T("Parameters"), DInstance::METHOD);
}
else
{
instance = DInstance(MakeString(*p++), DInstance::CLASS);
if (p == end)
return false;
}
// Consume name/value pairs:
for (;;)
{
if (strcmp(*p, "}") == 0)
{
p++;
break;
}
// Get name:
String name = MakeString(*p++);
if (p == end)
return false;
// Get value:
if (strcmp(*p, "{") == 0)
{
int nesting = 1;
const char** q = p;
q++;
// Find closing brace:
while (*q)
{
if (strcmp(*q, "{") == 0)
nesting++;
else if (strcmp(*q, "}") == 0)
nesting--;
q++;
if (nesting == 0)
break;
}
// Handle missing closing brace:
if (q == end)
return false;
// Recursively call to obtain reference or embedded instance.
DInstance tmpInstance;
if (!ArgsToInstance(p, q, DInstance::CLASS, key, tmpInstance))
{
return false;
}
if (!instance.AddInstance(name, tmpInstance, false, key))
return false;
}
else if (strcmp(*p, "[") == 0)
{
Array<String> array;
p++;
// Find closing brace:
while (*p && strcmp(*p, "]") != 0)
{
array.PushBack(MakeString(*p++));
}
// Handle missing closing brace:
if (p == end)
return false;
if (!instance.AddStringA(name, array, false, key))
return false;
p++;
}
else
{
// Get value:
String value = MakeString(*p++);
// Add property:
if (!instance.AddString(name, value, false, key))
return false;
if (p == end)
break;
}
}
instanceOut = instance;
return true;
}
static int NoOp(Client& client, int argc, const char* argv[])
{
MI_UNUSED(argv);
if (argc != 2)
{
fprintf(serr, "Usage: %s noop\n\n", arg0);
return 1;
}
if (!client.NoOp(opts.timeOut))
{
err("noop request failed");
return 1;
}
if (!opts.quiet)
fprintf(sout, "got noop response\n");
return 0;
}
static void PrintInstance(const DInstance& inst, bool nulls)
{
inst.Print(sout, 0, nulls);
}
static int Encode(int argc, const char* argv[])
{
if (argc < 3)
{
fprintf(serr, "Usage: %s noop CLASSNAME KEYBINDING\n\n", arg0);
return 1;
}
DInstance inst;
argc -= 2;
argv += 2;
if (!ArgsToInstance(argv, argv + argc, DInstance::CLASS, false, inst))
{
err("invalid instance name specification");
return 1;
}
if (!opts.quiet)
{
PrintInstance(inst, opts.nulls);
}
return 0;
}
static MI_Result s_result;
static bool s_done;
static int EnumerateInstances(Client& client, int argc, const char* argv[])
{
if (argc != 4)
{
fprintf(serr, "Usage: %s ei NAMESPACE CLASSNAME\n\n", arg0);
return 1;
}
// Default to WQL query language.
if (opts.querylang.GetSize() && opts.queryexpr.GetSize() == 0)
{
opts.querylang = T("WQL");
}
// Reject if --querylang option present but not --queryexpr option.
if (opts.querylang.GetSize() && opts.queryexpr.GetSize() == 0)
{
err("--querylang options requires --queryexpr option");
return 1;
}
const String nameSpace = MakeString(argv[2]);
const String className = MakeString(argv[3]);
Array<DInstance> instances;
MI_Result result;
Uint64 msgID = 0;
s_result = MI_RESULT_OK;
s_done = false;
if (!client.EnumerateInstancesAsync(nameSpace, className, !opts.shallow,
opts.querylang, opts.queryexpr, msgID))
{
err("communication failed (cannot connect/initiate command)");
return 1;
}
Uint64 endTime, now;
if (Time_Now(&now) != MI_RESULT_OK)
return 3;
endTime = now + opts.timeOut;
for (;!s_done && endTime >= now;)
{
client.Run(1000);
if (Time_Now(&now) != MI_RESULT_OK)
break;
}
if (!s_done)
{
err("communication failed (timeout)");
return 1;
}
result = s_result;
if (result != MI_RESULT_OK)
{
return 2;
}
return 0;
}
static int Query(Client& client, int argc, const char* argv[])
{
// Check arguments
if (argc != 4)
{
fprintf(serr, "Usage: %s wql NAMESPACE QUERY\n\n", arg0);
return 1;
}
// Extract query options.
opts.querylang = T("WQL");
opts.queryexpr = MakeString(argv[3]);
// Always perform shallow query.
opts.shallow = false;
// Pre-compile the query (to get className).
std::string className;
{
WQL* wql = WQL_Parse(opts.queryexpr.Str(), NULL);
if (!wql)
{
fprintf(serr, "%s : invalid query: %s\n\n", arg0, argv[3]);
return 1;
}
className = ZToStr(wql->className);
WQL_Delete(wql);
}
// Invoke enumerate with these arguments.
const char* args[5];
args[0] = argv[0];
args[1] = "ei";
args[2] = argv[2]; /* namespace */
args[3] = className.c_str();
args[4] = NULL;
return EnumerateInstances(client, 4, args);
}
static int GetInstance(Client& client, int argc, const char* argv[])
{
if (argc < 4)
{
fprintf(serr, "Usage: %s gi NAMESPACE INSTANCENAME\n\n", arg0);
return 1;
}
const String nameSpace = MakeString(argv[2]);
DInstance instanceName;
argc -= 3;
argv += 3;
const char** p = argv;
const char** end = p + argc;
if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
{
err("invalid instance name specification");
return 1;
}
if (p != end)
{
err("extraneous arguments after instance name");
return 1;
}
DInstance instance;
MI_Result result;
if (!client.GetInstance(nameSpace, instanceName, opts.timeOut, instance,
result))
{
err("communication failed");
return 1;
}
if (!opts.quiet && result == MI_RESULT_OK)
PrintInstance(instance, opts.nulls);
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF , Result_ToString(result));
return 2;
}
return 0;
}
static int CreateInstance(Client& client, int argc, const char* argv[])
{
if (argc < 4)
{
fprintf(serr, "Usage: %s ci NAMESPACE INSTANCE\n\n", arg0);
return 1;
}
const String nameSpace = MakeString(argv[2]);
DInstance instance;
argc -= 3;
argv += 3;
const char** p = argv;
const char** end = p + argc;
if (!ArgsToInstance(p, end, DInstance::CLASS, true, instance))
{
err("invalid instanceName name specification");
return 1;
}
if (p != end)
{
err("extraneous arguments after instanceName name");
return 1;
}
DInstance instanceName;
MI_Result result;
if (!client.CreateInstance(nameSpace, instance, opts.timeOut, instanceName,
result))
{
err("communication failed");
return 1;
}
if (!opts.quiet && result == MI_RESULT_OK)
PrintInstance(instanceName, true);
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF, Result_ToString(result));
return 2;
}
return 0;
}
static int ModifyInstance(Client& client, int argc, const char* argv[])
{
if (argc < 4)
{
fprintf(serr, "Usage: %s mi NAMESPACE INSTANCE\n\n", arg0);
return 1;
}
const String nameSpace = MakeString(argv[2]);
DInstance instance;
argc -= 3;
argv += 3;
const char** p = argv;
const char** end = p + argc;
if (!ArgsToInstance(p, end, DInstance::CLASS, true, instance))
{
err("invalid instanceName name specification");
return 1;
}
if (p != end)
{
err("extraneous arguments after instanceName name");
return 1;
}
MI_Result result;
if (!client.ModifyInstance(nameSpace, instance, opts.timeOut, result))
{
err("communication failed");
return 1;
}
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF, Result_ToString(result));
return 2;
}
return 0;
}
static int DeleteInstance(Client& client, int argc, const char* argv[])
{
if (argc < 4)
{
fprintf(serr, "Usage: %s gi NAMESPACE INSTANCENAME\n\n", arg0);
return 1;
}
const String nameSpace = MakeString(argv[2]);
DInstance instanceName;
argc -= 3;
argv += 3;
const char** p = argv;
const char** end = p + argc;
if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
{
err("invalid instance name specification");
return 1;
}
if (p != end)
{
err("extraneous arguments after instance name");
return 1;
}
DInstance instance;
MI_Result result;
if (!client.DeleteInstance(nameSpace, instanceName, opts.timeOut, result))
{
err("communication failed");
return 1;
}
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF, Result_ToString(result));
return 2;
}
return 0;
}
static int Associators(Client& client, int argc, const char* argv[])
{
if (argc < 4)
{
fprintf(serr, "Usage: %s a NAMESPACE INSTANCENAME\n\n", arg0);
return 1;
}
const String nameSpace = MakeString(argv[2]);
DInstance instanceName;
argc -= 3;
argv += 3;
const char** p = argv;
const char** end = p + argc;
if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
{
err("invalid instance name specification");
return 1;
}
if (p != end)
{
err("extraneous arguments after instance name");
return 1;
}
Array<DInstance> instances;
MI_Result result;
if (!client.AssociatorInstances(
nameSpace,
instanceName,
opts.assocClass,
opts.resultClass,
opts.role,
opts.resultRole,
opts.timeOut,
instances,
result))
{
err("communication failed");
return 1;
}
if (!opts.quiet)
{
for (Uint32 i = 0; i < instances.GetSize(); i++)
PrintInstance(instances[i], opts.nulls);
}
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF, Result_ToString(result));
return 2;
}
return 0;
}
static int References(Client& client, int argc, const char* argv[])
{
if (argc < 4)
{
fprintf(serr, "Usage: %s a NAMESPACE INSTANCENAME\n\n", arg0);
return 1;
}
const String nameSpace = MakeString(argv[2]);
DInstance instanceName;
argc -= 3;
argv += 3;
const char** p = argv;
const char** end = p + argc;
if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
{
err("invalid instance name specification");
return 1;
}
if (p != end)
{
err("extraneous arguments after instance name");
return 1;
}
Array<DInstance> instances;
MI_Result result;
if (!client.ReferenceInstances(
nameSpace,
instanceName,
opts.assocClass,
opts.role,
opts.timeOut,
instances,
result))
{
err("communication failed");
return 1;
}
if (!opts.quiet)
{
for (Uint32 i = 0; i < instances.GetSize(); i++)
PrintInstance(instances[i], opts.nulls);
}
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF, Result_ToString(result));
return 2;
}
return 0;
}
static int Invoke(Client& client, int argc, const char* argv[])
{
if (argc < 5)
{
fprintf(serr,
"Usage: %s iv NAMESPACE INSTANCENAME METHODNAME PARAMETERS\n\n",
arg0);
return 1;
}
const String nameSpace = MakeString(argv[2]);
// Skip over first 3 args:
argc -= 3;
argv += 3;
const char** p = argv;
const char** end = p + argc;
// Get instanceName parameter:
DInstance instanceName;
{
if (!ArgsToInstance(p, end, DInstance::CLASS, true, instanceName))
{
err("invalid instance name specification");
return 1;
}
}
// Get methodName parameter:
if (p == end)
{
err("expected method name");
return 1;
}
String methodName = MakeString(*p);
p++;
// Get method parameters:
DInstance in(T("Parameters"), DInstance::METHOD);
if (p != end)
{
if (!ArgsToInstance(p, end, DInstance::METHOD, true, in))
{
err("invalid parameters specification");
return 1;
}
}
// Invoke the method:
DInstance out;
MI_Result result;
if (!client.Invoke(nameSpace, instanceName, methodName, in, opts.timeOut,
out, result))
{
err("communication failed");
return 1;
}
if (!opts.quiet && result == MI_RESULT_OK)
PrintInstance(out, opts.nulls);
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF, Result_ToString(result));
return 2;
}
return 0;
}
class CliHandler : public Handler
{
public:
/*virtual void HandleConnect();
virtual void HandleNoOp(Uint64 msgID);*/
virtual void HandleConnectFailed()
{
if (!opts.suppressResults)
err("connect failed...");
s_result = MI_RESULT_FAILED;
s_done = true;
}
virtual void HandleDisconnect()
{
if (!opts.suppressResults)
err("disconnected...");
s_result = MI_RESULT_FAILED;
s_done = true;
}
virtual void HandleInstance(Uint64 msgID, const DInstance& instance)
{
MI_UNUSED(msgID);
if (!opts.quiet)
{
PrintInstance(instance, opts.nulls);
}
}
virtual void HandleResult(Uint64 msgID, MI_Result result)
{
MI_UNUSED(msgID);
if (result != MI_RESULT_OK)
{
if (!opts.suppressResults)
err("result: " STRF, Result_ToString(result));
}
s_result = result;
s_done = true;
}
};
int climain(int argc, const char* argv[])
{
arg0 = argv[0];
const Uint64 CONNECT_TIMEOUT_USEC = 10 * 1000 * 1000;
int r = 0;
Client client( new CliHandler );
// Setup default stderr and stdout streams:
serr = stderr;
sout = stdout;
// Initialize options:
opts.Clear();
// Get the options:
GetCommandLineDestDirOption(&argc, argv);
// Get configuration file options:
if (GetConfigFileOptions() != 0)
{
r = 1;
goto done;
}
// Get the options:
if (GetCommandLineOptions(argc, argv, opts) != 0)
{
r = 1;
goto done;
}
// There must be at least 1 argument left:
if (argc < 2)
{
fprintf(sout, "%s", USAGE);
r = 1;
goto done;
}
// Connect to server:
if (strcmp(argv[1], "enc") != 0)
{
#if defined(CONFIG_OS_WINDOWS)
if (!client.Connect(T("7777"), opts.user, opts.password, CONNECT_TIMEOUT_USEC))
#else
if (!client.Connect(GetPath(ID_SOCKETFILE), opts.user, opts.password, CONNECT_TIMEOUT_USEC))
#endif
{
#if defined(CONFIG_OS_WINDOWS)
err("failed to connect on port 7777");
#else
err("failed to connect to %s", GetPath(ID_SOCKETFILE));
#endif
r = 1;
goto done;
}
}
if (strcmp(argv[1], "noop") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = NoOp(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "enc") == 0)
{
r = Encode(argc, argv);
goto done;
}
else if (strcmp(argv[1], "ei") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = EnumerateInstances(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "id") == 0)
{
if (argc != 2)
{
fprintf(serr, "Usage: %s id\n\n", arg0);
r = 1;
goto done;
}
const char* args[5];
args[0]= argv[0];
args[1]= (char*)"ei";
args[2]= (char*)"root/omi";
args[3]= (char*)"OMI_Identify";
args[4]= NULL;
for (int i = 0; i < opts.repeat; i++)
{
r = EnumerateInstances(client, 4, args);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "gi") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = GetInstance(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "ci") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = CreateInstance(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "mi") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = ModifyInstance(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "di") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = DeleteInstance(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "iv") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = Invoke(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "a") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = Associators(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "r") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = References(client, argc, argv);
if (r != 0)
goto done;
}
}
else if (strcmp(argv[1], "wql") == 0)
{
for (int i = 0; i < opts.repeat; i++)
{
r = Query(client, argc, argv);
if (r != 0)
goto done;
}
}
else
{
err("unknown command: %s", argv[1]);
r = 1;
goto done;
}
done:
if (sout != stdout)
fclose(sout);
if (serr != stdout)
fclose(serr);
return r;
}