X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=extras%2Fscsi_id%2Fscsi_id.c;h=6c8826568f38de953122c7bbb065997c30dc5439;hb=0c0b3f97cad4c34140dda3aa85a9bc74badb4b16;hp=bf06ed2794abd233a8fe2af4fecdd8391e4a54e9;hpb=38f27948cdafd8a4b90a6b4f1f54b89891983506;p=elogind.git diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index bf06ed279..6c8826568 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -1,17 +1,19 @@ /* - * scsi_id.c - * - * Main section of the scsi_id program - * * Copyright (C) IBM Corp. 2003 * Copyright (C) SUSE Linux Products GmbH, 2006 * - * Author: - * Patrick Mansfield + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation version 2 of the License. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include @@ -27,21 +29,22 @@ #include #include -#include "../../udev/udev.h" +#include "libudev.h" +#include "libudev-private.h" #include "scsi_id.h" static const struct option options[] = { - { "device", 1, NULL, 'd' }, - { "config", 1, NULL, 'f' }, - { "page", 1, NULL, 'p' }, - { "blacklisted", 0, NULL, 'b' }, - { "whitelisted", 0, NULL, 'g' }, - { "replace-whitespace", 0, NULL, 'u' }, - { "sg-version", 1, NULL, 's' }, - { "verbose", 0, NULL, 'v' }, - { "version", 0, NULL, 'V' }, - { "export", 0, NULL, 'x' }, - { "help", 0, 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' }, + { "export", no_argument, NULL, 'x' }, + { "help", no_argument, NULL, 'h' }, {} }; @@ -59,6 +62,8 @@ static int reformat_serial; static int export; static char vendor_str[64]; static char model_str[64]; +static char vendor_enc_str[256]; +static char model_enc_str[256]; static char revision_str[16]; static char type_str[16]; @@ -69,39 +74,7 @@ static void log_fn(struct udev *udev, int priority, vsyslog(priority, format, args); } -static void set_str(char *to, const char *from, size_t count) -{ - size_t i, j, len; - - /* strip trailing whitespace */ - len = strnlen(from, count); - while (len && isspace(from[len-1])) - len--; - - /* strip leading whitespace */ - i = 0; - while (isspace(from[i]) && (i < len)) - i++; - - j = 0; - while (i < len) { - /* substitute multiple whitespace */ - if (isspace(from[i])) { - while (isspace(from[i])) - i++; - to[j++] = '_'; - } - /* skip chars */ - if (from[i] == '/') { - i++; - continue; - } - to[j++] = from[i++]; - } - to[j] = '\0'; -} - -static void set_type(char *to, const char *from, size_t len) +static void set_type(const char *from, char *to, size_t len) { int type_num; char *eptr; @@ -135,8 +108,7 @@ static void set_type(char *to, const char *from, size_t len) break; } } - strncpy(to, type, len); - to[len-1] = '\0'; + util_strscpy(to, len, type); } /* @@ -256,7 +228,7 @@ static int get_file_options(struct udev *udev, if (*buf == '#') continue; - dbg("lineno %d: '%s'\n", lineno, buf); + dbg(udev, "lineno %d: '%s'\n", lineno, buf); str1 = strsep(&buf, "="); if (str1 && strcasecmp(str1, "VENDOR") == 0) { str1 = get_value(&buf); @@ -286,7 +258,7 @@ static int get_file_options(struct udev *udev, } options_in = str1; } - dbg("config file line %d:\n" + dbg(udev, "config file line %d:\n" " vendor '%s'; model '%s'; options '%s'\n", lineno, vendor_in, model_in, options_in); /* @@ -299,7 +271,7 @@ static int get_file_options(struct udev *udev, } if (vendor == NULL) { if (vendor_in == NULL) { - dbg("matched global option\n"); + dbg(udev, "matched global option\n"); break; } } else if ((vendor_in && strncmp(vendor, vendor_in, @@ -313,10 +285,10 @@ static int get_file_options(struct udev *udev, * give a partial match (that is FOO * matches FOOBAR). */ - dbg("matched vendor/model\n"); + dbg(udev, "matched vendor/model\n"); break; } else { - dbg("no match\n"); + dbg(udev, "no match\n"); } } @@ -385,8 +357,7 @@ static int set_options(struct udev *udev, case 'd': dev_specified = 1; - strncpy(maj_min_dev, optarg, MAX_PATH_LEN); - maj_min_dev[MAX_PATH_LEN-1] = '\0'; + util_strscpy(maj_min_dev, MAX_PATH_LEN, optarg); break; case 'e': @@ -394,8 +365,7 @@ static int set_options(struct udev *udev, break; case 'f': - strncpy(config_file, optarg, MAX_PATH_LEN); - config_file[MAX_PATH_LEN-1] = '\0'; + util_strscpy(config_file, MAX_PATH_LEN, optarg); break; case 'g': @@ -461,8 +431,7 @@ static int set_options(struct udev *udev, } if (optind < argc && !dev_specified) { dev_specified = 1; - strncpy(maj_min_dev, argv[optind], MAX_PATH_LEN); - maj_min_dev[MAX_PATH_LEN-1] = '\0'; + util_strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]); } return 0; } @@ -537,90 +506,100 @@ static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, co if (retval) return retval; - 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)); + udev_util_encode_string(dev_scsi->vendor, vendor_enc_str, sizeof(vendor_enc_str)); + udev_util_encode_string(dev_scsi->model, model_enc_str, sizeof(model_enc_str)); + udev_util_replace_whitespace(dev_scsi->vendor, vendor_str, sizeof(vendor_str)); + udev_util_replace_chars(vendor_str, NULL); + udev_util_replace_whitespace(dev_scsi->model, model_str, sizeof(model_str)); + udev_util_replace_chars(model_str, NULL); + set_type(dev_scsi->type, type_str, sizeof(type_str)); + udev_util_replace_whitespace(dev_scsi->revision, revision_str, sizeof(revision_str)); + udev_util_replace_chars(revision_str, NULL); return 0; } -/* - * format_serial: replace to whitespaces by underscores for calling - * programs that use the serial for device naming (multipath, Suse - * naming, etc...) - */ -static void format_serial(char *serial) -{ - char *p = serial, *q; - - q = p; - while (*p != '\0') { - if (isspace(*p)) { - if (q > serial && q[-1] != '_') { - *q = '_'; - q++; - } - } else { - *q = *p; - q++; - } - p++; - } - *q = '\0'; -} - /* * scsi_id: try to get an id, if one is found, printf it to stdout. - * returns a value passed to exit() - 0 if printed an id, else 1. This - * could be expanded, for example, if we want to report a failure like no - * memory etc. return 2, and return 1 for expected cases (like broken - * device found) that do not print an id. + * returns a value passed to exit() - 0 if printed an id, else 1. */ static int scsi_id(struct udev *udev, char *maj_min_dev) { - int retval; struct scsi_id_device dev_scsi; int good_dev; int page_code; - char serial_short[MAX_SERIAL_LEN] = ""; + int retval = 0; - set_inq_values(udev, &dev_scsi, maj_min_dev); + memset(&dev_scsi, 0x00, sizeof(struct scsi_id_device)); - /* get per device (vendor + model) options from the config file */ - 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 (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) { + retval = 1; + goto out; + } + /* get per device (vendor + model) options from the config file */ + per_dev_options(udev, &dev_scsi, &good_dev, &page_code); + dbg(udev, "per dev options: good %d; page code 0x%x\n", good_dev, page_code); if (!good_dev) { retval = 1; - } else if (scsi_get_serial(udev, - &dev_scsi, maj_min_dev, page_code, - serial_short, MAX_SERIAL_LEN)) { - retval = 1; - } else { - retval = 0; + goto out; } - if (!retval) { - if (export) { - char serial_str[MAX_SERIAL_LEN]; - - printf("ID_VENDOR=%s\n", vendor_str); - printf("ID_MODEL=%s\n", model_str); - printf("ID_REVISION=%s\n", revision_str); - set_str(serial_str, dev_scsi.serial, sizeof(serial_str)); + + /* read serial number from mode pages (no values for optical drives) */ + scsi_get_serial(udev, &dev_scsi, maj_min_dev, page_code, MAX_SERIAL_LEN); + + if (export) { + char serial_str[MAX_SERIAL_LEN]; + + printf("ID_SCSI=1\n"); + printf("ID_VENDOR=%s\n", vendor_str); + printf("ID_VENDOR_ENC=%s\n", vendor_enc_str); + printf("ID_MODEL=%s\n", model_str); + printf("ID_MODEL_ENC=%s\n", model_enc_str); + printf("ID_REVISION=%s\n", revision_str); + printf("ID_TYPE=%s\n", type_str); + if (dev_scsi.serial[0] != '\0') { + udev_util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)); + udev_util_replace_chars(serial_str, NULL); printf("ID_SERIAL=%s\n", serial_str); - set_str(serial_str, serial_short, sizeof(serial_str)); + udev_util_replace_whitespace(dev_scsi.serial_short, serial_str, sizeof(serial_str)); + udev_util_replace_chars(serial_str, NULL); printf("ID_SERIAL_SHORT=%s\n", serial_str); - printf("ID_TYPE=%s\n", type_str); - } else { - if (reformat_serial) - format_serial(dev_scsi.serial); - printf("%s\n", dev_scsi.serial); } - dbg("%s\n", dev_scsi.serial); - retval = 0; + if (dev_scsi.wwn[0] != '\0') { + printf("ID_WWN=0x%s\n", dev_scsi.wwn); + if (dev_scsi.wwn_vendor_extension[0] != '\0') { + printf("ID_WWN_VENDOR_EXTENSION=0x%s\n", dev_scsi.wwn_vendor_extension); + printf("ID_WWN_WITH_EXTENSION=0x%s%s\n", dev_scsi.wwn, dev_scsi.wwn_vendor_extension); + } else { + printf("ID_WWN_WITH_EXTENSION=0x%s\n", dev_scsi.wwn); + } + } + if (dev_scsi.tgpt_group[0] != '\0') { + printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group); + } + if (dev_scsi.unit_serial_number[0] != '\0') { + printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number); + } + goto out; + } + + if (dev_scsi.serial[0] == '\0') { + retval = 1; + goto out; + } + + if (reformat_serial) { + char serial_str[MAX_SERIAL_LEN]; + + udev_util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str)); + udev_util_replace_chars(serial_str, NULL); + printf("%s\n", serial_str); + goto out; } + printf("%s\n", dev_scsi.serial); +out: return retval; } @@ -636,7 +615,7 @@ int main(int argc, char **argv) if (udev == NULL) goto exit; - logging_init("scsi_id"); + udev_log_init("scsi_id"); udev_set_log_fn(udev, log_fn); /* @@ -672,6 +651,6 @@ int main(int argc, char **argv) exit: udev_unref(udev); - logging_close(); + udev_log_close(); return retval; }