X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fudev-builtin-usb_id.c;h=06d4191584c48096d5a6b07c680217de42c36164;hb=73ae2b7dade339c8a258dcf4fa2b302e238117e1;hp=6481b35ae79ffc968003eccef17df88f74daf5c7;hpb=baa30fbc2c04b23209d0b8fb3c86cd15ef9ea81a;p=elogind.git diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c index 6481b35ae..06d419158 100644 --- a/src/udev/udev-builtin-usb_id.c +++ b/src/udev/udev-builtin-usb_id.c @@ -4,7 +4,7 @@ * Copyright (c) 2005 SUSE Linux Products GmbH, Germany * Author: Hannes Reinecke * - * Copyright (C) 2005-2011 Kay Sievers + * Copyright (C) 2005-2011 Kay Sievers * * 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 @@ -31,9 +31,8 @@ #include "udev.h" -static void set_usb_iftype(char *to, int if_class_num, size_t len) -{ - char *type = "generic"; +static void set_usb_iftype(char *to, int if_class_num, size_t len) { + const char *type = "generic"; switch (if_class_num) { case 1: @@ -82,15 +81,17 @@ static void set_usb_iftype(char *to, int if_class_num, size_t len) to[len-1] = '\0'; } -static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) -{ +static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) { int type_num = 0; char *eptr; - char *type = "generic"; + const char *type = "generic"; type_num = strtoul(from, &eptr, 0); if (eptr != from) { switch (type_num) { + case 1: /* RBC devices */ + type = "rbc"; + break; case 2: type = "atapi"; break; @@ -98,12 +99,8 @@ static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len type = "tape"; break; case 4: /* UFI */ - case 5: /* SFF-8070i */ type = "floppy"; break; - case 1: /* RBC devices */ - type = "rbc"; - break; case 6: /* Transparent SPC-2 devices */ type = "scsi"; break; @@ -111,15 +108,14 @@ static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len break; } } - util_strscpy(to, len, type); + strscpy(to, len, type); return type_num; } -static void set_scsi_type(char *to, const char *from, size_t len) -{ +static void set_scsi_type(char *to, const char *from, size_t len) { int type_num; char *eptr; - char *type = "generic"; + const char *type = "generic"; type_num = strtoul(from, &eptr, 0); if (eptr != from) { @@ -143,19 +139,19 @@ static void set_scsi_type(char *to, const char *from, size_t len) break; } } - util_strscpy(to, len, type); + strscpy(to, len, type); } #define USB_DT_DEVICE 0x01 #define USB_DT_INTERFACE 0x04 -static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len) -{ - char *filename = NULL; - int fd; +static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len) { + _cleanup_free_ char *filename = NULL; + _cleanup_close_ int fd = -1; ssize_t size; unsigned char buf[18 + 65535]; - unsigned int pos, strpos; + int pos = 0; + unsigned strpos = 0; struct usb_interface_descriptor { u_int8_t bLength; u_int8_t bDescriptorType; @@ -167,29 +163,22 @@ static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len u_int8_t bInterfaceProtocol; u_int8_t iInterface; } __attribute__((packed)); - int err = 0; - if (asprintf(&filename, "%s/descriptors", udev_device_get_syspath(dev)) < 0) { - err = -1; - goto out; - } + if (asprintf(&filename, "%s/descriptors", udev_device_get_syspath(dev)) < 0) + return log_oom(); + fd = open(filename, O_RDONLY|O_CLOEXEC); if (fd < 0) { fprintf(stderr, "error opening USB device 'descriptors' file\n"); - err = -1; - goto out; + return -errno; } + size = read(fd, buf, sizeof(buf)); - close(fd); - if (size < 18 || size == sizeof(buf)) { - err = -1; - goto out; - } + if (size < 18 || size == sizeof(buf)) + return -EIO; - pos = 0; - strpos = 0; ifs_str[0] = '\0'; - while (pos < sizeof(buf) && strpos+7 < len-2) { + while (pos < size && strpos+7 < len-2) { struct usb_interface_descriptor *desc; char if_str[8]; @@ -213,22 +202,22 @@ static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len memcpy(&ifs_str[strpos], if_str, 8), strpos += 7; } + if (strpos > 0) { ifs_str[strpos++] = ':'; ifs_str[strpos++] = '\0'; } -out: - free(filename); - return err; + + return 0; } /* * A unique USB identification is generated like this: * * 1.) Get the USB device type from InterfaceClass and InterfaceSubClass - * 2.) If the device type is 'Mass-Storage/SPC-2' or 'Mass-Storage/RBC' + * 2.) If the device type is 'Mass-Storage/SPC-2' or 'Mass-Storage/RBC', * use the SCSI vendor and model as USB-Vendor and USB-model. - * 3.) Otherwise use the USB manufacturer and product as + * 3.) Otherwise, use the USB manufacturer and product as * USB-Vendor and USB-model. Any non-printable characters * in those strings will be skipped; a slash '/' will be converted * into a full stop '.'. @@ -239,8 +228,7 @@ out: * 6.) If the device supplies a serial number, this number * is concatenated with the identification with an underscore '_'. */ -static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test) -{ +static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test) { char vendor_str[64]; char vendor_str_enc[256]; const char *vendor_id; @@ -256,7 +244,6 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool const char *driver = NULL; char serial[256]; - struct udev *udev = udev_device_get_udev(dev); struct udev_device *dev_interface = NULL; struct udev_device *dev_usb = NULL; const char *if_class, *if_subclass; @@ -274,7 +261,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool instance_str[0] = '\0'; /* shortcut, if we are called directly for a "usb_device" type */ - if (udev_device_get_devtype(dev) != NULL && strcmp(udev_device_get_devtype(dev), "usb_device") == 0) { + if (udev_device_get_devtype(dev) != NULL && streq(udev_device_get_devtype(dev), "usb_device")) { dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str)); dev_usb = dev; goto fallback; @@ -283,7 +270,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool /* usb interface directory */ dev_interface = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); if (dev_interface == NULL) { - log_debug("unable to access usb_interface device of '%s'\n", + log_debug("unable to access usb_interface device of '%s'", udev_device_get_syspath(dev)); return EXIT_FAILURE; } @@ -293,7 +280,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool if_class = udev_device_get_sysattr_value(dev_interface, "bInterfaceClass"); if (!if_class) { - log_debug("%s: cannot get bInterfaceClass attribute\n", + log_debug("%s: cannot get bInterfaceClass attribute", udev_device_get_sysname(dev)); return EXIT_FAILURE; } @@ -308,13 +295,13 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1); } - log_debug("%s: if_class %d protocol %d\n", + log_debug("%s: if_class %d protocol %d", udev_device_get_syspath(dev_interface), if_class_num, protocol); /* usb device directory */ dev_usb = udev_device_get_parent_with_subsystem_devtype(dev_interface, "usb", "usb_device"); if (!dev_usb) { - log_debug("unable to find parent 'usb' device of '%s'\n", + log_debug("unable to find parent 'usb' device of '%s'", udev_device_get_syspath(dev)); return EXIT_FAILURE; } @@ -331,19 +318,19 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool /* get scsi device */ dev_scsi = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device"); if (dev_scsi == NULL) { - log_debug("unable to find parent 'scsi' device of '%s'\n", + log_debug("unable to find parent 'scsi' device of '%s'", udev_device_get_syspath(dev)); goto fallback; } if (sscanf(udev_device_get_sysname(dev_scsi), "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) { - log_debug("invalid scsi device '%s'\n", udev_device_get_sysname(dev_scsi)); + log_debug("invalid scsi device '%s'", udev_device_get_sysname(dev_scsi)); goto fallback; } /* Generic SPC-2 device */ scsi_vendor = udev_device_get_sysattr_value(dev_scsi, "vendor"); if (!scsi_vendor) { - log_debug("%s: cannot get SCSI vendor attribute\n", + log_debug("%s: cannot get SCSI vendor attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -353,7 +340,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool scsi_model = udev_device_get_sysattr_value(dev_scsi, "model"); if (!scsi_model) { - log_debug("%s: cannot get SCSI model attribute\n", + log_debug("%s: cannot get SCSI model attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -363,7 +350,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool scsi_type = udev_device_get_sysattr_value(dev_scsi, "type"); if (!scsi_type) { - log_debug("%s: cannot get SCSI type attribute\n", + log_debug("%s: cannot get SCSI type attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -371,7 +358,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool scsi_rev = udev_device_get_sysattr_value(dev_scsi, "rev"); if (!scsi_rev) { - log_debug("%s: cannot get SCSI revision attribute\n", + log_debug("%s: cannot get SCSI revision attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -397,7 +384,7 @@ fallback: if (!usb_vendor) usb_vendor = vendor_id; if (!usb_vendor) { - log_debug("No USB vendor information available\n"); + log_debug("No USB vendor information available"); return EXIT_FAILURE; } udev_util_encode_string(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc)); @@ -432,6 +419,17 @@ fallback: const char *usb_serial; usb_serial = udev_device_get_sysattr_value(dev_usb, "serial"); + if (usb_serial) { + const unsigned char *p; + + /* http://msdn.microsoft.com/en-us/library/windows/hardware/gg487321.aspx */ + for (p = (unsigned char *)usb_serial; *p != '\0'; p++) + if (*p < 0x20 || *p > 0x7f || *p == ',') { + usb_serial = NULL; + break; + } + } + if (usb_serial) { util_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1); util_replace_chars(serial_str, NULL); @@ -439,12 +437,12 @@ fallback: } s = serial; - l = util_strpcpyl(&s, sizeof(serial), vendor_str, "_", model_str, NULL); + l = strpcpyl(&s, sizeof(serial), vendor_str, "_", model_str, NULL); if (serial_str[0] != '\0') - l = util_strpcpyl(&s, l, "_", serial_str, NULL); + l = strpcpyl(&s, l, "_", serial_str, NULL); if (instance_str[0] != '\0') - util_strpcpyl(&s, l, "-", instance_str, NULL); + strpcpyl(&s, l, "-", instance_str, NULL); udev_builtin_add_property(dev, test, "ID_VENDOR", vendor_str); udev_builtin_add_property(dev, test, "ID_VENDOR_ENC", vendor_str_enc);