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 <omiclient/client.h>
30 #include <base/args.h>
31 #include <base/dir.h>
32 #include <base/result.h>
33 #include <base/strings.h>
34 #include <base/paths.h>
35 #include <base/conf.h>
36 #include <base/env.h>
37 #include <base/getopt.h>
38 #include <base/io.h>
39 #include <base/time.h>
40
41 #define T MI_T
42
43 mike 1.1 #if (MI_CHAR_TYPE == 1)
44 #define STRF "%s"
45 #else
46 #define STRF "%S"
47 #endif
48
49 using namespace mi;
50
51 const char* arg0;
52
53 struct Options
54 {
55 bool help;
56 };
57
58 static Options opts;
59
60 PRINTF_FORMAT(1, 2)
61 static void err(const char* fmt, ...)
62 {
63 fprintf(stderr, "%s: ", arg0);
64 mike 1.1
65 va_list ap;
66 va_start(ap, fmt);
67 vfprintf(stderr, fmt, ap);
68 va_end(ap);
69
70 fputc('\n', stderr);
71 exit(1);
72 }
73
74 static void _GetCommandLineOptions(
75 int& argc,
76 const char* argv[],
77 Options& options)
78 {
79 GetOptState state = GETOPTSTATE_INITIALIZER;
80 const char* supportedOptions[] =
81 {
82 "-h",
83 NULL,
84 };
85 mike 1.1
86 for (;;)
87 {
88 int r = GetOpt(&argc, argv, supportedOptions, &state);
89
90 if (r == 1)
91 break;
92
93 if (r == -1)
94 err("%s", state.err);
95
96 if (strcmp(state.opt, "-h") == 0)
97 {
98 options.help = true;
99 }
100 }
101 }
102
103 class ClientHandler : public Handler
104 {
105 public:
106 mike 1.1
107 virtual void HandleConnect()
108 {
109 }
110
111
112 virtual void HandleNoOp(Uint64 msgID)
113 {
114 }
115
116 virtual void HandleConnectFailed()
117 {
118 }
119
120 virtual void HandleDisconnect()
121 {
122 }
123
124 virtual void HandleInstance(Uint64 msgID, const DInstance& instance)
125 {
126 }
127 mike 1.1
128 virtual void HandleResult(Uint64 msgID, MI_Result result)
129 {
130 }
131 };
132
133 static void _CheckIdentifyProvider(Client& cli, const MI_Char* nameSpace)
134 {
135 const Uint64 TIMEOUT = 10 * 1000 * 1000;
136
137 // Enumerate instances os OMI_Identify:
138
139 Array<DInstance> instances;
140 Result result;
141
142 printf("Enumerating identify instances... ");
143 fflush(stdout);
144
145 if (!cli.EnumerateInstances(nameSpace, "OMI_Identify", true,
146 TIMEOUT, instances, String(), String(), result))
147 {
148 mike 1.1 printf("failed\n");
149 err("communication failed (cannot connect/initiate command)");
150 exit(1);
151 }
152
153 printf("ok\n");
154
155 // Check identify instance.
156
157 if (instances.GetSize() != 1)
158 {
159 err("expected one instance of OMI_Identify but found %u",
160 instances.GetSize());
161 }
162
163 printf("Checking for standard namespaces... ");
164 fflush(stdout);
165
166 StringA nameSpaces;
167 bool isNull;
168 bool isKey;
169 mike 1.1
170 if (!instances[0].GetStringA("ConfigNameSpaces", nameSpaces, isNull, isKey))
171 {
172 printf("failed\n");
173 err("missing ConfigNameSpaces property\n");
174 }
175
176 bool foundRootNw = false;
177 bool foundRootCimv2 = false;
178 bool foundInterop = false;
179 bool foundRootCheck = false;
180
181 // Sort the array
182 for (size_t i = 0; i < nameSpaces.GetSize(); i++)
183 {
184 if (nameSpaces[i] == "root#omi")
185 {
186 foundRootNw = true;
187 }
188 else if (nameSpaces[i] == "root#check")
189 {
190 mike 1.1 foundRootCheck = true;
191 }
192 else if (nameSpaces[i] == "root#cimv2")
193 {
194 foundRootCimv2 = true;
195 }
196 else if (nameSpaces[i] == "interop")
197 {
198 foundInterop = true;
199 }
200 }
201
202 if (!foundRootNw)
203 {
204 printf("failed\n");
205 err("missing namespace directory: root#omi");
206 }
207
208 if (!foundRootCheck)
209 {
210 printf("failed\n");
211 mike 1.1 err("missing namespace directory: root#check");
212 }
213
214 if (!foundRootCimv2)
215 {
216 printf("failed\n");
217 err("missing namespace directory: root#cimv2");
218 }
219
220 if (!foundInterop)
221 {
222 printf("failed\n");
223 err("missing namespace directory: interop");
224 }
225
226 printf("ok\n");
227 }
228
229 static void _CheckDirLayout()
230 {
231 printf("Checking directory layout... ");
232 mike 1.1 fflush(stdout);
233
234 if (Chdir(GetPath(ID_PREFIX)) != 0)
235 err("chdir(%s) failed\n", GetPath(ID_PREFIX));
236
237 if (Chdir(GetPath(ID_LIBDIR)) != 0)
238 err("chdir(%s) failed\n", GetPath(ID_LIBDIR));
239
240 if (Chdir(GetPath(ID_BINDIR)) != 0)
241 err("chdir(%s) failed\n", GetPath(ID_BINDIR));
242
243 if (Chdir(GetPath(ID_LOCALSTATEDIR)) != 0)
244 err("chdir(%s) failed\n", GetPath(ID_LOCALSTATEDIR));
245
246 if (Chdir(GetPath(ID_SYSCONFDIR)) != 0)
247 err("chdir(%s) failed\n", GetPath(ID_SYSCONFDIR));
248
249 if (Chdir(GetPath(ID_CERTSDIR)) != 0)
250 err("chdir(%s) failed\n", GetPath(ID_CERTSDIR));
251
252 if (Chdir(GetPath(ID_CERTSDIR)) != 0)
253 mike 1.1 err("chdir(%s) failed\n", GetPath(ID_CERTSDIR));
254
255 if (Chdir(GetPath(ID_DATADIR)) != 0)
256 err("chdir(%s) failed\n", GetPath(ID_DATADIR));
257
258 if (Chdir(GetPath(ID_RUNDIR)) != 0)
259 err("chdir(%s) failed\n", GetPath(ID_RUNDIR));
260
261 if (Chdir(GetPath(ID_LOGDIR)) != 0)
262 err("chdir(%s) failed\n", GetPath(ID_LOGDIR));
263
264 if (Chdir(GetPath(ID_REGISTERDIR)) != 0)
265 err("chdir(%s) failed\n", GetPath(ID_REGISTERDIR));
266
267 if (Chdir(GetPath(ID_INCLUDEDIR)) != 0)
268 err("chdir(%s) failed\n", GetPath(ID_INCLUDEDIR));
269
270 if (Chdir(GetPath(ID_DESTDIR)) != 0)
271 err("chdir(%s) failed\n", GetPath(ID_DESTDIR));
272
273 if (Chdir(GetPath(ID_AUTHDIR)) != 0)
274 mike 1.1 err("chdir(%s) failed\n", GetPath(ID_AUTHDIR));
275
276 printf("ok\n");
277 }
278
279 static void _Check(Client& cli)
280 {
281 // Check in-process identify provider.
282 _CheckIdentifyProvider(cli, MI_T("root/omi"));
283
284 // Check out-of-process identify provider.
285 _CheckIdentifyProvider(cli, MI_T("root/check"));
286
287 // Check directory layout:
288 _CheckDirLayout();
289 }
290
291 static void GetCommandLineDestDirOption(
292 int* argc_,
293 const char* argv[])
294 {
295 mike 1.1 int argc = *argc_;
296 int i;
297 const char* destdir = NULL;
298
299 for (i = 1; i < argc; )
300 {
301 if (strcmp(argv[i], "--destdir") == 0)
302 {
303 if (i + 1 == argc)
304 err("missing argument for --destdir option");
305
306 destdir = argv[i+1];
307 memmove((char*)&argv[i], (char*)&argv[i+2],
308 sizeof(char*) * (argc-i-1));
309 argc -= 2;
310 }
311 else if (strncmp(argv[i], "--destdir=", 10) == 0)
312 {
313 destdir = argv[i] + 10;
314 memmove((char*)&argv[i], (char*)&argv[i+1],
315 sizeof(char*) * (argc-i));
316 mike 1.1
317 argc -= 1;
318 }
319 else
320 i++;
321 }
322
323 if (destdir)
324 {
325 if (SetPath(ID_DESTDIR, destdir) != 0)
326 err("failed to set destdir");
327 }
328
329 *argc_ = argc;
330 }
331
332 const char USAGE[] = "\
333 Usage: %s [OPTIONS] COMMAND ...\n\
334 \n\
335 This tool checks the sanity of an OMI installation.\n\
336 \n\
337 mike 1.1 OPTIONS:\n\
338 -h Print this help message.\n\
339 \n\
340 \n";
341
342 int main(int argc, const char* argv[])
343 {
344 arg0 = argv[0];
345 const Uint64 CONNECT_TIMEOUT_USEC = 10 * 1000 * 1000;
346 Client client(new ClientHandler);
347
348 // Get destdir option.
349 GetCommandLineDestDirOption(&argc, argv);
350
351 // Get options:
352 _GetCommandLineOptions(argc, argv, opts);
353
354 // There must be at least 1 argument left:
355 if (argc != 1 || opts.help)
356 {
357 fprintf(stdout, "%s", USAGE);
358 mike 1.1 exit(1);
359 }
360
361 // Connect to server:
362 {
363 printf("Connecting locally to server... ");
364 fflush(stdout);
365
366 if (!client.Connect(GetPath(ID_SOCKETFILE), String(), String(),
367 CONNECT_TIMEOUT_USEC))
368 {
369 printf("failed\n");
370 err("failed to connect to %s", GetPath(ID_SOCKETFILE));
371 }
372
373 printf("ok\n");
374 }
375
376 // Perform check!
377 _Check(client);
378 printf("\n");
379 mike 1.1
380 return 0;
381 }
|