chiark / gitweb /
libudev: rename libudev-utils.c libudev-util.c
[elogind.git] / extras / scsi_id / scsi_id.c
index 4f0233ed0d6a9a7b44a31ec15378dbe57f99b0d8..d692a86799db76ef2f2ed9bb64ced6267930013f 100644 (file)
@@ -14,6 +14,8 @@
  *     Free Software Foundation version 2 of the License.
  */
 
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -27,9 +29,8 @@
 #include <getopt.h>
 #include <sys/stat.h>
 
-#include "../../udev.h"
+#include "../../udev/udev.h"
 #include "scsi_id.h"
-#include "scsi_id_version.h"
 
 static const struct option options[] = {
        { "device", 1, NULL, 'd' },
@@ -37,8 +38,8 @@ static const struct option options[] = {
        { "page", 1, NULL, 'p' },
        { "blacklisted", 0, NULL, 'b' },
        { "whitelisted", 0, NULL, 'g' },
-       { "prefix-bus-id", 0, NULL, 'i' },
        { "replace-whitespace", 0, NULL, 'u' },
+       { "sg-version", 1, NULL, 's' },
        { "verbose", 0, NULL, 'v' },
        { "version", 0, NULL, 'V' },
        { "export", 0, NULL, 'x' },
@@ -51,9 +52,9 @@ static const char dev_short_options[] = "bgp:";
 
 static int all_good;
 static int dev_specified;
-static char config_file[MAX_PATH_LEN] = SCSI_ID_CONFIG_FILE;
-static int display_bus_id;
+static char config_file[MAX_PATH_LEN] = SYSCONFDIR "/scsi_id.config";
 static enum page_code default_page_code;
+static int sg_version = 4;
 static int use_stderr;
 static int debug;
 static int reformat_serial;
@@ -63,30 +64,12 @@ static char model_str[64];
 static char revision_str[16];
 static char type_str[16];
 
-#ifdef USE_LOG
-void log_message(int priority, const char *format, ...)
+static void log_fn(struct udev *udev, int priority,
+                  const char *file, int line, const char *fn,
+                  const char *format, va_list args)
 {
-       va_list args;
-       static int udev_log = -1;
-
-       if (udev_log == -1) {
-               const char *value;
-
-               value = getenv("UDEV_LOG");
-               if (value)
-                       udev_log = log_priority(value);
-               else
-                       udev_log = LOG_ERR;
-       }
-
-       if (priority > udev_log)
-               return;
-
-       va_start(args, format);
        vsyslog(priority, format, args);
-       va_end(args);
 }
-#endif
 
 static void set_str(char *to, const char *from, size_t count)
 {
@@ -214,7 +197,8 @@ static int argc_count(char *opts)
  *
  * vendor and model can end in '\n'.
  */
-static int get_file_options(const char *vendor, const char *model,
+static int get_file_options(struct udev *udev,
+                           const char *vendor, const char *model,
                            int *argc, char ***newargv)
 {
        char *buffer;
@@ -226,14 +210,14 @@ static int get_file_options(const char *vendor, const char *model,
        int c;
        int retval = 0;
 
-       dbg("vendor='%s'; model='%s'\n", vendor, model);
+       dbg(udev, "vendor='%s'; model='%s'\n", vendor, model);
        fd = fopen(config_file, "r");
        if (fd == NULL) {
-               dbg("can't open %s\n", config_file);
+               dbg(udev, "can't open %s\n", config_file);
                if (errno == ENOENT) {
                        return 1;
                } else {
-                       err("can't open %s: %s\n", config_file, strerror(errno));
+                       err(udev, "can't open %s: %s\n", config_file, strerror(errno));
                        return -1;
                }
        }
@@ -245,7 +229,7 @@ static int get_file_options(const char *vendor, const char *model,
         */
        buffer = malloc(MAX_BUFFER_LEN);
        if (!buffer) {
-               err("can't allocate memory\n");
+               err(udev, "can't allocate memory\n");
                return -1;
        }
 
@@ -259,7 +243,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);
+                       err(udev, "Config file line %d too long\n", lineno);
                        break;
                }
 
@@ -311,7 +295,7 @@ static int get_file_options(const char *vendor, const char *model,
                 * Only allow: [vendor=foo[,model=bar]]options=stuff
                 */
                if (!options_in || (!vendor_in && model_in)) {
-                       info("Error parsing config file line %d '%s'\n", lineno, buffer);
+                       err(udev, "Error parsing config file line %d '%s'\n", lineno, buffer);
                        retval = -1;
                        break;
                }
@@ -349,7 +333,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\n");
+                               err(udev, "can't allocate memory\n");
                                retval = -1;
                        } else {
                                *argc = c;
@@ -374,7 +358,8 @@ static int get_file_options(const char *vendor, const char *model,
        return retval;
 }
 
-static int set_options(int argc, char **argv, const char *short_opts,
+static int set_options(struct udev *udev,
+                      int argc, char **argv, const char *short_opts,
                       char *maj_min_dev)
 {
        int option;
@@ -391,9 +376,9 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        break;
 
                if (optarg)
-                       dbg("option '%c' arg '%s'\n", option, optarg);
+                       dbg(udev, "option '%c' arg '%s'\n", option, optarg);
                else
-                       dbg("option '%c'\n", option);
+                       dbg(udev, "option '%c'\n", option);
 
                switch (option) {
                case 'b':
@@ -421,23 +406,19 @@ static int set_options(int argc, char **argv, const char *short_opts,
 
                case 'h':
                        printf("Usage: scsi_id OPTIONS <device>\n"
-                              "  --device               device node for SG_IO commands\n"
-                              "  --config               location of config file\n"
-                              "  --page                 SCSI page (0x80, 0x83, pre-spc3-83)\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");
+                              "  --device=                     device node for SG_IO commands\n"
+                              "  --config=                     location of config file\n"
+                              "  --page=0x80|0x83|pre-spc3-83  SCSI page (0x80, 0x83, pre-spc3-83)\n"
+                              "  --sg-version=3|4              use SGv3 or SGv4\n"
+                              "  --blacklisted                 threat device as blacklisted\n"
+                              "  --whitelisted                 threat device as whitelisted\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;
-
                case 'p':
                        if (strcmp(optarg, "0x80") == 0) {
                                default_page_code = PAGE_80;
@@ -446,7 +427,15 @@ 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'\n", optarg);
+                               err(udev, "Unknown page code '%s'\n", optarg);
+                               return -1;
+                       }
+                       break;
+
+               case 's':
+                       sg_version = atoi(optarg);
+                       if (sg_version < 3 || sg_version > 4) {
+                               err(udev, "Unknown SG version '%s'\n", optarg);
                                return -1;
                        }
                        break;
@@ -464,7 +453,7 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        break;
 
                case 'V':
-                       printf("%s\n", SCSI_ID_VERSION);
+                       printf("%s\n", VERSION);
                        exit(0);
                        break;
 
@@ -480,7 +469,8 @@ static int set_options(int argc, char **argv, const char *short_opts,
        return 0;
 }
 
-static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *page_code)
+static int per_dev_options(struct udev *udev,
+                          struct scsi_id_device *dev_scsi, int *good_bad, int *page_code)
 {
        int retval;
        int newargc;
@@ -490,7 +480,7 @@ static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *
        *good_bad = all_good;
        *page_code = default_page_code;
 
-       retval = get_file_options(vendor_str, model_str, &newargc, &newargv);
+       retval = get_file_options(udev, vendor_str, model_str, &newargc, &newargv);
 
        optind = 1; /* reset this global extern */
        while (retval == 0) {
@@ -499,9 +489,9 @@ static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *
                        break;
 
                if (optarg)
-                       dbg("option '%c' arg '%s'\n", option, optarg);
+                       dbg(udev, "option '%c' arg '%s'\n", option, optarg);
                else
-                       dbg("option '%c'\n", option);
+                       dbg(udev, "option '%c'\n", option);
 
                switch (option) {
                case 'b':
@@ -520,13 +510,13 @@ static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *
                        } else if (strcmp(optarg, "pre-spc3-83") == 0) {
                                *page_code = PAGE_83_PRE_SPC3; 
                        } else {
-                               info("Unknown page code '%s'\n", optarg);
+                               err(udev, "Unknown page code '%s'\n", optarg);
                                retval = -1;
                        }
                        break;
 
                default:
-                       info("Unknown or bad option '%c' (0x%x)\n", option, option);
+                       err(udev, "Unknown or bad option '%c' (0x%x)\n", option, option);
                        retval = -1;
                        break;
                }
@@ -539,18 +529,20 @@ static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *
        return retval;
 }
 
-static int set_inq_values(struct scsi_id_device *dev_scsi, const char *path)
+static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, const char *path)
 {
        int retval;
 
-       retval = scsi_std_inquiry(dev_scsi, path);
+       dev_scsi->use_sg = sg_version;
+
+       retval = scsi_std_inquiry(udev, dev_scsi, path);
        if (retval)
-           return retval;
+               return retval;
 
-       set_str(vendor_str, dev_scsi->vendor, 8);
-       set_str(model_str, dev_scsi->model, 16);
-       set_type(type_str, dev_scsi->type, sizeof(type_str) - 1);
-       set_str(revision_str, dev_scsi->revision, sizeof(revision_str) -1);
+       set_str(vendor_str, dev_scsi->vendor, sizeof(vendor_str));
+       set_str(model_str, dev_scsi->model, sizeof(model_str));
+       set_type(type_str, dev_scsi->type, sizeof(type_str));
+       set_str(revision_str, dev_scsi->revision, sizeof(revision_str));
 
        return 0;
 }
@@ -587,7 +579,7 @@ static void format_serial(char *serial)
  * memory etc. return 2, and return 1 for expected cases (like broken
  * device found) that do not print an id.
  */
-static int scsi_id(char *maj_min_dev)
+static int scsi_id(struct udev *udev, char *maj_min_dev)
 {
        int retval;
        struct scsi_id_device dev_scsi;
@@ -595,15 +587,16 @@ static int scsi_id(char *maj_min_dev)
        int page_code;
        char serial_short[MAX_SERIAL_LEN] = "";
 
-       set_inq_values(&dev_scsi, maj_min_dev);
+       set_inq_values(udev, &dev_scsi, maj_min_dev);
 
        /* get per device (vendor + model) options from the config file */
-       retval = per_dev_options(&dev_scsi, &good_dev, &page_code);
+       retval = per_dev_options(udev, &dev_scsi, &good_dev, &page_code);
        dbg("per dev options: good %d; page code 0x%x\n", good_dev, page_code);
 
        if (!good_dev) {
                retval = 1;
-       } else if (scsi_get_serial(&dev_scsi, maj_min_dev, page_code,
+       } else if (scsi_get_serial(udev,
+                                  &dev_scsi, maj_min_dev, page_code,
                                   serial_short, MAX_SERIAL_LEN)) {
                retval = 1;
        } else {
@@ -635,25 +628,30 @@ static int scsi_id(char *maj_min_dev)
 
 int main(int argc, char **argv)
 {
+       struct udev *udev;
        int retval = 0;
        char maj_min_dev[MAX_PATH_LEN];
        int newargc;
        char **newargv;
 
+       udev = udev_new();
+       if (udev == NULL)
+               goto exit;
+
        logging_init("scsi_id");
-       dbg("argc is %d\n", argc);
+       udev_set_log_fn(udev, log_fn);
 
        /*
         * Get config file options.
         */
        newargv = NULL;
-       retval = get_file_options(NULL, NULL, &newargc, &newargv);
+       retval = get_file_options(udev, NULL, NULL, &newargc, &newargv);
        if (retval < 0) {
                retval = 1;
                goto exit;
        }
        if (newargv && (retval == 0)) {
-               if (set_options(newargc, newargv, short_options, maj_min_dev) < 0) {
+               if (set_options(udev, newargc, newargv, short_options, maj_min_dev) < 0) {
                        retval = 2;
                        goto exit;
                }
@@ -663,18 +661,19 @@ int main(int argc, char **argv)
        /*
         * Get command line options (overriding any config file settings).
         */
-       if (set_options(argc, argv, short_options, maj_min_dev) < 0)
+       if (set_options(udev, argc, argv, short_options, maj_min_dev) < 0)
                exit(1);
 
        if (!dev_specified) {
-               info("no device specified\n");
+               err(udev, "no device specified\n");
                retval = 1;
                goto exit;
        }
 
-       retval = scsi_id(maj_min_dev);
+       retval = scsi_id(udev, maj_min_dev);
 
 exit:
+       udev_unref(udev);
        logging_close();
        return retval;
 }