chiark / gitweb /
scsi_id: initialize serial strings
[elogind.git] / extras / scsi_id / scsi_id.c
index 79a8d7e51bce5e1bc62d15355aa9eed2fca60540..538108717dcfc8ac3f195b99734a5704e8d9c649 100644 (file)
@@ -24,6 +24,7 @@
 #include <syslog.h>
 #include <stdarg.h>
 #include <ctype.h>
+#include <getopt.h>
 #include <sys/stat.h>
 
 #include "../../udev.h"
 #define TMP_DIR                "/dev"
 #define TMP_PREFIX     "tmp-scsi"
 
-static const char short_options[] = "abd:f:ginp:s:uvVx";
+static const struct option options[] = {
+       { "device", 1, NULL, 'd' },
+       { "config", 1, NULL, 'f' },
+       { "page", 1, NULL, 'p' },
+       { "devpath", 1, NULL, 's' },
+       { "fallback-to-sysfs", 0, NULL, 'a' },
+       { "blacklisted", 0, NULL, 'b' },
+       { "whitelisted", 0, NULL, 'g' },
+       { "prefix-bus-id", 0, NULL, 'i' },
+       { "replace-whitespace", 0, NULL, 'u' },
+       { "ignore-sysfs", 0, NULL, 'n' },
+       { "verbose", 0, NULL, 'v' },
+       { "version", 0, NULL, 'V' },
+       { "export", 0, NULL, 'x' },
+       { "help", 0, NULL, 'h' },
+       {}
+};
+
+static const char short_options[] = "abd:f:ghinp:s:uvVx";
 static const char dev_short_options[] = "bgp:";
 
 static int all_good;
@@ -155,25 +174,25 @@ static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type)
        unsigned int maj, min;
        const char *attr;
 
-       dbg("%s", devpath);
+       dbg("%s\n", devpath);
        attr = sysfs_attr_get_value(devpath, "dev");
        if (attr == NULL) {
-               dbg("%s: could not get dev attribute: %s", devpath, strerror(errno));
+               dbg("%s: could not get dev attribute: %s\n", devpath, strerror(errno));
                return -1;
        }
 
-       dbg("dev value %s", attr);
+       dbg("dev value %s\n", attr);
        if (sscanf(attr, "%u:%u", &maj, &min) != 2) {
-               err("%s: invalid dev major/minor", devpath);
+               err("%s: invalid dev major/minor\n", devpath);
                return -1;
        }
 
        snprintf(tmpdev, MAX_PATH_LEN, "%s/%s-maj%d-min%d-%u",
                 TMP_DIR, TMP_PREFIX, maj, min, getpid());
 
-       dbg("tmpdev '%s'", tmpdev);
+       dbg("tmpdev '%s'\n", tmpdev);
        if (mknod(tmpdev, 0600 | dev_type, makedev(maj, min))) {
-               err("mknod failed: %s", strerror(errno));
+               err("mknod failed: %s\n", strerror(errno));
                return -1;
        }
        return 0;
@@ -254,7 +273,7 @@ static int get_file_options(const char *vendor, const char *model,
                if (errno == ENOENT) {
                        return 1;
                } else {
-                       err("can't open %s: %s", config_file, strerror(errno));
+                       err("can't open %s: %s\n", config_file, strerror(errno));
                        return -1;
                }
        }
@@ -266,7 +285,7 @@ static int get_file_options(const char *vendor, const char *model,
         */
        buffer = malloc(MAX_BUFFER_LEN);
        if (!buffer) {
-               err("Can't allocate memory.");
+               err("can't allocate memory\n");
                return -1;
        }
 
@@ -280,7 +299,7 @@ static int get_file_options(const char *vendor, const char *model,
                        break;
                lineno++;
                if (buf[strlen(buffer) - 1] != '\n') {
-                       info("Config file line %d too long.\n", lineno);
+                       info("Config file line %d too long\n", lineno);
                        break;
                }
 
@@ -325,14 +344,14 @@ static int get_file_options(const char *vendor, const char *model,
                        }
                        options_in = str1;
                }
-               dbg("config file line %d:"
+               dbg("config file line %d:\n"
                        " vendor '%s'; model '%s'; options '%s'\n",
                        lineno, vendor_in, model_in, options_in);
                /*
                 * Only allow: [vendor=foo[,model=bar]]options=stuff
                 */
                if (!options_in || (!vendor_in && model_in)) {
-                       info("Error parsing config file line %d '%s'", lineno, buffer);
+                       info("Error parsing config file line %d '%s'\n", lineno, buffer);
                        retval = -1;
                        break;
                }
@@ -370,7 +389,7 @@ static int get_file_options(const char *vendor, const char *model,
                        c = argc_count(buffer) + 2;
                        *newargv = calloc(c, sizeof(**newargv));
                        if (!*newargv) {
-                               err("Can't allocate memory.");
+                               err("can't allocate memory\n");
                                retval = -1;
                        } else {
                                *argc = c;
@@ -407,7 +426,7 @@ static int set_options(int argc, char **argv, const char *short_opts,
         */
        optind = 1;
        while (1) {
-               option = getopt(argc, argv, short_opts);
+               option = getopt_long(argc, argv, short_opts, options, NULL);
                if (option == -1)
                        break;
 
@@ -443,6 +462,24 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        all_good = 1;
                        break;
 
+               case 'h':
+                       printf("Usage: scsi_id OPTIONS <device>\n"
+                              "  --device               device node for SG_IO commands\n"
+                              "  --devpath              sysfs devpath\n"
+                              "  --config               location of config file\n"
+                              "  --page                 SCSI page (0x80, 0x83, pre-spc3-83)\n"
+                              "  --fallback-to-sysfs    print sysfs values if inquiry fails\n"
+                              "  --ignore-sysfs         ignore sysfs entries\n"
+                              "  --blacklisted          threat device as blacklisted\n"
+                              "  --whitelisted          threat device as whitelisted\n"
+                              "  --prefix-bus-id        prefix SCSI bus id\n"
+                              "  --replace-whitespace   replace all whitespaces by underscores\n"
+                              "  --verbose              verbose logging\n"
+                              "  --version              print version\n"
+                              "  --export               print values as environment keys\n"
+                              "  --help                 print this help text\n\n");
+                       exit(0);
+
                case 'i':
                        display_bus_id = 1;
                        break;
@@ -455,7 +492,7 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        } else if (strcmp(optarg, "pre-spc3-83") == 0) {
                                default_page_code = PAGE_83_PRE_SPC3; 
                        } else {
-                               info("Unknown page code '%s'", optarg);
+                               info("Unknown page code '%s'\n", optarg);
                                return -1;
                        }
                        break;
@@ -483,13 +520,12 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        break;
 
                case 'V':
-                       info("scsi_id version: %s\n", SCSI_ID_VERSION);
+                       printf("%s\n", SCSI_ID_VERSION);
                        exit(0);
                        break;
 
                default:
-                       info("Unknown or bad option '%c' (0x%x)", option, option);
-                       return -1;
+                       exit(1);
                }
        }
        return 0;
@@ -509,7 +545,7 @@ static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *pa
 
        optind = 1; /* reset this global extern */
        while (retval == 0) {
-               option = getopt(newargc, newargv, dev_short_options);
+               option = getopt_long(newargc, newargv, dev_short_options, options, NULL);
                if (option == -1)
                        break;
 
@@ -535,13 +571,13 @@ static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *pa
                        } else if (strcmp(optarg, "pre-spc3-83") == 0) {
                                *page_code = PAGE_83_PRE_SPC3; 
                        } else {
-                               info("Unknown page code '%s'", optarg);
+                               info("Unknown page code '%s'\n", optarg);
                                retval = -1;
                        }
                        break;
 
                default:
-                       info("Unknown or bad option '%c' (0x%x)", option, option);
+                       info("Unknown or bad option '%c' (0x%x)\n", option, option);
                        retval = -1;
                        break;
                }
@@ -560,7 +596,7 @@ static int set_sysfs_values(struct sysfs_device *dev_scsi)
 
        vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
        if (!vendor) {
-               info("%s: cannot get vendor attribute", dev_scsi->devpath);
+               info("%s: cannot get vendor attribute\n", dev_scsi->devpath);
                return -1;
        }
        set_str(vendor_str, vendor, sizeof(vendor_str)-1);
@@ -574,7 +610,7 @@ static int set_sysfs_values(struct sysfs_device *dev_scsi)
 
        type = sysfs_attr_get_value(dev_scsi->devpath, "type");
        if (!type) {
-               info("%s: cannot get type attribute", dev_scsi->devpath);
+               info("%s: cannot get type attribute\n", dev_scsi->devpath);
                return -1;
        }
        set_type(type_str, type, sizeof(type_str));
@@ -646,15 +682,15 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
        struct sysfs_device *dev_scsi = NULL;
        int good_dev;
        int page_code;
-       char serial[MAX_SERIAL_LEN];
-       char serial_short[MAX_SERIAL_LEN];
-       char bus_str[8];
+       char serial[MAX_SERIAL_LEN] = "";
+       char serial_short[MAX_SERIAL_LEN] = "";
+       const char *bus_str = NULL;
 
        dbg("devpath %s\n", devpath);
 
        dev = sysfs_device_get(devpath);
        if (dev == NULL) {
-               err("unable to access '%s'", devpath);
+               err("unable to access '%s'\n", devpath);
                return 1;
        }
 
@@ -663,15 +699,6 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
        else
                dev_type = S_IFCHR;
 
-       if (!ignore_sysfs) {
-               /* get scsi parent device */
-               dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi");
-               if (dev_scsi == NULL) {
-                       err("unable to access parent device of '%s'", devpath);
-                       return 1;
-               }
-       }
-
        /* mknod a temp dev to communicate with the device */
        if (!dev_specified && create_tmp_dev(dev->devpath, maj_min_dev, dev_type)) {
                dbg("create_tmp_dev failed\n");
@@ -679,17 +706,22 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
        }
 
        if (!ignore_sysfs) {
+               /* get scsi parent device */
+               dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi");
+               if (dev_scsi == NULL) {
+                       err("unable to access parent device of '%s'\n", devpath);
+                       return 1;
+               }
                set_sysfs_values(dev_scsi);
-               strcpy(bus_str,"scsi");
+               bus_str = "scsi";
        } else {
                dev_scsi = dev;
                set_inq_values(dev_scsi, maj_min_dev);
-               strcpy(bus_str,"cciss");
        }
 
        /* get per device (vendor + model) options from the config file */
        retval = per_dev_options(dev_scsi, &good_dev, &page_code);
-       dbg("per dev options: good %d; page code 0x%x", good_dev, page_code);
+       dbg("per dev options: good %d; page code 0x%x\n", good_dev, page_code);
 
        if (!good_dev) {
                retval = 1;
@@ -711,7 +743,8 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
                        set_str(serial_str, serial_short, sizeof(serial_str));
                        printf("ID_SERIAL_SHORT=%s\n", serial_str);
                        printf("ID_TYPE=%s\n", type_str);
-                       printf("ID_BUS=%s\n", bus_str);
+                       if (bus_str != NULL)
+                               printf("ID_BUS=%s\n", bus_str);
                } else {
                        if (reformat_serial)
                                format_serial(serial);
@@ -784,7 +817,7 @@ int main(int argc, char **argv)
                exit(1);
 
        if (!sys_specified) {
-               info("-s must be specified\n");
+               info("--devpath=<path> must be specified\n");
                retval = 1;
                goto exit;
        }