"Fossies" - the Fresh Open Source Software Archive

Member "dmidecode-3.2/dmiopt.c" (14 Sep 2018, 9686 Bytes) of package /linux/privat/dmidecode-3.2.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dmiopt.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.1_vs_3.2.

    1 /*
    2  * Command line handling of dmidecode
    3  * This file is part of the dmidecode project.
    4  *
    5  *   Copyright (C) 2005-2008 Jean Delvare <jdelvare@suse.de>
    6  *
    7  *   This program is free software; you can redistribute it and/or modify
    8  *   it under the terms of the GNU General Public License as published by
    9  *   the Free Software Foundation; either version 2 of the License, or
   10  *   (at your option) any later version.
   11  *
   12  *   This program is distributed in the hope that it will be useful,
   13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  *   GNU General Public License for more details.
   16  *
   17  *   You should have received a copy of the GNU General Public License
   18  *   along with this program; if not, write to the Free Software
   19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   20  */
   21 
   22 #include <stdio.h>
   23 #include <string.h>
   24 #include <strings.h>
   25 #include <stdlib.h>
   26 #include <getopt.h>
   27 
   28 #include "config.h"
   29 #include "types.h"
   30 #include "util.h"
   31 #include "dmidecode.h"
   32 #include "dmiopt.h"
   33 
   34 
   35 /* Options are global */
   36 struct opt opt;
   37 
   38 
   39 /*
   40  * Handling of option --type
   41  */
   42 
   43 struct type_keyword
   44 {
   45     const char *keyword;
   46     const u8 *type;
   47 };
   48 
   49 static const u8 opt_type_bios[] = { 0, 13, 255 };
   50 static const u8 opt_type_system[] = { 1, 12, 15, 23, 32, 255 };
   51 static const u8 opt_type_baseboard[] = { 2, 10, 41, 255 };
   52 static const u8 opt_type_chassis[] = { 3, 255 };
   53 static const u8 opt_type_processor[] = { 4, 255 };
   54 static const u8 opt_type_memory[] = { 5, 6, 16, 17, 255 };
   55 static const u8 opt_type_cache[] = { 7, 255 };
   56 static const u8 opt_type_connector[] = { 8, 255 };
   57 static const u8 opt_type_slot[] = { 9, 255 };
   58 
   59 static const struct type_keyword opt_type_keyword[] = {
   60     { "bios", opt_type_bios },
   61     { "system", opt_type_system },
   62     { "baseboard", opt_type_baseboard },
   63     { "chassis", opt_type_chassis },
   64     { "processor", opt_type_processor },
   65     { "memory", opt_type_memory },
   66     { "cache", opt_type_cache },
   67     { "connector", opt_type_connector },
   68     { "slot", opt_type_slot },
   69 };
   70 
   71 static void print_opt_type_list(void)
   72 {
   73     unsigned int i;
   74 
   75     fprintf(stderr, "Valid type keywords are:\n");
   76     for (i = 0; i < ARRAY_SIZE(opt_type_keyword); i++)
   77     {
   78         fprintf(stderr, "  %s\n", opt_type_keyword[i].keyword);
   79     }
   80 }
   81 
   82 static u8 *parse_opt_type(u8 *p, const char *arg)
   83 {
   84     unsigned int i;
   85 
   86     /* Allocate memory on first call only */
   87     if (p == NULL)
   88     {
   89         p = (u8 *)calloc(256, sizeof(u8));
   90         if (p == NULL)
   91         {
   92             perror("calloc");
   93             return NULL;
   94         }
   95     }
   96 
   97     /* First try as a keyword */
   98     for (i = 0; i < ARRAY_SIZE(opt_type_keyword); i++)
   99     {
  100         if (!strcasecmp(arg, opt_type_keyword[i].keyword))
  101         {
  102             int j = 0;
  103             while (opt_type_keyword[i].type[j] != 255)
  104                 p[opt_type_keyword[i].type[j++]] = 1;
  105             goto found;
  106         }
  107     }
  108 
  109     /* Else try as a number */
  110     while (*arg != '\0')
  111     {
  112         unsigned long val;
  113         char *next;
  114 
  115         val = strtoul(arg, &next, 0);
  116         if (next == arg || (*next != '\0' && *next != ',' && *next != ' '))
  117         {
  118             fprintf(stderr, "Invalid type keyword: %s\n", arg);
  119             print_opt_type_list();
  120             goto exit_free;
  121         }
  122         if (val > 0xff)
  123         {
  124             fprintf(stderr, "Invalid type number: %lu\n", val);
  125             goto exit_free;
  126         }
  127 
  128         p[val] = 1;
  129         arg = next;
  130         while (*arg == ',' || *arg == ' ')
  131             arg++;
  132     }
  133 
  134 found:
  135     return p;
  136 
  137 exit_free:
  138     free(p);
  139     return NULL;
  140 }
  141 
  142 
  143 /*
  144  * Handling of option --string
  145  */
  146 
  147 /* This lookup table could admittedly be reworked for improved performance.
  148    Due to the low count of items in there at the moment, it did not seem
  149    worth the additional code complexity though. */
  150 static const struct string_keyword opt_string_keyword[] = {
  151     { "bios-vendor", 0, 0x04 },
  152     { "bios-version", 0, 0x05 },
  153     { "bios-release-date", 0, 0x08 },
  154     { "system-manufacturer", 1, 0x04 },
  155     { "system-product-name", 1, 0x05 },
  156     { "system-version", 1, 0x06 },
  157     { "system-serial-number", 1, 0x07 },
  158     { "system-uuid", 1, 0x08 },             /* dmi_system_uuid() */
  159     { "system-family", 1, 0x1a },
  160     { "baseboard-manufacturer", 2, 0x04 },
  161     { "baseboard-product-name", 2, 0x05 },
  162     { "baseboard-version", 2, 0x06 },
  163     { "baseboard-serial-number", 2, 0x07 },
  164     { "baseboard-asset-tag", 2, 0x08 },
  165     { "chassis-manufacturer", 3, 0x04 },
  166     { "chassis-type", 3, 0x05 },            /* dmi_chassis_type() */
  167     { "chassis-version", 3, 0x06 },
  168     { "chassis-serial-number", 3, 0x07 },
  169     { "chassis-asset-tag", 3, 0x08 },
  170     { "processor-family", 4, 0x06 },        /* dmi_processor_family() */
  171     { "processor-manufacturer", 4, 0x07 },
  172     { "processor-version", 4, 0x10 },
  173     { "processor-frequency", 4, 0x16 },     /* dmi_processor_frequency() */
  174 };
  175 
  176 /* This is a template, 3rd field is set at runtime. */
  177 static struct string_keyword opt_oem_string_keyword =
  178     { NULL, 11, 0x00 };
  179 
  180 static void print_opt_string_list(void)
  181 {
  182     unsigned int i;
  183 
  184     fprintf(stderr, "Valid string keywords are:\n");
  185     for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++)
  186     {
  187         fprintf(stderr, "  %s\n", opt_string_keyword[i].keyword);
  188     }
  189 }
  190 
  191 static int parse_opt_string(const char *arg)
  192 {
  193     unsigned int i;
  194 
  195     if (opt.string)
  196     {
  197         fprintf(stderr, "Only one string can be specified\n");
  198         return -1;
  199     }
  200 
  201     for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++)
  202     {
  203         if (!strcasecmp(arg, opt_string_keyword[i].keyword))
  204         {
  205             opt.string = &opt_string_keyword[i];
  206             return 0;
  207         }
  208     }
  209 
  210     fprintf(stderr, "Invalid string keyword: %s\n", arg);
  211     print_opt_string_list();
  212     return -1;
  213 }
  214 
  215 static int parse_opt_oem_string(const char *arg)
  216 {
  217     unsigned long val;
  218     char *next;
  219 
  220     if (opt.string)
  221     {
  222         fprintf(stderr, "Only one string can be specified\n");
  223         return -1;
  224     }
  225 
  226     /* Return the number of OEM strings */
  227     if (strcmp(arg, "count") == 0)
  228         goto done;
  229 
  230     val = strtoul(arg, &next, 10);
  231     if (next == arg  || *next != '\0' || val == 0x00 || val > 0xff)
  232     {
  233         fprintf(stderr, "Invalid OEM string number: %s\n", arg);
  234         return -1;
  235     }
  236 
  237     opt_oem_string_keyword.offset = val;
  238 done:
  239     opt.string = &opt_oem_string_keyword;
  240     return 0;
  241 }
  242 
  243 static u32 parse_opt_handle(const char *arg)
  244 {
  245     u32 val;
  246     char *next;
  247 
  248     val = strtoul(arg, &next, 0);
  249     if (next == arg || *next != '\0' || val > 0xffff)
  250     {
  251         fprintf(stderr, "Invalid handle number: %s\n", arg);
  252         return ~0;
  253     }
  254     return val;
  255 }
  256 
  257 /*
  258  * Command line options handling
  259  */
  260 
  261 /* Return -1 on error, 0 on success */
  262 int parse_command_line(int argc, char * const argv[])
  263 {
  264     int option;
  265     const char *optstring = "d:hqs:t:uH:V";
  266     struct option longopts[] = {
  267         { "dev-mem", required_argument, NULL, 'd' },
  268         { "help", no_argument, NULL, 'h' },
  269         { "quiet", no_argument, NULL, 'q' },
  270         { "string", required_argument, NULL, 's' },
  271         { "type", required_argument, NULL, 't' },
  272         { "dump", no_argument, NULL, 'u' },
  273         { "dump-bin", required_argument, NULL, 'B' },
  274         { "from-dump", required_argument, NULL, 'F' },
  275         { "handle", required_argument, NULL, 'H' },
  276         { "oem-string", required_argument, NULL, 'O' },
  277         { "no-sysfs", no_argument, NULL, 'S' },
  278         { "version", no_argument, NULL, 'V' },
  279         { NULL, 0, NULL, 0 }
  280     };
  281 
  282     while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
  283         switch (option)
  284         {
  285             case 'B':
  286                 opt.flags |= FLAG_DUMP_BIN;
  287                 opt.dumpfile = optarg;
  288                 break;
  289             case 'F':
  290                 opt.flags |= FLAG_FROM_DUMP;
  291                 opt.dumpfile = optarg;
  292                 break;
  293             case 'd':
  294                 opt.devmem = optarg;
  295                 break;
  296             case 'h':
  297                 opt.flags |= FLAG_HELP;
  298                 break;
  299             case 'q':
  300                 opt.flags |= FLAG_QUIET;
  301                 break;
  302             case 's':
  303                 if (parse_opt_string(optarg) < 0)
  304                     return -1;
  305                 opt.flags |= FLAG_QUIET;
  306                 break;
  307             case 'O':
  308                 if (parse_opt_oem_string(optarg) < 0)
  309                     return -1;
  310                 opt.flags |= FLAG_QUIET;
  311                 break;
  312             case 't':
  313                 opt.type = parse_opt_type(opt.type, optarg);
  314                 if (opt.type == NULL)
  315                     return -1;
  316                 break;
  317             case 'H':
  318                 opt.handle = parse_opt_handle(optarg);
  319                 if (opt.handle  == ~0U)
  320                     return -1;
  321                 break;
  322             case 'u':
  323                 opt.flags |= FLAG_DUMP;
  324                 break;
  325             case 'S':
  326                 opt.flags |= FLAG_NO_SYSFS;
  327                 break;
  328             case 'V':
  329                 opt.flags |= FLAG_VERSION;
  330                 break;
  331             case '?':
  332                 switch (optopt)
  333                 {
  334                     case 's':
  335                         fprintf(stderr, "String keyword expected\n");
  336                         print_opt_string_list();
  337                         break;
  338                     case 't':
  339                         fprintf(stderr, "Type number or keyword expected\n");
  340                         print_opt_type_list();
  341                         break;
  342                 }
  343                 return -1;
  344         }
  345 
  346     /* Check for mutually exclusive output format options */
  347     if ((opt.string != NULL) + (opt.type != NULL)
  348       + !!(opt.flags & FLAG_DUMP_BIN) + (opt.handle != ~0U) > 1)
  349     {
  350         fprintf(stderr, "Options --string, --type, --handle and --dump-bin are mutually exclusive\n");
  351         return -1;
  352     }
  353 
  354     if ((opt.flags & FLAG_FROM_DUMP) && (opt.flags & FLAG_DUMP_BIN))
  355     {
  356         fprintf(stderr, "Options --from-dump and --dump-bin are mutually exclusive\n");
  357         return -1;
  358     }
  359 
  360     return 0;
  361 }
  362 
  363 void print_help(void)
  364 {
  365     static const char *help =
  366         "Usage: dmidecode [OPTIONS]\n"
  367         "Options are:\n"
  368         " -d, --dev-mem FILE     Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
  369         " -h, --help             Display this help text and exit\n"
  370         " -q, --quiet            Less verbose output\n"
  371         " -s, --string KEYWORD   Only display the value of the given DMI string\n"
  372         " -t, --type TYPE        Only display the entries of given type\n"
  373         " -H, --handle HANDLE    Only display the entry of given handle\n"
  374         " -u, --dump             Do not decode the entries\n"
  375         "     --dump-bin FILE    Dump the DMI data to a binary file\n"
  376         "     --from-dump FILE   Read the DMI data from a binary file\n"
  377         "     --no-sysfs         Do not attempt to read DMI data from sysfs files\n"
  378         "     --oem-string N     Only display the value of the given OEM string\n"
  379         " -V, --version          Display the version and exit\n";
  380 
  381     printf("%s", help);
  382 }