X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=extras%2Fscsi_id%2Fscsi_id.c;h=1b4234a40ea1782c8650b61f41465f6474d25d1f;hp=32a96d8adb7150aaeb88b630dcb76b434ccc571d;hb=46f01c6dc44ba516e42d5c8c1ada98a743f916f2;hpb=4e05e4238b2cb63eb3f3cd51cf76f136fa684f2e diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 32a96d8ad..1b4234a40 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -52,7 +52,7 @@ * options are not supported, but other code is still left in place for * now. */ -static const char short_options[] = "bd:f:gip:s:uvV"; +static const char short_options[] = "abd:f:gip:s:uvVx"; /* * Just duplicate per dev options. */ @@ -61,6 +61,7 @@ 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; @@ -71,6 +72,11 @@ static int use_stderr; static int debug; static int hotplug_mode; 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, ...) { @@ -84,13 +90,8 @@ void log_message (int level, const char *format, ...) vfprintf(stderr, format, args); } else { static int logging_init = 0; - static unsigned char logname[32]; if (!logging_init) { - /* - * klibc does not have LOG_PID. - */ - snprintf(logname, 32, "scsi_id[%d]", getpid()); - openlog (logname, 0, LOG_DAEMON); + openlog ("scsi_id", LOG_PID, LOG_DAEMON); logging_init = 1; } @@ -100,6 +101,77 @@ void log_message (int level, const char *format, ...) return; } +static void set_str(char *to, const unsigned char *from, int count) +{ + int i, j; + int len; + + /* strip trailing whitespace */ + len = strnlen(from, count); + while (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, int count) +{ + int type_num; + char *eptr; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + sprintf(to, "disk"); + break; + case 1: + sprintf(to, "tape"); + break; + case 4: + sprintf(to, "optical"); + break; + case 5: + sprintf(to, "cd"); + break; + case 7: + sprintf(to, "optical"); + break; + case 0xe: + sprintf(to, "disk"); + break; + case 0xf: + sprintf(to, "optical"); + break; + default: + sprintf(to, "generic"); + break; + } + } else { + sprintf(to, "generic"); + } +} + static int get_major_minor(struct sysfs_class_device *class_dev, int *maj, int *min) { @@ -414,6 +486,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; @@ -465,6 +540,10 @@ static int set_options(int argc, char **argv, const char *short_opts, reformat_serial = 1; break; + case 'x': + export = 1; + break; + case 'v': debug++; break; @@ -491,7 +570,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; @@ -507,6 +586,7 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, scsi_dev->name); return -1; } + set_str(vendor_str, vendor->value, sizeof(vendor_str)-1); model = sysfs_get_device_attr(scsi_dev, "model"); if (!model) { @@ -514,6 +594,23 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, scsi_dev->name); return -1; } + 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)-1); + + 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); @@ -584,7 +681,6 @@ static void format_serial(char *serial) *p = '_'; p++; } - return; } /* @@ -718,16 +814,27 @@ 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; } if (!retval) { - if (reformat_serial) - format_serial(serial); - if (display_bus_id) - printf("%s: ", scsi_dev->name); - printf("%s\n", serial); + if (export) { + 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); + if (display_bus_id) + printf("%s: ", scsi_dev->name); + printf("%s\n", serial); + } dprintf("%s\n", serial); retval = 0; }