1 | /* |
---|
2 | * Copyright (c) 1992-1998 Michael A. Cooper. |
---|
3 | * This software may be freely used and distributed provided it is not |
---|
4 | * sold for profit or used in part or in whole for commercial gain |
---|
5 | * without prior written agreement, and the author is credited |
---|
6 | * appropriately. |
---|
7 | */ |
---|
8 | |
---|
9 | #ifndef lint |
---|
10 | static char *RCSid = "$Revision: 1.1.1.3 $"; |
---|
11 | #endif |
---|
12 | |
---|
13 | /* |
---|
14 | * Display System Information |
---|
15 | */ |
---|
16 | |
---|
17 | #include <stdio.h> |
---|
18 | #include <sys/types.h> |
---|
19 | |
---|
20 | #include "defs.h" |
---|
21 | |
---|
22 | /* |
---|
23 | * Local declarations |
---|
24 | */ |
---|
25 | int Danger = FALSE; |
---|
26 | int DoPrintUnknown = FALSE; |
---|
27 | int DoPrintVersion = FALSE; |
---|
28 | int DoPrintLicense = FALSE; |
---|
29 | int MsgLevel = L_GENERAL; |
---|
30 | char *FormatStr = NULL; |
---|
31 | FormatType_t FormatType = FT_PRETTY; |
---|
32 | char *MsgClassStr = NULL; |
---|
33 | int MsgClassFlags = SIM_DEFAULT; |
---|
34 | int UseProm = 0; |
---|
35 | int DebugFlag = 0; |
---|
36 | int OffSetAmt = 4; |
---|
37 | int UseConfig = 1; |
---|
38 | char *ShowStr = NULL; |
---|
39 | char *ClassNames = NULL; |
---|
40 | char *TypeNames = NULL; |
---|
41 | char *MsgLevelStr = NULL; |
---|
42 | char *ListStr = NULL; |
---|
43 | char *UnSupported = NULL; |
---|
44 | char *ConfFile = NULL; |
---|
45 | char *ConfDir = CONFIG_DIR; |
---|
46 | char *MCLprogramName = "sysinfo"; |
---|
47 | char **Environ = NULL; |
---|
48 | extern char *RepSep; |
---|
49 | int DoNothing = TRUE; |
---|
50 | |
---|
51 | #if defined(OPTION_COMPAT) |
---|
52 | int Terse = FALSE; |
---|
53 | #endif /* OPTION_COMPAT */ |
---|
54 | |
---|
55 | /* |
---|
56 | * Command line options table. |
---|
57 | */ |
---|
58 | OptionDescRec Opts[] = { |
---|
59 | {"-cffile", SepArg, OptStr, (OptPtr_t) &ConfFile, NULL, |
---|
60 | "file","Sysinfo config file"}, |
---|
61 | {"-cfdir", SepArg, OptStr, (OptPtr_t) &ConfDir, NULL, |
---|
62 | "directory","Sysinfo config directory"}, |
---|
63 | {"-class", SepArg, OptStr, (OptPtr_t) &ClassNames, NULL, |
---|
64 | "<see \"-list class\">", "Class name"}, |
---|
65 | {"-danger",NoArg, OptBool,(OptPtr_t) &Danger, "1", |
---|
66 | NULL, "Disable runtime platform checks" }, |
---|
67 | {"-license",NoArg, OptBool,(OptPtr_t) &DoPrintLicense, "1", |
---|
68 | NULL, "Print license information" }, |
---|
69 | {"-list", SepArg, OptStr, (OptPtr_t) &ListStr, "-", |
---|
70 | "<what>", "List information about <what>"}, |
---|
71 | {"-format", SepArg, OptStr, (OptPtr_t) &FormatStr, NULL, |
---|
72 | "<see \"-list format\">", "Format Type"}, |
---|
73 | {"-msgclass",SepArg, OptStr, (OptPtr_t) &MsgClassStr, NULL, |
---|
74 | "<see \"-list msgclass\">", "Message Classes to output"}, |
---|
75 | {"-msglevel",SepArg, OptStr, (OptPtr_t) &MsgLevelStr, NULL, |
---|
76 | "<see \"-list msglevel\">", "Message Levels to output"}, |
---|
77 | {"-offset", SepArg, OptInt, (OptPtr_t) &OffSetAmt, NULL, |
---|
78 | "<amount>", "Number of spaces to offset device info"}, |
---|
79 | {"-repsep", SepArg, OptStr, (OptPtr_t) &RepSep, NULL, |
---|
80 | "<string>","Report field seperator"}, |
---|
81 | {"-show", SepArg, OptStr, (OptPtr_t) &ShowStr, NULL, |
---|
82 | "<see \"-list show\">", "Show names"}, |
---|
83 | {"-type", SepArg, OptStr, (OptPtr_t) &TypeNames, NULL, |
---|
84 | "<see \"-list type\">", "Type name"}, |
---|
85 | {"+unknown",NoArg, OptBool,(OptPtr_t) &DoPrintUnknown, "1", |
---|
86 | NULL, "Print unknown devices"}, |
---|
87 | {"-unknown",NoArg, OptBool,(OptPtr_t) &DoPrintUnknown, "0", |
---|
88 | NULL, "Don't print unknown devices"}, |
---|
89 | {"+useconfig",NoArg, OptBool,(OptPtr_t) &UseConfig, "1", |
---|
90 | NULL, "Use config (-cffile,-cfdir) files"}, |
---|
91 | {"-useconfig",NoArg, OptBool,(OptPtr_t) &UseConfig, "0", |
---|
92 | NULL, "Don't use config (-cffile,-cfdir) files"}, |
---|
93 | {"+useprom",NoArg, OptBool,(OptPtr_t) &UseProm, "1", |
---|
94 | NULL, "Use PROM values"}, |
---|
95 | {"-useprom",NoArg, OptBool,(OptPtr_t) &UseProm, "0", |
---|
96 | NULL, "Don't use PROM values"}, |
---|
97 | {"-version",NoArg, OptBool,(OptPtr_t) &DoPrintVersion, "1", |
---|
98 | NULL, "Print version of this program" }, |
---|
99 | /* |
---|
100 | * These options are obsolete, but are present for backwards compatibility |
---|
101 | * Some of the options still do things and some don't (see DoNothing). |
---|
102 | */ |
---|
103 | {"-debug",ArgHidden|SepArg, OptInt, (OptPtr_t) &DebugFlag, "1", |
---|
104 | NULL, "Enable debugging" }, |
---|
105 | {"-level",ArgHidden|SepArg, OptStr, (OptPtr_t) &MsgLevelStr, NULL, |
---|
106 | "<see \"-list msglevel\">", "Message Levels to output"}, |
---|
107 | {"+all", ArgHidden|NoArg, OptBool,(OptPtr_t) &DoNothing, "1", |
---|
108 | NULL, "Print all information"}, |
---|
109 | {"-all", ArgHidden|NoArg, OptBool,(OptPtr_t) &DoNothing, "0", |
---|
110 | NULL, "Don't print all information"}, |
---|
111 | #if defined(OPTION_COMPAT) |
---|
112 | /* |
---|
113 | * Old options from version 2.x |
---|
114 | * that can be enabled for backwards compatibility |
---|
115 | */ |
---|
116 | {"+terse", NoArg,OptBool,(OptPtr_t) &Terse,"1",NULL,"Print info in terse format"}, |
---|
117 | {"-terse", NoArg,OptBool,(OptPtr_t) &Terse,"0",NULL,"Don't print info in terse format"}, |
---|
118 | #endif /* OPTION_COMPAT */ |
---|
119 | }; |
---|
120 | |
---|
121 | /* |
---|
122 | * Values and names of levels |
---|
123 | */ |
---|
124 | ListInfo_t MsgLevelNames[] = { |
---|
125 | { L_TERSE, "terse", "Values only (for parsing)" }, |
---|
126 | { L_BRIEF, "brief", "Brief, but human readable" }, |
---|
127 | { L_GENERAL, "general", "General info" }, |
---|
128 | { L_DESC, "descriptions", "Show description info" }, |
---|
129 | { L_CONFIG, "config", "Show configuration info" }, |
---|
130 | { L_ALL, "all", "All information available" }, |
---|
131 | { 0 }, |
---|
132 | }; |
---|
133 | |
---|
134 | /* |
---|
135 | * MsgClass options |
---|
136 | */ |
---|
137 | ListInfo_t MsgClassNames[] = { |
---|
138 | { SIM_INFO, "info", "Normal information" }, |
---|
139 | { SIM_WARN, "warn", "Warnings" }, |
---|
140 | { SIM_GERR, "gerror", "General errors" }, |
---|
141 | { SIM_CERR, "cerror", "Critical errors" }, |
---|
142 | { SIM_UNKN, "unknown", "Messages about unknown values" }, |
---|
143 | { SIM_DBG, "debug", "Debugging information" }, |
---|
144 | { SIM_ALL, "all", "All message classes" }, |
---|
145 | { 0 }, |
---|
146 | }; |
---|
147 | |
---|
148 | /* |
---|
149 | * Format options |
---|
150 | */ |
---|
151 | ListInfo_t FormatNames[] = { |
---|
152 | { FT_PRETTY, "pretty", "Format output for humans" }, |
---|
153 | { FT_REPORT, "report", "Format output for programs" }, |
---|
154 | { 0 }, |
---|
155 | }; |
---|
156 | |
---|
157 | /* |
---|
158 | * List options |
---|
159 | */ |
---|
160 | static void ListMsgLevel(); |
---|
161 | static void ListFormat(); |
---|
162 | static void ListMsgClass(); |
---|
163 | static void ListShow(); |
---|
164 | |
---|
165 | ListInfo_t ListInfo[] = { |
---|
166 | { 0, "class", "Values for `-class' option", ClassList }, |
---|
167 | { 0, "format", "Values for `-format' option", ListFormat }, |
---|
168 | { 0, "msgclass", "Values for `-msgclass' option",ListMsgClass }, |
---|
169 | { 0, "msglevel", "Values for `-msglevel' option",ListMsgLevel }, |
---|
170 | { 0, "show", "Values for `-show' option", ClassCallList }, |
---|
171 | { 0, "type", "Values for `-type' option", TypeList }, |
---|
172 | { 0 }, |
---|
173 | }; |
---|
174 | |
---|
175 | /* |
---|
176 | * List possible values for List |
---|
177 | */ |
---|
178 | static void ListInfoDesc(OptStr, List) |
---|
179 | char *OptStr; |
---|
180 | ListInfo_t *List; |
---|
181 | { |
---|
182 | register ListInfo_t *ListPtr; |
---|
183 | |
---|
184 | if (OptStr) |
---|
185 | SImsg(SIM_INFO, |
---|
186 | "\nThe following values may be specified with the `%s' option:\n", |
---|
187 | OptStr); |
---|
188 | |
---|
189 | SImsg(SIM_INFO, "%-20s %s\n", "VALUE", "DESCRIPTION"); |
---|
190 | |
---|
191 | for (ListPtr = List; ListPtr->Name; ++ListPtr) |
---|
192 | SImsg(SIM_INFO, "%-20s %s\n", ListPtr->Name, |
---|
193 | (ListPtr->Desc) ? ListPtr->Desc : ""); |
---|
194 | } |
---|
195 | |
---|
196 | /* |
---|
197 | * List Format values |
---|
198 | */ |
---|
199 | static void ListFormat() |
---|
200 | { |
---|
201 | ListInfoDesc("-format", FormatNames); |
---|
202 | } |
---|
203 | |
---|
204 | /* |
---|
205 | * List MsgClass values |
---|
206 | */ |
---|
207 | static void ListMsgClass() |
---|
208 | { |
---|
209 | ListInfoDesc("-msgclass", MsgClassNames); |
---|
210 | } |
---|
211 | |
---|
212 | /* |
---|
213 | * List MsgLevel values |
---|
214 | */ |
---|
215 | static void ListMsgLevel() |
---|
216 | { |
---|
217 | ListInfoDesc("-msglevel", MsgLevelNames); |
---|
218 | } |
---|
219 | |
---|
220 | /* |
---|
221 | * List list values |
---|
222 | */ |
---|
223 | static void ListList() |
---|
224 | { |
---|
225 | ListInfoDesc("-list", ListInfo); |
---|
226 | } |
---|
227 | |
---|
228 | /* |
---|
229 | * List information about each word found in Str. |
---|
230 | */ |
---|
231 | static void List(Str) |
---|
232 | char *Str; |
---|
233 | { |
---|
234 | register ListInfo_t *ListPtr; |
---|
235 | char *Word; |
---|
236 | int Found; |
---|
237 | |
---|
238 | if (EQ(Str, "-")) { |
---|
239 | ListList(); |
---|
240 | return; |
---|
241 | } |
---|
242 | |
---|
243 | for (Word = strtok(Str, ","); Word; Word = strtok((char *)NULL, ",")) { |
---|
244 | for (ListPtr = ListInfo, Found = FALSE; |
---|
245 | ListPtr->Name && !Found; ++ListPtr) |
---|
246 | if (EQ(Word, ListPtr->Name)) { |
---|
247 | Found = TRUE; |
---|
248 | (*ListPtr->List)(); |
---|
249 | } |
---|
250 | |
---|
251 | if (!Found) { |
---|
252 | SImsg(SIM_CERR, "The word \"%s\" is invalid.", Word); |
---|
253 | ListList(); |
---|
254 | return; |
---|
255 | } |
---|
256 | } |
---|
257 | } |
---|
258 | |
---|
259 | /* |
---|
260 | * Get argument number "arg" from "str". |
---|
261 | */ |
---|
262 | static char *GetArg(Str, ArgNum) |
---|
263 | char *Str; |
---|
264 | int ArgNum; |
---|
265 | { |
---|
266 | register char *p, *start = NULL; |
---|
267 | register int c; |
---|
268 | |
---|
269 | for (c = 1, p = Str; p && *p; ++c) { |
---|
270 | /* set start of word */ |
---|
271 | start = p; |
---|
272 | |
---|
273 | /* skip over word */ |
---|
274 | while (p && *p && *p != ' ' && *p != '\t' && *p != '\n') |
---|
275 | ++p; |
---|
276 | |
---|
277 | /* is this what we want? */ |
---|
278 | if (c == ArgNum) { |
---|
279 | if (p) *p = C_NULL; |
---|
280 | break; |
---|
281 | } |
---|
282 | |
---|
283 | /* skip white space */ |
---|
284 | while (*p == ' ' || *p == '\t') |
---|
285 | ++p; |
---|
286 | } |
---|
287 | |
---|
288 | return(start); |
---|
289 | } |
---|
290 | |
---|
291 | /* |
---|
292 | * Parse and set the level keyword list |
---|
293 | */ |
---|
294 | static int ParseMsgLevel(Str) |
---|
295 | char *Str; |
---|
296 | { |
---|
297 | ListInfo_t *ListPtr; |
---|
298 | char *Word; |
---|
299 | int Found; |
---|
300 | |
---|
301 | /* |
---|
302 | * Check each word in the MsgLevelNames table |
---|
303 | */ |
---|
304 | for (Word = strtok(Str, ","); Word; Word = strtok((char *)NULL, ",")) { |
---|
305 | for (ListPtr = MsgLevelNames, Found = FALSE; |
---|
306 | ListPtr && ListPtr->Name && !Found; ListPtr++) { |
---|
307 | if (strncasecmp(Word, ListPtr->Name, strlen(Word)) == 0) { |
---|
308 | MsgLevel |= ListPtr->IntKey; |
---|
309 | Found = TRUE; |
---|
310 | } |
---|
311 | } |
---|
312 | if (!Found) { |
---|
313 | SImsg(SIM_CERR, "The word \"%s\" is not a valid message level.", |
---|
314 | Word); |
---|
315 | return(-1); |
---|
316 | } |
---|
317 | } |
---|
318 | |
---|
319 | return(0); |
---|
320 | } |
---|
321 | |
---|
322 | /* |
---|
323 | * Parse and set the Message Class Flags |
---|
324 | */ |
---|
325 | static int ParseMsgClass(Str) |
---|
326 | char *Str; |
---|
327 | { |
---|
328 | ListInfo_t *ListPtr; |
---|
329 | char *Word; |
---|
330 | int Found; |
---|
331 | int NewFlags = 0; |
---|
332 | |
---|
333 | /* |
---|
334 | * Check each word in the MsgClassNames table |
---|
335 | */ |
---|
336 | for (Word = strtok(Str, ","); Word; Word = strtok((char *)NULL, ",")) { |
---|
337 | for (ListPtr = MsgClassNames, Found = FALSE; |
---|
338 | ListPtr && ListPtr->Name && !Found; ListPtr++) { |
---|
339 | if (EQN(Word, ListPtr->Name, strlen(Word))) { |
---|
340 | NewFlags |= ListPtr->IntKey; |
---|
341 | Found = TRUE; |
---|
342 | } |
---|
343 | } |
---|
344 | if (!Found) { |
---|
345 | SImsg(SIM_CERR, "The word \"%s\" is not a valid MsgClass flag.", |
---|
346 | Word); |
---|
347 | return(-1); |
---|
348 | } |
---|
349 | } |
---|
350 | |
---|
351 | if (NewFlags) |
---|
352 | MsgClassFlags = NewFlags; |
---|
353 | |
---|
354 | return(0); |
---|
355 | } |
---|
356 | |
---|
357 | /* |
---|
358 | * Parse and set the format type |
---|
359 | */ |
---|
360 | static int ParseFormat(Str) |
---|
361 | char *Str; |
---|
362 | { |
---|
363 | register ListInfo_t *ListPtr; |
---|
364 | char *Word; |
---|
365 | int Found; |
---|
366 | |
---|
367 | /* |
---|
368 | * Check each word in the FormatNames table |
---|
369 | */ |
---|
370 | for (Word = strtok(Str, ","); Word; Word = strtok((char *)NULL, ",")) { |
---|
371 | for (ListPtr = FormatNames, Found = FALSE; ListPtr->Name && !Found; |
---|
372 | ListPtr++) { |
---|
373 | if (strncasecmp(Word, ListPtr->Name, strlen(Word)) == 0) { |
---|
374 | FormatType = ListPtr->IntKey; |
---|
375 | Found = TRUE; |
---|
376 | } |
---|
377 | } |
---|
378 | if (!Found) { |
---|
379 | SImsg(SIM_CERR, "The word \"%s\" is not a valid format type.", |
---|
380 | Word); |
---|
381 | return(-1); |
---|
382 | } |
---|
383 | } |
---|
384 | |
---|
385 | return(0); |
---|
386 | } |
---|
387 | |
---|
388 | /* |
---|
389 | * Check for license. |
---|
390 | * |
---|
391 | * PLEASE DO NOT DISABLE. DISABLING THIS CODE IS A VIOLATION OF |
---|
392 | * THE LICENSE. AND IT'S NOT VERY NICE EITHER. |
---|
393 | */ |
---|
394 | static mcl_t *CheckMCL(Product) |
---|
395 | char *Product; |
---|
396 | { |
---|
397 | static mcl_t Query; |
---|
398 | static char FileBuff[MAXPATHLEN]; |
---|
399 | |
---|
400 | (void) snprintf(FileBuff, sizeof(FileBuff), "%s/license%s", |
---|
401 | ConfDir, MCL_FILE_EXT); |
---|
402 | (void) memset(&Query, 0, sizeof(Query)); |
---|
403 | Query.File = FileBuff; |
---|
404 | Query.Product = Product; |
---|
405 | |
---|
406 | if (MCLcheck(&Query) < 0) { |
---|
407 | if (Query.Status == MCL_STAT_NOTFOUND) |
---|
408 | SImsg(SIM_CERR|SIM_NOLBL, "\ |
---|
409 | You are running a free 60-day DEMO version of %s. Please obtain a\n\ |
---|
410 | permanent license or cease using this program within 60 days. Licenses\n\ |
---|
411 | may be obtained from http://www.MagniComp.com/sysinfo/#getlicense\n", |
---|
412 | Product); |
---|
413 | SImsg(SIM_DBG, "Cannot obtain license: %s", |
---|
414 | (Query.Msg) ? Query.Msg : "UNKNOWN REASON"); |
---|
415 | return((mcl_t *) NULL); |
---|
416 | } |
---|
417 | |
---|
418 | return(&Query); |
---|
419 | } |
---|
420 | |
---|
421 | #if defined(OPTION_COMPAT) |
---|
422 | /* |
---|
423 | * Set option compatibility |
---|
424 | */ |
---|
425 | static void SetOptionCompat() |
---|
426 | { |
---|
427 | /* |
---|
428 | * For backwards compatibility |
---|
429 | */ |
---|
430 | if (Terse) |
---|
431 | MsgLevel |= L_TERSE; |
---|
432 | } |
---|
433 | #endif /* OPTION_COMPAT */ |
---|
434 | |
---|
435 | /* |
---|
436 | * Check to see if we're running with the right Root Access. |
---|
437 | */ |
---|
438 | static void CheckRunTimeAccess() |
---|
439 | { |
---|
440 | #if defined(RA_LEVEL) && RA_LEVEL == RA_ADVISED |
---|
441 | if (geteuid() != 0) { |
---|
442 | SImsg(SIM_WARN, |
---|
443 | "This program should be run as `root' (uid=0) to obtain\n\t\ |
---|
444 | all supported information. Please either make setuid to\n\t\ |
---|
445 | root (chown root sysinfo;chmod u+s sysinfo) or invoke as a\n\t\ |
---|
446 | uid=0 user such as `root'."); |
---|
447 | } |
---|
448 | #endif /* RA_ADVISED */ |
---|
449 | #if defined(RA_LEVEL) && RA_LEVEL == RA_NONE |
---|
450 | /* Do nothing */ |
---|
451 | return; |
---|
452 | #endif /* RA_NONE */ |
---|
453 | } |
---|
454 | |
---|
455 | /* |
---|
456 | * Check to see if we're running on the same platform as we were |
---|
457 | * compiled on. |
---|
458 | */ |
---|
459 | static void CheckRunTimePlatform() |
---|
460 | { |
---|
461 | extern char BuildCPUType[]; |
---|
462 | extern char BuildCPUArch[]; |
---|
463 | extern char BuildOSname[]; |
---|
464 | extern char BuildOSver[]; |
---|
465 | static char What[512]; |
---|
466 | |
---|
467 | /* |
---|
468 | * Skip this check if the user specified the -danger flag |
---|
469 | */ |
---|
470 | if (Danger) |
---|
471 | return; |
---|
472 | |
---|
473 | /* |
---|
474 | * Yes, it is possible for the OS name to be different. |
---|
475 | * i.e. "IRIX" vs. "IRIX64" |
---|
476 | */ |
---|
477 | if (!EQ(GetOSName(), BuildOSname)) |
---|
478 | (void) snprintf(What, sizeof(What), |
---|
479 | "This program was built on `%s' but is being run on `%s'.", |
---|
480 | BuildOSname, GetOSName()); |
---|
481 | else if (!EQ(GetOSVer(), BuildOSver)) |
---|
482 | (void) snprintf(What, sizeof(What), |
---|
483 | "This program was built on `%s %s' \ |
---|
484 | but is being run on `%s %s'.", |
---|
485 | BuildOSname, BuildOSver, GetOSName(), GetOSVer()); |
---|
486 | #if defined(sunos) && OSMVER == 4 |
---|
487 | else if (!EQ(GetKernArch(), BuildCPUArch)) |
---|
488 | (void) snprintf(What, sizeof(What), |
---|
489 | "This program was built on a `%s' kernel arch machine and is being\ |
---|
490 | run on a `%s' machine.", |
---|
491 | BuildCPUArch, GetKernArch()); |
---|
492 | #endif |
---|
493 | |
---|
494 | if (What[0]) { |
---|
495 | SImsg(SIM_CERR, "%s", What); |
---|
496 | SImsg(SIM_CERR, |
---|
497 | "%s may not be able to provide consistant information.", |
---|
498 | ProgramName); |
---|
499 | SImsg(SIM_CERR, |
---|
500 | "If you wish to override and run anyway, use the `-danger'"); |
---|
501 | SImsg(SIM_CERR, "option. This is generally not advised."); |
---|
502 | exit(1); |
---|
503 | } |
---|
504 | } |
---|
505 | |
---|
506 | /* |
---|
507 | * Print version information |
---|
508 | */ |
---|
509 | void PrintVersion() |
---|
510 | { |
---|
511 | extern char BuildDate[]; |
---|
512 | extern char BuildHost[]; |
---|
513 | extern char BuildUser[]; |
---|
514 | extern char BuildOSname[]; |
---|
515 | extern char BuildOSver[]; |
---|
516 | extern char BuildOStype[]; |
---|
517 | extern char BuildAppArch[]; |
---|
518 | extern char BuildCPUArch[]; |
---|
519 | int MsgFlags = SIM_INFO|SIM_DBG|SIM_NONL; |
---|
520 | char *MCLinfo; |
---|
521 | |
---|
522 | if (!VL_TERSE) |
---|
523 | SImsg(MsgFlags, "SysInfo Version "); |
---|
524 | if (PATCHLEVEL) |
---|
525 | SImsg(MsgFlags, "%s.%d", VERSION_STR, PATCHLEVEL); |
---|
526 | else |
---|
527 | SImsg(MsgFlags, "%s", VERSION_STR); |
---|
528 | |
---|
529 | if (!VL_TERSE) { |
---|
530 | SImsg(MsgFlags, " (%s)\n", VERSION_STATUS); |
---|
531 | SImsg(MsgFlags, "Binary Build Information:\n"); |
---|
532 | #define bOFFSET 10 |
---|
533 | SImsg(MsgFlags, "\t%*s: %s\n", bOFFSET, "Build Date", BuildDate); |
---|
534 | SImsg(MsgFlags, "\t%*s: %s on %s\n", |
---|
535 | bOFFSET, "Built By", BuildUser, BuildHost); |
---|
536 | SImsg(MsgFlags, "\t%*s: %s %s\n", |
---|
537 | bOFFSET, "OS", BuildOSname, BuildOSver); |
---|
538 | SImsg(MsgFlags, "\t%*s: %s\n", bOFFSET, "OS Type", BuildOStype); |
---|
539 | SImsg(MsgFlags, "\t%*s: %s\n", bOFFSET, "App Arch", BuildAppArch); |
---|
540 | SImsg(MsgFlags, "\t%*s: %s\n", bOFFSET, "CPU Arch", BuildCPUArch); |
---|
541 | #undef bOFFSET |
---|
542 | SImsg(MsgFlags, GENERAL_MSG); |
---|
543 | SImsg(MsgFlags, COPYRIGHT_MSG); |
---|
544 | } |
---|
545 | |
---|
546 | SImsg(MsgFlags, "\n"); |
---|
547 | } |
---|
548 | |
---|
549 | /* |
---|
550 | * The beginning |
---|
551 | */ |
---|
552 | main(Argc, Argv, Envp) |
---|
553 | int Argc; |
---|
554 | char **Argv; |
---|
555 | char **Envp; |
---|
556 | { |
---|
557 | char *cp; |
---|
558 | mcl_t *MClic; |
---|
559 | |
---|
560 | Environ = Envp; |
---|
561 | |
---|
562 | /* |
---|
563 | * Parse command line arguments. |
---|
564 | */ |
---|
565 | if (ParseOptions(Opts, Num_Opts(Opts), Argc, Argv) < 0) |
---|
566 | exit(1); |
---|
567 | |
---|
568 | /* |
---|
569 | * Cleanup our program name used for error messages. |
---|
570 | */ |
---|
571 | if (cp = strrchr(ProgramName, '/')) |
---|
572 | ProgramName = ++cp; |
---|
573 | |
---|
574 | /* |
---|
575 | * Set Message Class Flags |
---|
576 | */ |
---|
577 | if (MsgClassStr && ParseMsgClass(MsgClassStr)) |
---|
578 | exit(1); |
---|
579 | |
---|
580 | /* |
---|
581 | * For -debug backwards compatibile |
---|
582 | */ |
---|
583 | if (DebugFlag) |
---|
584 | MsgClassFlags |= SIM_DBG|SIM_GERR; |
---|
585 | |
---|
586 | /* |
---|
587 | * If we're setuid(root) and we're not being run by user "root", |
---|
588 | * don't let unpriv'ed users try anything tricky. |
---|
589 | */ |
---|
590 | if (UseConfig && (getuid() != 0 && geteuid() == 0) && |
---|
591 | (ConfFile || !EQ(ConfDir, CONFIG_DIR))) { |
---|
592 | SImsg(SIM_CERR, |
---|
593 | "Only \"root\" may specify \"-cfdir\" when %s is \"setuid root\".", |
---|
594 | ProgramName); |
---|
595 | exit(1); |
---|
596 | } |
---|
597 | |
---|
598 | UnSupported = (Debug) ? "**UNSUPPORTED**" : (char *)NULL; |
---|
599 | |
---|
600 | #if defined(OPTION_COMPAT) |
---|
601 | SetOptionCompat(); |
---|
602 | #endif |
---|
603 | |
---|
604 | /* |
---|
605 | * Show version info |
---|
606 | */ |
---|
607 | if (DoPrintVersion || Debug) { |
---|
608 | PrintVersion(); |
---|
609 | if (!Debug) |
---|
610 | exit(0); |
---|
611 | } |
---|
612 | |
---|
613 | /* |
---|
614 | * Parse config files |
---|
615 | */ |
---|
616 | if (UseConfig) { |
---|
617 | if (CFparse(ConfFile, ConfDir) != 0) { |
---|
618 | SImsg(SIM_CERR, "Errors occured while parsing config file(s)."); |
---|
619 | exit(1); |
---|
620 | } |
---|
621 | } |
---|
622 | |
---|
623 | /* |
---|
624 | * Check MCL |
---|
625 | */ |
---|
626 | MClic = CheckMCL(MCLprogramName); |
---|
627 | |
---|
628 | if (DoPrintLicense) { |
---|
629 | if (cp = MCLgetInfo(MClic)) |
---|
630 | SImsg(SIM_INFO|SIM_NONL|SIM_DBG, cp); |
---|
631 | exit(0); |
---|
632 | } |
---|
633 | |
---|
634 | /* |
---|
635 | * Do any list commands and exit |
---|
636 | */ |
---|
637 | if (ListStr) { |
---|
638 | List(ListStr); |
---|
639 | exit(0); |
---|
640 | } |
---|
641 | |
---|
642 | /* |
---|
643 | * Set verbosity strings |
---|
644 | */ |
---|
645 | if (MsgLevelStr && ParseMsgLevel(MsgLevelStr)) |
---|
646 | exit(1); |
---|
647 | |
---|
648 | /* |
---|
649 | * Set format type |
---|
650 | */ |
---|
651 | if (FormatStr && ParseFormat(FormatStr)) |
---|
652 | exit(1); |
---|
653 | |
---|
654 | /* |
---|
655 | * Check to see if runtime access is ok. |
---|
656 | */ |
---|
657 | CheckRunTimeAccess(); |
---|
658 | |
---|
659 | /* |
---|
660 | * Check to see if we're running on the right platform |
---|
661 | */ |
---|
662 | CheckRunTimePlatform(); |
---|
663 | |
---|
664 | /* |
---|
665 | * If a -show was specified but not -class, then |
---|
666 | * default to "General". |
---|
667 | */ |
---|
668 | if (ShowStr && !ClassNames) |
---|
669 | ClassNames = "General"; |
---|
670 | |
---|
671 | /* |
---|
672 | * Set class info |
---|
673 | */ |
---|
674 | ClassSetInfo(ClassNames); |
---|
675 | |
---|
676 | /* |
---|
677 | * Set type info |
---|
678 | */ |
---|
679 | TypeSetInfo(TypeNames); |
---|
680 | |
---|
681 | SImsg(SIM_DBG, "Verbosity level = 0x%x\n", MsgLevel); |
---|
682 | |
---|
683 | exit( ClassCall(ShowStr) ); |
---|
684 | } |
---|