4 * Dump a MIB module conforming to a given format.
6 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
7 * Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig.
9 * See the file "COPYING" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * @(#) $Id: smidump.c 7870 2008-03-11 19:29:58Z schoenw $
33 static void help(void);
34 static void usage(void);
35 static void version(void);
36 static void config(char *filename);
37 static void level(int lev);
38 static void quiet(void);
39 static void preload(char *module);
40 static void unified(void);
41 static void format(char *form);
45 static int mFlag = 0; /* show the name for error messages */
46 static int sFlag = 0; /* show the severity for error messages */
47 static int kFlag = 0; /* keep going after severe errors */
48 static SmidumpDriver *driver;
49 static SmidumpDriver *firstDriver;
50 static SmidumpDriver *lastDriver;
51 static SmidumpDriver *defaultDriver;
55 static optStruct *opt;
56 static optStruct genericOpt[] = {
57 /* short long type var/func special */
58 { 'h', "help", OPT_FLAG, help, OPT_CALLFUNC },
59 { 'V', "version", OPT_FLAG, version, OPT_CALLFUNC },
60 { 'c', "config", OPT_STRING, config, OPT_CALLFUNC },
61 { 'l', "level", OPT_INT, level, OPT_CALLFUNC },
62 { 'p', "preload", OPT_STRING, preload, OPT_CALLFUNC },
63 { 'l', "level", OPT_INT, level, OPT_CALLFUNC },
64 { 'q', "quiet", OPT_FLAG, quiet, OPT_CALLFUNC },
65 { 'm', "error-names", OPT_FLAG, &mFlag, 0 },
66 { 's', "severity", OPT_FLAG, &sFlag, 0 },
67 { 'u', "unified", OPT_FLAG, unified, OPT_CALLFUNC },
68 { 'f', "format", OPT_STRING, format, OPT_CALLFUNC },
69 { 'o', "output", OPT_STRING, &output, 0 },
70 { 'k', "keep-going", OPT_FLAG, &kFlag, 0 },
71 { 0, 0, OPT_END, 0, 0 } /* no more options */
76 void *xmalloc(size_t size)
78 char *m = malloc(size);
80 fprintf(stderr, "smidump: malloc failed - running out of memory\n");
89 void *xrealloc(void *ptr, size_t size)
91 char *m = realloc(ptr, size);
93 fprintf(stderr, "smidump: realloc failed - running out of memory\n");
101 void *xcalloc(size_t nmemb, size_t size)
103 char *m = calloc(nmemb, size);
105 fprintf(stderr, "smidump: calloc failed - running out of memory\n");
113 char *xstrdup(const char *s)
117 fprintf(stderr, "smidump: strdup failed - running out of memory\n");
125 void xfree(void *ptr)
132 void smidumpRegisterDriver(SmidumpDriver *driver)
137 firstDriver = driver;
140 lastDriver->next = driver;
144 for (i = 0; driver->opt && driver->opt[i].type != OPT_END; i++) {
145 opt = xrealloc(opt, (opts+1) * sizeof(optStruct));
146 memcpy(&opt[opts], &opt[opts-1], sizeof(optStruct));
147 opt[opts-1].shortName = 0;
148 opt[opts-1].longName = xmalloc(strlen(driver->name) +
149 strlen(driver->opt[i].name) + 2);
150 sprintf(opt[opts-1].longName, "%s-%s",
151 driver->name, driver->opt[i].name);
152 opt[opts-1].type = driver->opt[i].type;
153 opt[opts-1].arg = driver->opt[i].arg;
154 opt[opts-1].flags = driver->opt[i].flags;
161 static void formats()
163 SmidumpDriver *driver = firstDriver;
165 for (driver = firstDriver; driver; driver = driver->next) {
166 fprintf(stderr, " %-14s: %s\n", driver->name,
167 driver->descr ? driver->descr : "...");
176 SmidumpDriver *driver;
181 %n in printf is a security vulnerability. Ref:
182 http://en.wikipedia.org/wiki/Format_string_vulnerabilities
183 MS decided it was important enough to disble it by default. Ref:
184 "ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vccrt/html/77a854ae-5b48-4865-89f4-f2dc5cf80f52.htm
185 Calling _set_printf_count_output() stops an invalid parameter crash.
192 "Usage: smidump [options] [module or path ...]\n"
193 " -V, --version show version and license information\n"
194 " -h, --help show usage information\n"
195 " -q, --quiet do not generate any comments\n"
196 " -c, --config=file load a specific configuration file\n"
197 " -p, --preload=module preload <module>\n"
198 " -l, --level=level set maximum level of errors and warnings\n"
199 " -m, --error-names print the name of errors in braces\n"
200 " -s, --severity print the severity of errors in brackets\n"
201 " -f, --format=format use <format> when dumping (default %s)\n"
202 " -o, --output=name use <name> when creating names for output files\n"
203 " -u, --unified print a single unified output of all modules\n"
204 " -k, --keep-going continue after serious parse errors\n\n",
205 defaultDriver ? defaultDriver->name : "none");
207 fprintf(stderr, "Supported formats are:\n");
210 for (driver = firstDriver; driver; driver = driver->next) {
211 if (! driver->opt) continue;
212 fprintf(stderr, "\nSpecific option for the \"%s\" format:\n",
214 for (i = 0; driver->opt && driver->opt[i].type != OPT_END; i++) {
216 switch (driver->opt[i].type) {
233 printf_state=_set_printf_count_output(1);
236 fprintf(stderr, " --%s-%s%s%s%n",
237 driver->name, driver->opt[i].name,
243 (void)_set_printf_count_output(printf_state);
246 fprintf(stderr, "%*s%s\n",
248 driver->opt[i].descr ? driver->opt[i].descr : "...");
255 static void help() { usage(); exit(0); }
256 static void version() { printf("smidump " SMI_VERSION_STRING "\n"); exit(0); }
257 static void config(char *filename) { smiReadConfig(filename, "smidump"); }
258 static void level(int lev) { smiSetErrorLevel(lev); }
259 static void quiet() { flags |= SMIDUMP_FLAG_SILENT; }
260 static void preload(char *module) { smiLoadModule(module); }
261 static void unified() { flags |= SMIDUMP_FLAG_UNITE; }
263 static void format(char *form)
265 for (driver = firstDriver; driver; driver = driver->next) {
266 if (strcasecmp(driver->name, form) == 0) {
271 fprintf(stderr, "smidump: invalid dump format `%s'"
272 " - supported formats are:\n", form);
281 errorHandler(char *path, int line, int severity, char *msg, char *tag)
284 fprintf(stderr, "%s:%d: ", path, line);
287 fprintf(stderr, "[%d] ", severity);
290 fprintf(stderr, "{%s} ", tag);
295 fprintf(stderr, "warning: ");
298 fprintf(stderr, "info: ");
301 fprintf(stderr, "%s\n", msg);
310 int main(int argc, char *argv[])
313 SmiModule *smiModule;
315 SmiModule **modv = NULL;
319 firstDriver = lastDriver = defaultDriver = NULL;
321 opts = sizeof(genericOpt) / sizeof(optStruct);
322 opt = xmalloc(sizeof(genericOpt));
323 memcpy(opt, genericOpt, sizeof(genericOpt));
339 initSmi(); defaultDriver = lastDriver;
355 for (i = 1; i < argc; i++)
356 if ((strstr(argv[i], "-c") == argv[i]) ||
357 (strstr(argv[i], "--config") == argv[i])) break;
364 driver = defaultDriver;
366 optParseOptions(&argc, argv, opt, 0);
369 fprintf(stderr, "smidump: no dump formats registered\n");
374 if (sFlag || mFlag) {
375 smiSetErrorHandler(errorHandler);
378 smiflags = smiGetFlags();
379 smiflags |= SMI_FLAG_ERRORS;
380 smiflags |= driver->smiflags;
381 smiSetFlags(smiflags);
383 if (flags & SMIDUMP_FLAG_UNITE && driver->ignflags & SMIDUMP_DRIVER_CANT_UNITE) {
384 fprintf(stderr, "smidump: %s format does not support united output:"
385 " ignoring -u\n", driver->name);
386 flags = (flags & ~SMIDUMP_FLAG_UNITE);
389 if (output && driver->ignflags & SMIDUMP_DRIVER_CANT_OUTPUT) {
390 fprintf(stderr, "smidump: %s format does not support output option:"
391 " ignoring -o %s\n", driver->name, output);
395 modv = (SmiModule **) xmalloc((argc) * sizeof(SmiModule *));
398 for (i = 1; i < argc; i++) {
399 modulename = smiLoadModule(argv[i]);
400 smiModule = modulename ? smiGetModule(modulename) : NULL;
402 if ((smiModule->conformance) && (smiModule->conformance < 3)) {
403 flags |= SMIDUMP_FLAG_ERROR;
404 if (! (flags & SMIDUMP_FLAG_SILENT)) {
406 "smidump: module `%s' contains errors, "
407 "expect flawed output\n",
411 modv[modc++] = smiModule;
413 fprintf(stderr, "smidump: cannot locate module `%s'\n",
418 if (! (flags & SMIDUMP_FLAG_ERROR) || kFlag) {
419 (driver->func)(modc, modv, flags, output);
421 if (! (flags & SMIDUMP_FLAG_SILENT)) {
423 "smidump: aborting due to severe parsing errors\n"
424 "smidump: use the -k option to force continuation\n");
430 if (modv) xfree(modv);