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