"Fossies" - the Fresh Open Source Software Archive

Member "dmidecode-3.3/dmiopt.c" (14 Oct 2020, 9828 Bytes) of package /linux/privat/dmidecode-3.3.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.2_vs_3.3.

    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     { "bios-revision", 0, 0x15 },       /* 0x14 and 0x15 */
  155     { "firmware-revision", 0, 0x17 },   /* 0x16 and 0x17 */
  156     { "system-manufacturer", 1, 0x04 },
  157     { "system-product-name", 1, 0x05 },
  158     { "system-version", 1, 0x06 },
  159     { "system-serial-number", 1, 0x07 },
  160     { "system-uuid", 1, 0x08 },             /* dmi_system_uuid() */
  161     { "system-sku-number", 1, 0x19 },
  162     { "system-family", 1, 0x1a },
  163     { "baseboard-manufacturer", 2, 0x04 },
  164     { "baseboard-product-name", 2, 0x05 },
  165     { "baseboard-version", 2, 0x06 },
  166     { "baseboard-serial-number", 2, 0x07 },
  167     { "baseboard-asset-tag", 2, 0x08 },
  168     { "chassis-manufacturer", 3, 0x04 },
  169     { "chassis-type", 3, 0x05 },            /* dmi_chassis_type() */
  170     { "chassis-version", 3, 0x06 },
  171     { "chassis-serial-number", 3, 0x07 },
  172     { "chassis-asset-tag", 3, 0x08 },
  173     { "processor-family", 4, 0x06 },        /* dmi_processor_family() */
  174     { "processor-manufacturer", 4, 0x07 },
  175     { "processor-version", 4, 0x10 },
  176     { "processor-frequency", 4, 0x16 },     /* dmi_processor_frequency() */
  177 };
  178 
  179 /* This is a template, 3rd field is set at runtime. */
  180 static struct string_keyword opt_oem_string_keyword =
  181     { NULL, 11, 0x00 };
  182 
  183 static void print_opt_string_list(void)
  184 {
  185     unsigned int i;
  186 
  187     fprintf(stderr, "Valid string keywords are:\n");
  188     for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++)
  189     {
  190         fprintf(stderr, "  %s\n", opt_string_keyword[i].keyword);
  191     }
  192 }
  193 
  194 static int parse_opt_string(const char *arg)
  195 {
  196     unsigned int i;
  197 
  198     if (opt.string)
  199     {
  200         fprintf(stderr, "Only one string can be specified\n");
  201         return -1;
  202     }
  203 
  204     for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++)
  205     {
  206         if (!strcasecmp(arg, opt_string_keyword[i].keyword))
  207         {
  208             opt.string = &opt_string_keyword[i];
  209             return 0;
  210         }
  211     }
  212 
  213     fprintf(stderr, "Invalid string keyword: %s\n", arg);
  214     print_opt_string_list();
  215     return -1;
  216 }
  217 
  218 static int parse_opt_oem_string(const char *arg)
  219 {
  220     unsigned long val;
  221     char *next;
  222 
  223     if (opt.string)
  224     {
  225         fprintf(stderr, "Only one string can be specified\n");
  226         return -1;
  227     }
  228 
  229     /* Return the number of OEM strings */
  230     if (strcmp(arg, "count") == 0)
  231         goto done;
  232 
  233     val = strtoul(arg, &next, 10);
  234     if (next == arg  || *next != '\0' || val == 0x00 || val > 0xff)
  235     {
  236         fprintf(stderr, "Invalid OEM string number: %s\n", arg);
  237         return -1;
  238     }
  239 
  240     opt_oem_string_keyword.offset = val;
  241 done:
  242     opt.string = &opt_oem_string_keyword;
  243     return 0;
  244 }
  245 
  246 static u32 parse_opt_handle(const char *arg)
  247 {
  248     u32 val;
  249     char *next;
  250 
  251     val = strtoul(arg, &next, 0);
  252     if (next == arg || *next != '\0' || val > 0xffff)
  253     {
  254         fprintf(stderr, "Invalid handle number: %s\n", arg);
  255         return ~0;
  256     }
  257     return val;
  258 }
  259 
  260 /*
  261  * Command line options handling
  262  */
  263 
  264 /* Return -1 on error, 0 on success */
  265 int parse_command_line(int argc, char * const argv[])
  266 {
  267     int option;
  268     const char *optstring = "d:hqs:t:uH:V";
  269     struct option longopts[] = {
  270         { "dev-mem", required_argument, NULL, 'd' },
  271         { "help", no_argument, NULL, 'h' },
  272         { "quiet", no_argument, NULL, 'q' },
  273         { "string", required_argument, NULL, 's' },
  274         { "type", required_argument, NULL, 't' },
  275         { "dump", no_argument, NULL, 'u' },
  276         { "dump-bin", required_argument, NULL, 'B' },
  277         { "from-dump", required_argument, NULL, 'F' },
  278         { "handle", required_argument, NULL, 'H' },
  279         { "oem-string", required_argument, NULL, 'O' },
  280         { "no-sysfs", no_argument, NULL, 'S' },
  281         { "version", no_argument, NULL, 'V' },
  282         { NULL, 0, NULL, 0 }
  283     };
  284 
  285     while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
  286         switch (option)
  287         {
  288             case 'B':
  289                 opt.flags |= FLAG_DUMP_BIN;
  290                 opt.dumpfile = optarg;
  291                 break;
  292             case 'F':
  293                 opt.flags |= FLAG_FROM_DUMP;
  294                 opt.dumpfile = optarg;
  295                 break;
  296             case 'd':
  297                 opt.devmem = optarg;
  298                 break;
  299             case 'h':
  300                 opt.flags |= FLAG_HELP;
  301                 break;
  302             case 'q':
  303                 opt.flags |= FLAG_QUIET;
  304                 break;
  305             case 's':
  306                 if (parse_opt_string(optarg) < 0)
  307                     return -1;
  308                 opt.flags |= FLAG_QUIET;
  309                 break;
  310             case 'O':
  311                 if (parse_opt_oem_string(optarg) < 0)
  312                     return -1;
  313                 opt.flags |= FLAG_QUIET;
  314                 break;
  315             case 't':
  316                 opt.type = parse_opt_type(opt.type, optarg);
  317                 if (opt.type == NULL)
  318                     return -1;
  319                 break;
  320             case 'H':
  321                 opt.handle = parse_opt_handle(optarg);
  322                 if (opt.handle  == ~0U)
  323                     return -1;
  324                 break;
  325             case 'u':
  326                 opt.flags |= FLAG_DUMP;
  327                 break;
  328             case 'S':
  329                 opt.flags |= FLAG_NO_SYSFS;
  330                 break;
  331             case 'V':
  332                 opt.flags |= FLAG_VERSION;
  333                 break;
  334             case '?':
  335                 switch (optopt)
  336                 {
  337                     case 's':
  338                         fprintf(stderr, "String keyword expected\n");
  339                         print_opt_string_list();
  340                         break;
  341                     case 't':
  342                         fprintf(stderr, "Type number or keyword expected\n");
  343                         print_opt_type_list();
  344                         break;
  345                 }
  346                 return -1;
  347         }
  348 
  349     /* Check for mutually exclusive output format options */
  350     if ((opt.string != NULL) + (opt.type != NULL)
  351       + !!(opt.flags & FLAG_DUMP_BIN) + (opt.handle != ~0U) > 1)
  352     {
  353         fprintf(stderr, "Options --string, --type, --handle and --dump-bin are mutually exclusive\n");
  354         return -1;
  355     }
  356 
  357     if ((opt.flags & FLAG_FROM_DUMP) && (opt.flags & FLAG_DUMP_BIN))
  358     {
  359         fprintf(stderr, "Options --from-dump and --dump-bin are mutually exclusive\n");
  360         return -1;
  361     }
  362 
  363     return 0;
  364 }
  365 
  366 void print_help(void)
  367 {
  368     static const char *help =
  369         "Usage: dmidecode [OPTIONS]\n"
  370         "Options are:\n"
  371         " -d, --dev-mem FILE     Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
  372         " -h, --help             Display this help text and exit\n"
  373         " -q, --quiet            Less verbose output\n"
  374         " -s, --string KEYWORD   Only display the value of the given DMI string\n"
  375         " -t, --type TYPE        Only display the entries of given type\n"
  376         " -H, --handle HANDLE    Only display the entry of given handle\n"
  377         " -u, --dump             Do not decode the entries\n"
  378         "     --dump-bin FILE    Dump the DMI data to a binary file\n"
  379         "     --from-dump FILE   Read the DMI data from a binary file\n"
  380         "     --no-sysfs         Do not attempt to read DMI data from sysfs files\n"
  381         "     --oem-string N     Only display the value of the given OEM string\n"
  382         " -V, --version          Display the version and exit\n";
  383 
  384     printf("%s", help);
  385 }