X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=extras%2Fusb_id%2Fusb_id.c;h=b412598d35a8ea56749f3a27dcbeeede1aa29259;hp=489f97e5376da9a9953dc91c73be4d6e9b1165f1;hb=1230d021bd75de9b1503bbaa807d6a59789963db;hpb=7e827bcde81cc702f232a53d84506cf065274ded diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index 489f97e53..b412598d3 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -21,7 +21,8 @@ #include #include -#include "../../udev/udev.h" +#include "libudev.h" +#include "libudev-private.h" int debug; @@ -38,14 +39,18 @@ static void log_fn(struct udev *udev, int priority, } static char vendor_str[64]; +static char vendor_str_enc[256]; +static const char *vendor_id = ""; static char model_str[64]; static char model_str_enc[256]; -static char vendor_str_enc[256]; +static const char *product_id = ""; static char serial_str[UTIL_NAME_SIZE]; static char packed_if_str[UTIL_NAME_SIZE]; static char revision_str[64]; static char type_str[64]; static char instance_str[64]; +static const char *ifnum; +static const char *driver; static int use_usb_info; static int use_num_info; @@ -130,7 +135,7 @@ static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len break; } } - util_strlcpy(to, type, len); + util_strscpy(to, len, type); return type_num; } @@ -162,7 +167,7 @@ static void set_scsi_type(char *to, const char *from, size_t len) break; } } - util_strlcpy(to, type, len); + util_strscpy(to, len, type); } #define USB_DT_DEVICE 0x01 @@ -186,7 +191,7 @@ 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; + int err = 0; if (asprintf(&filename, "%s/descriptors", udev_device_get_syspath(dev)) < 0) { err = -1; @@ -233,14 +238,13 @@ static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len } out: free(filename); - return 0; + return err; } /* * A unique USB identification is generated like this: * - * 1.) Get the USB device type from DeviceClass, InterfaceClass - * and InterfaceSubClass + * 1.) Get the USB device type from InterfaceClass and InterfaceSubClass * 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 @@ -257,14 +261,21 @@ out: static int usb_id(struct udev_device *dev) { struct udev *udev = udev_device_get_udev(dev); - struct udev_device *dev_interface; - struct udev_device *dev_usb; + struct udev_device *dev_interface = NULL; + struct udev_device *dev_usb = NULL; const char *if_class, *if_subclass; int if_class_num; int protocol = 0; dbg(udev, "syspath %s\n", udev_device_get_syspath(dev)); + /* 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) { + dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str)); + dev_usb = dev; + goto fallback; + } + /* usb interface directory */ dev_interface = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); if (dev_interface == NULL) { @@ -273,6 +284,9 @@ static int usb_id(struct udev_device *dev) return 1; } + ifnum = udev_device_get_sysattr_value(dev_interface, "bInterfaceNumber"); + driver = udev_device_get_sysattr_value(dev_interface, "driver"); + if_class = udev_device_get_sysattr_value(dev_interface, "bInterfaceClass"); if (!if_class) { info(udev, "%s: cannot get bInterfaceClass attribute\n", @@ -368,6 +382,9 @@ static int usb_id(struct udev_device *dev) } fallback: + vendor_id = udev_device_get_sysattr_value(dev_usb, "idVendor"); + product_id = udev_device_get_sysattr_value(dev_usb, "idProduct"); + /* fallback to USB vendor & device */ if (vendor_str[0] == '\0') { const char *usb_vendor = NULL; @@ -376,7 +393,7 @@ fallback: usb_vendor = udev_device_get_sysattr_value(dev_usb, "manufacturer"); if (!usb_vendor) - usb_vendor = udev_device_get_sysattr_value(dev_usb, "idVendor"); + usb_vendor = vendor_id; if (!usb_vendor) { info(udev, "No USB vendor information available\n"); @@ -394,7 +411,7 @@ fallback: usb_model = udev_device_get_sysattr_value(dev_usb, "product"); if (!usb_model) - usb_model = udev_device_get_sysattr_value(dev_usb, "idProduct"); + usb_model = product_id; if (!usb_model) { dbg(udev, "No USB model information available\n"); @@ -448,7 +465,7 @@ int main(int argc, char **argv) if (udev == NULL) goto exit; - logging_init("usb_id"); + udev_log_init("usb_id"); udev_set_log_fn(udev, log_fn); while (1) { @@ -493,8 +510,7 @@ int main(int argc, char **argv) goto exit; } - util_strlcpy(syspath, udev_get_sys_path(udev), sizeof(syspath)); - util_strlcat(syspath, devpath, sizeof(syspath)); + util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), devpath, NULL); dev = udev_device_new_from_syspath(udev, syspath); if (dev == NULL) { err(udev, "unable to access '%s'\n", devpath); @@ -504,34 +520,38 @@ int main(int argc, char **argv) retval = usb_id(dev); if (retval == 0) { char serial[256]; + size_t l; + char *s; - util_strlcpy(serial, vendor_str, sizeof(serial)); - util_strlcat(serial, "_", sizeof(serial)); - util_strlcat(serial, model_str, sizeof(serial)); - if (serial_str[0] != '\0') { - util_strlcat(serial, "_", sizeof(serial)); - util_strlcat(serial, serial_str, sizeof(serial)); - } - if (instance_str[0] != '\0') { - util_strlcat(serial, "-", sizeof(serial)); - util_strlcat(serial, instance_str, sizeof(serial)); - } + s = serial; + l = util_strpcpyl(&s, sizeof(serial), vendor_str, "_", model_str, NULL); + if (serial_str[0] != '\0') + l = util_strpcpyl(&s, l, "_", serial_str, NULL); + if (instance_str[0] != '\0') + util_strpcpyl(&s, l, "-", instance_str, NULL); if (export) { printf("ID_VENDOR=%s\n", vendor_str); printf("ID_VENDOR_ENC=%s\n", vendor_str_enc); + printf("ID_VENDOR_ID=%s\n", vendor_id); printf("ID_MODEL=%s\n", model_str); printf("ID_MODEL_ENC=%s\n", model_str_enc); + printf("ID_MODEL_ID=%s\n", product_id); printf("ID_REVISION=%s\n", revision_str); printf("ID_SERIAL=%s\n", serial); if (serial_str[0] != '\0') printf("ID_SERIAL_SHORT=%s\n", serial_str); - printf("ID_TYPE=%s\n", type_str); + if (type_str[0] != '\0') + printf("ID_TYPE=%s\n", type_str); if (instance_str[0] != '\0') printf("ID_INSTANCE=%s\n", instance_str); printf("ID_BUS=usb\n"); if (packed_if_str[0] != '\0') printf("ID_USB_INTERFACES=:%s\n", packed_if_str); + if (ifnum != NULL) + printf("ID_USB_INTERFACE_NUM=%s\n", ifnum); + if (driver != NULL) + printf("ID_USB_DRIVER=%s\n", driver); } else printf("%s\n", serial); } @@ -539,6 +559,6 @@ int main(int argc, char **argv) exit: udev_device_unref(dev); udev_unref(udev); - logging_close(); + udev_log_close(); return retval; }