X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fscsi_id%2Fscsi_id.c;h=5511df882550b44313c987c7c64929acd38c2744;hb=bdd13f6be4b588568683a1ab54f421fc6a636dbb;hp=b1e089cb7c63ce3c276a19c75b81be391165988d;hpb=0d0f0c50d3a1d90f03972a6abb82e6413daaa583;p=elogind.git diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c index b1e089cb7..5511df882 100644 --- a/src/udev/scsi_id/scsi_id.c +++ b/src/udev/scsi_id/scsi_id.c @@ -18,13 +18,14 @@ #include #include +#include +#include #include #include #include #include #include #include -#include #include #include #include @@ -32,34 +33,31 @@ #include "libudev.h" #include "libudev-private.h" #include "scsi_id.h" +#include "udev-util.h" static const struct option options[] = { - { "device", required_argument, NULL, 'd' }, - { "config", required_argument, NULL, 'f' }, - { "page", required_argument, NULL, 'p' }, - { "blacklisted", no_argument, NULL, 'b' }, - { "whitelisted", no_argument, NULL, 'g' }, - { "replace-whitespace", no_argument, NULL, 'u' }, - { "sg-version", required_argument, NULL, 's' }, - { "verbose", no_argument, NULL, 'v' }, - { "version", no_argument, NULL, 'V' }, - { "export", no_argument, NULL, 'x' }, - { "help", no_argument, NULL, 'h' }, + { "device", required_argument, NULL, 'd' }, + { "config", required_argument, NULL, 'f' }, + { "page", required_argument, NULL, 'p' }, + { "blacklisted", no_argument, NULL, 'b' }, + { "whitelisted", no_argument, NULL, 'g' }, + { "replace-whitespace", no_argument, NULL, 'u' }, + { "sg-version", required_argument, NULL, 's' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, /* don't advertise -V */ + { "export", no_argument, NULL, 'x' }, + { "help", no_argument, NULL, 'h' }, {} }; -static const char short_options[] = "d:f:ghip:uvVx"; -static const char dev_short_options[] = "bgp:"; - -static int all_good; -static int dev_specified; -static char config_file[MAX_PATH_LEN] = SYSCONFDIR "/scsi_id.config"; -static enum page_code default_page_code; +static bool all_good = false; +static bool dev_specified = false; +static char config_file[MAX_PATH_LEN] = "/etc/scsi_id.config"; +static enum page_code default_page_code = PAGE_UNSPECIFIED; static int sg_version = 4; -static int use_stderr; -static int debug; -static int reformat_serial; -static int export; +static int debug = 0; +static bool reformat_serial = false; +static bool export = false; static char vendor_str[64]; static char model_str[64]; static char vendor_enc_str[256]; @@ -67,6 +65,7 @@ static char model_enc_str[256]; static char revision_str[16]; static char type_str[16]; +_printf_(6,0) static void log_fn(struct udev *udev, int priority, const char *file, int line, const char *fn, const char *format, va_list args) @@ -108,7 +107,7 @@ static void set_type(const char *from, char *to, size_t len) break; } } - util_strscpy(to, len, type); + strscpy(to, len, type); } /* @@ -172,7 +171,7 @@ static int get_file_options(struct udev *udev, int *argc, char ***newargv) { char *buffer; - FILE *fd; + _cleanup_fclose_ FILE *f; char *buf; char *str1; char *vendor_in, *model_in, *options_in; /* read in from file */ @@ -180,12 +179,12 @@ static int get_file_options(struct udev *udev, int c; int retval = 0; - fd = fopen(config_file, "re"); - if (fd == NULL) { - if (errno == ENOENT) { + f = fopen(config_file, "re"); + if (f == NULL) { + if (errno == ENOENT) return 1; - } else { - log_error("can't open %s: %s\n", config_file, strerror(errno)); + else { + log_error("can't open %s: %m", config_file); return -1; } } @@ -196,22 +195,20 @@ static int get_file_options(struct udev *udev, * points into this buffer for its strings). */ buffer = malloc(MAX_BUFFER_LEN); - if (!buffer) { - fclose(fd); + if (!buffer) return log_oom(); - } *newargv = NULL; lineno = 0; while (1) { vendor_in = model_in = options_in = NULL; - buf = fgets(buffer, MAX_BUFFER_LEN, fd); + buf = fgets(buffer, MAX_BUFFER_LEN, f); if (buf == NULL) break; lineno++; if (buf[strlen(buffer) - 1] != '\n') { - log_error("Config file line %d too long\n", lineno); + log_error("Config file line %d too long", lineno); break; } @@ -227,7 +224,7 @@ static int get_file_options(struct udev *udev, continue; str1 = strsep(&buf, "="); - if (str1 && strcasecmp(str1, "VENDOR") == 0) { + if (str1 && strcaseeq(str1, "VENDOR")) { str1 = get_value(&buf); if (!str1) { retval = log_oom(); @@ -236,7 +233,7 @@ static int get_file_options(struct udev *udev, vendor_in = str1; str1 = strsep(&buf, "="); - if (str1 && strcasecmp(str1, "MODEL") == 0) { + if (str1 && strcaseeq(str1, "MODEL")) { str1 = get_value(&buf); if (!str1) { retval = log_oom(); @@ -247,7 +244,7 @@ static int get_file_options(struct udev *udev, } } - if (str1 && strcasecmp(str1, "OPTIONS") == 0) { + if (str1 && strcaseeq(str1, "OPTIONS")) { str1 = get_value(&buf); if (!str1) { retval = log_oom(); @@ -260,17 +257,17 @@ static int get_file_options(struct udev *udev, * Only allow: [vendor=foo[,model=bar]]options=stuff */ if (!options_in || (!vendor_in && model_in)) { - log_error("Error parsing config file line %d '%s'\n", lineno, buffer); + log_error("Error parsing config file line %d '%s'", lineno, buffer); retval = -1; break; } if (vendor == NULL) { if (vendor_in == NULL) break; - } else if ((vendor_in && strncmp(vendor, vendor_in, - strlen(vendor_in)) == 0) && - (!model_in || (strncmp(model, model_in, - strlen(model_in)) == 0))) { + } else if (vendor_in && + strneq(vendor, vendor_in, strlen(vendor_in)) && + (!model_in || + (strneq(model, model_in, strlen(model_in))))) { /* * Matched vendor and optionally model. * @@ -313,12 +310,27 @@ static int get_file_options(struct udev *udev, } if (retval != 0) free(buffer); - fclose(fd); return retval; } +static void help(void) { + printf("Usage: scsi_id [OPTION...] DEVICE\n" + " -d,--device= device node for SG_IO commands\n" + " -f,--config= location of config file\n" + " -p,--page=0x80|0x83|pre-spc3-83 SCSI page (0x80, 0x83, pre-spc3-83)\n" + " -s,--sg-version=3|4 use SGv3 or SGv4\n" + " -b,--blacklisted threat device as blacklisted\n" + " -g,--whitelisted threat device as whitelisted\n" + " -u,--replace-whitespace replace all whitespace by underscores\n" + " -v,--verbose verbose logging\n" + " --version print version\n" + " -x,--export print values as environment keys\n" + " -h,--help print this help text\n\n"); + +} + static int set_options(struct udev *udev, - int argc, char **argv, const char *short_opts, + int argc, char **argv, char *maj_min_dev) { int option; @@ -329,57 +341,38 @@ static int set_options(struct udev *udev, * file) we have to reset this back to 1. */ optind = 1; - while (1) { - option = getopt_long(argc, argv, short_opts, options, NULL); - if (option == -1) - break; - + while ((option = getopt_long(argc, argv, "d:f:gp:uvVxh", options, NULL)) >= 0) switch (option) { case 'b': - all_good = 0; + all_good = false; break; case 'd': - dev_specified = 1; - util_strscpy(maj_min_dev, MAX_PATH_LEN, optarg); - break; - - case 'e': - use_stderr = 1; + dev_specified = true; + strscpy(maj_min_dev, MAX_PATH_LEN, optarg); break; case 'f': - util_strscpy(config_file, MAX_PATH_LEN, optarg); + strscpy(config_file, MAX_PATH_LEN, optarg); break; case 'g': - all_good = 1; + all_good = true; break; case 'h': - printf("Usage: scsi_id OPTIONS \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"); + help(); exit(0); case 'p': - if (strcmp(optarg, "0x80") == 0) { + if (streq(optarg, "0x80")) default_page_code = PAGE_80; - } else if (strcmp(optarg, "0x83") == 0) { + else if (streq(optarg, "0x83")) default_page_code = PAGE_83; - } else if (strcmp(optarg, "pre-spc3-83") == 0) { + else if (streq(optarg, "pre-spc3-83")) default_page_code = PAGE_83_PRE_SPC3; - } else { - log_error("Unknown page code '%s'\n", optarg); + else { + log_error("Unknown page code '%s'", optarg); return -1; } break; @@ -387,17 +380,13 @@ static int set_options(struct udev *udev, case 's': sg_version = atoi(optarg); if (sg_version < 3 || sg_version > 4) { - log_error("Unknown SG version '%s'\n", optarg); + log_error("Unknown SG version '%s'", optarg); return -1; } break; case 'u': - reformat_serial = 1; - break; - - case 'x': - export = 1; + reformat_serial = true; break; case 'v': @@ -407,16 +396,23 @@ static int set_options(struct udev *udev, case 'V': printf("%s\n", VERSION); exit(0); + + case 'x': + export = true; break; + case '?': + return -1; + default: - exit(1); + assert_not_reached("Unknown option"); } - } + if (optind < argc && !dev_specified) { - dev_specified = 1; - util_strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]); + dev_specified = true; + strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]); } + return 0; } @@ -435,7 +431,7 @@ static int per_dev_options(struct udev *udev, optind = 1; /* reset this global extern */ while (retval == 0) { - option = getopt_long(newargc, newargv, dev_short_options, options, NULL); + option = getopt_long(newargc, newargv, "bgp:", options, NULL); if (option == -1) break; @@ -449,20 +445,20 @@ static int per_dev_options(struct udev *udev, break; case 'p': - if (strcmp(optarg, "0x80") == 0) { + if (streq(optarg, "0x80")) { *page_code = PAGE_80; - } else if (strcmp(optarg, "0x83") == 0) { + } else if (streq(optarg, "0x83")) { *page_code = PAGE_83; - } else if (strcmp(optarg, "pre-spc3-83") == 0) { + } else if (streq(optarg, "pre-spc3-83")) { *page_code = PAGE_83_PRE_SPC3; } else { - log_error("Unknown page code '%s'\n", optarg); + log_error("Unknown page code '%s'", optarg); retval = -1; } break; default: - log_error("Unknown or bad option '%c' (0x%x)\n", option, option); + log_error("Unknown or bad option '%c' (0x%x)", option, option); retval = -1; break; } @@ -504,13 +500,11 @@ static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, co */ static int scsi_id(struct udev *udev, char *maj_min_dev) { - struct scsi_id_device dev_scsi; + struct scsi_id_device dev_scsi = {}; int good_dev; int page_code; int retval = 0; - memset(&dev_scsi, 0x00, sizeof(struct scsi_id_device)); - if (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) { retval = 1; goto out; @@ -583,11 +577,11 @@ out: int main(int argc, char **argv) { - struct udev *udev; + _cleanup_udev_unref_ struct udev *udev; int retval = 0; char maj_min_dev[MAX_PATH_LEN]; int newargc; - char **newargv; + char **newargv = NULL; udev = udev_new(); if (udev == NULL) @@ -599,28 +593,28 @@ int main(int argc, char **argv) /* * Get config file options. */ - newargv = NULL; retval = get_file_options(udev, NULL, NULL, &newargc, &newargv); if (retval < 0) { retval = 1; goto exit; } - if (newargv && (retval == 0)) { - if (set_options(udev, newargc, newargv, short_options, maj_min_dev) < 0) { + if (retval == 0) { + assert(newargv); + + if (set_options(udev, newargc, newargv, maj_min_dev) < 0) { retval = 2; goto exit; } - free(newargv); } /* * Get command line options (overriding any config file settings). */ - if (set_options(udev, argc, argv, short_options, maj_min_dev) < 0) + if (set_options(udev, argc, argv, maj_min_dev) < 0) exit(1); if (!dev_specified) { - log_error("no device specified\n"); + log_error("no device specified"); retval = 1; goto exit; } @@ -628,7 +622,10 @@ int main(int argc, char **argv) retval = scsi_id(udev, maj_min_dev); exit: - udev_unref(udev); + if (newargv) { + free(newargv[0]); + free(newargv); + } log_close(); return retval; }