X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=extras%2Fscsi_id%2Fscsi_id.c;h=aa1b16009e9f989cd301dfe9d78acd16391de767;hb=cbba4a544628b2f5d78cb15dadbc4e0f73f75eb3;hp=86b84bee30e6337e4c04680d75771b98fa3003f9;hpb=34129109a1f5dca72af2f3f2d3d14a9a0d0c43f6;p=elogind.git diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 86b84bee3..aa1b16009 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -44,15 +44,15 @@ /* * temporary names for mknod. */ -#define TMP_DIR "/tmp" -#define TMP_PREFIX "scsi" +#define TMP_DIR "/dev" +#define TMP_PREFIX "tmp-scsi" /* * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout) * options are not supported, but other code is still left in place for * now. */ -static const char short_options[] = "bd:f:gip:s:uvVx"; +static const char short_options[] = "abd:f:gip:s:uvVx"; /* * Just duplicate per dev options. */ @@ -61,12 +61,13 @@ static const char dev_short_options[] = "bgp:"; char sysfs_mnt_path[SYSFS_PATH_MAX]; static int all_good; +static int always_info; static char *default_callout; static int dev_specified; static int sys_specified; static char config_file[MAX_NAME_LEN] = SCSI_ID_CONFIG_FILE; static int display_bus_id; -static int default_page_code; +static enum page_code default_page_code; static int use_stderr; static int debug; static int hotplug_mode; @@ -74,6 +75,8 @@ static int reformat_serial; static int export; static char vendor_str[64]; static char model_str[64]; +static char revision_str[16]; +static char type_str[16]; void log_message (int level, const char *format, ...) { @@ -98,32 +101,74 @@ void log_message (int level, const char *format, ...) return; } -static void set_str(char *to, const unsigned char *from, int count) +static void set_str(char *to, const char *from, size_t count) { - int i, j; - int len; + size_t i, j, len; + /* strip trailing whitespace */ len = strnlen(from, count); - while (isspace(from[len-1])) + while (len && isspace(from[len-1])) len--; + /* strip leading whitespace */ i = 0; while (isspace(from[i]) && (i < len)) i++; j = 0; while (i < len) { - switch(from[i]) { - case '/': - case ' ': + /* 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) +{ + int type_num; + char *eptr; + char *type = "generic"; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + type = "disk"; + break; + case 1: + type = "tape"; + break; + case 4: + type = "optical"; + break; + case 5: + type = "cd"; + break; + case 7: + type = "optical"; + break; + case 0xe: + type = "disk"; + break; + case 0xf: + type = "optical"; break; default: - to[j++] = from[i]; + break; } - i++; } - to[j] = '\0'; + strncpy(to, type, len); + to[len-1] = '\0'; } static int get_major_minor(struct sysfs_class_device *class_dev, int *maj, @@ -430,7 +475,7 @@ static int set_options(int argc, char **argv, const char *short_opts, */ optind = 1; while (1) { - option = getopt(argc, argv, short_options); + option = getopt(argc, argv, short_opts); if (option == -1) break; @@ -440,6 +485,9 @@ static int set_options(int argc, char **argv, const char *short_opts, dprintf("option '%c'\n", option); switch (option) { + case 'a': + always_info = 1; + break; case 'b': all_good = 0; break; @@ -471,9 +519,11 @@ static int set_options(int argc, char **argv, const char *short_opts, case 'p': if (strcmp(optarg, "0x80") == 0) { - default_page_code = 0x80; + default_page_code = PAGE_80; } else if (strcmp(optarg, "0x83") == 0) { - default_page_code = 0x83; + default_page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + default_page_code = PAGE_83_PRE_SPC3; } else { log_message(LOG_WARNING, "Unknown page code '%s'\n", optarg); @@ -521,7 +571,7 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, int retval; int newargc; char **newargv = NULL; - struct sysfs_attribute *vendor, *model; + struct sysfs_attribute *vendor, *model, *type; int option; *good_bad = all_good; @@ -547,6 +597,22 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, } set_str(model_str, model->value, sizeof(model_str)-1); + type = sysfs_get_device_attr(scsi_dev, "type"); + if (!type) { + log_message(LOG_WARNING, "%s: cannot get type attribute\n", + scsi_dev->name); + return -1; + } + set_type(type_str, type->value, sizeof(type_str)); + + type = sysfs_get_device_attr(scsi_dev, "rev"); + if (!type) { + log_message(LOG_WARNING, "%s: cannot get type attribute\n", + scsi_dev->name); + return -1; + } + set_str(revision_str, type->value, sizeof(revision_str)-1); + retval = get_file_options(vendor->value, model->value, &newargc, &newargv); @@ -576,9 +642,11 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, case 'p': if (strcmp(optarg, "0x80") == 0) { - *page_code = 0x80; + *page_code = PAGE_80; } else if (strcmp(optarg, "0x83") == 0) { - *page_code = 0x83; + *page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + *page_code = PAGE_83_PRE_SPC3; } else { log_message(LOG_WARNING, "Unknown page code '%s'\n", optarg); @@ -609,14 +677,22 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, */ static void format_serial(char *serial) { - char *p = serial; + char *p = serial, *q; + q = p; while (*p != '\0') { - if (isspace(*p)) - *p = '_'; + if (isspace(*p)) { + if (q > serial && q[-1] != '_') { + *q = '_'; + q++; + } + } else { + *q = *p; + q++; + } p++; } -return; + *q = '\0'; } /* @@ -750,7 +826,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) retval = 1; } else if (scsi_get_serial(scsi_dev, maj_min_dev, page_code, serial, MAX_SERIAL_LEN)) { - retval = 1; + retval = always_info?0:1; } else { retval = 0; } @@ -759,8 +835,11 @@ static int scsi_id(const char *target_path, char *maj_min_dev) static char serial_str[64]; 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, serial, sizeof(serial_str)); printf("ID_SERIAL=%s\n", serial_str); + printf("ID_TYPE=%s\n", type_str); + printf("ID_BUS=scsi\n"); } else { if (reformat_serial) format_serial(serial);