diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2013-09-03 15:46:39 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2013-09-03 15:46:39 +0000 |
commit | e01fb70f1bd277c9e05046579e43edef325dffa8 (patch) | |
tree | ea8b50c8b1e43f30a328f409a95ef7f2bb9cda65 /package/utils/usbreset | |
parent | 07216b9f466dcfa097b4249720b70ba45968d633 (diff) | |
download | upstream-e01fb70f1bd277c9e05046579e43edef325dffa8.tar.gz upstream-e01fb70f1bd277c9e05046579e43edef325dffa8.tar.bz2 upstream-e01fb70f1bd277c9e05046579e43edef325dffa8.zip |
usbreset: rewrite to not rely on /proc/bus/usb anymore
SVN-Revision: 37893
Diffstat (limited to 'package/utils/usbreset')
-rw-r--r-- | package/utils/usbreset/Makefile | 4 | ||||
-rw-r--r-- | package/utils/usbreset/src/usbreset.c | 118 |
2 files changed, 52 insertions, 70 deletions
diff --git a/package/utils/usbreset/Makefile b/package/utils/usbreset/Makefile index 75bfd85138..55ce21ef52 100644 --- a/package/utils/usbreset/Makefile +++ b/package/utils/usbreset/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2011-2012 OpenWrt.org +# Copyright (C) 2011-2013 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=usbreset -PKG_RELEASE:=2 +PKG_RELEASE:=3 include $(INCLUDE_DIR)/package.mk diff --git a/package/utils/usbreset/src/usbreset.c b/package/utils/usbreset/src/usbreset.c index 087a14cfa4..f6f2ba288a 100644 --- a/package/utils/usbreset/src/usbreset.c +++ b/package/utils/usbreset/src/usbreset.c @@ -42,7 +42,11 @@ Alan Stern #include <fcntl.h> #include <errno.h> #include <string.h> +#include <ctype.h> +#include <limits.h> +#include <dirent.h> #include <sys/ioctl.h> +#include <sys/types.h> #include <linux/usbdevice_fs.h> @@ -59,86 +63,70 @@ struct usbentry { }; -static bool find_usbfs(void) +static char *sysfs_attr(const char *dev, const char *attr) { - FILE *mtab; + int fd, len; + char path[PATH_MAX]; + static char buf[129]; - char buf[1024], type[32]; - static char path[1024]; + memset(buf, 0, sizeof(buf)); + snprintf(path, sizeof(path) - 1, "/sys/bus/usb/devices/%s/%s", dev, attr); - if ((mtab = fopen("/proc/mounts", "r")) != NULL) + if ((fd = open(path, O_RDONLY)) >= 0) { - while (fgets(buf, sizeof(buf), mtab)) - { - if (sscanf(buf, "%*s %1023s %31s ", path, type) == 2 && - !strncmp(type, "usbfs", 5)) - { - usbfs = path; - break; - } - } - - fclose(mtab); + len = read(fd, buf, sizeof(buf) - 1); + close(fd); } - return !!usbfs; -} + while (--len > 0 && isspace(buf[len])) + buf[len] = 0; -static FILE * open_devlist(void) -{ - char buf[1024]; - snprintf(buf, sizeof(buf), "%s/devices", usbfs); - return fopen(buf, "r"); + return (len >= 0) ? buf : NULL; } -static void close_devlist(FILE *devs) +static struct usbentry * parse_devlist(DIR *d) { - fclose(devs); -} - -static struct usbentry * parse_devlist(FILE *devs) -{ - char buf[1024]; + char *attr; + struct dirent *e; static struct usbentry dev; + do { + e = readdir(d); + + if (!e) + return NULL; + } + while(!isdigit(e->d_name[0]) || strchr(e->d_name, ':')); + memset(&dev, 0, sizeof(dev)); - while (fgets(buf, sizeof(buf), devs)) - { - buf[strlen(buf)-1] = 0; + if ((attr = sysfs_attr(e->d_name, "busnum")) != NULL) + dev.bus_num = strtoul(attr, NULL, 10); - switch (buf[0]) - { - case 'T': - sscanf(buf, "T: Bus=%d Lev=%*d Prnt=%*d Port=%*d Cnt=%*d Dev#=%d", - &dev.bus_num, &dev.dev_num); - break; + if ((attr = sysfs_attr(e->d_name, "devnum")) != NULL) + dev.dev_num = strtoul(attr, NULL, 10); - case 'P': - sscanf(buf, "P: Vendor=%x ProdID=%x", - &dev.vendor_id, &dev.product_id); - break; + if ((attr = sysfs_attr(e->d_name, "idVendor")) != NULL) + dev.vendor_id = strtoul(attr, NULL, 16); - case 'S': - if (!strncmp(buf, "S: Manufacturer=", 17)) - snprintf(dev.vendor_name, sizeof(dev.vendor_name), - "%s", buf+17); - else if (!strncmp(buf, "S: Product=", 12)) - snprintf(dev.product_name, sizeof(dev.product_name), - "%s", buf+12); - break; - } + if ((attr = sysfs_attr(e->d_name, "idProduct")) != NULL) + dev.product_id = strtoul(attr, NULL, 16); - if (dev.product_name[0]) - return &dev; - } + if ((attr = sysfs_attr(e->d_name, "manufacturer")) != NULL) + strcpy(dev.vendor_name, attr); + + if ((attr = sysfs_attr(e->d_name, "product")) != NULL) + strcpy(dev.product_name, attr); + + if (dev.bus_num && dev.dev_num && dev.vendor_id && dev.product_id) + return &dev; return NULL; } static void list_devices(void) { - FILE *devs = open_devlist(); + DIR *devs = opendir("/sys/bus/usb/devices"); struct usbentry *dev; if (!devs) @@ -152,14 +140,14 @@ static void list_devices(void) dev->product_name); } - close_devlist(devs); + closedir(devs); } struct usbentry * find_device(int *bus, int *dev, int *vid, int *pid, const char *product) { - FILE *devs = open_devlist(); + DIR *devs = opendir("/sys/bus/usb/devices"); struct usbentry *e, *match = NULL; @@ -177,7 +165,7 @@ struct usbentry * find_device(int *bus, int *dev, } } - close_devlist(devs); + closedir(devs); return match; } @@ -185,10 +173,10 @@ struct usbentry * find_device(int *bus, int *dev, static void reset_device(struct usbentry *dev) { int fd; - char path[1024]; + char path[PATH_MAX]; - snprintf(path, sizeof(path), "%s/%03d/%03d", - usbfs, dev->bus_num, dev->dev_num); + snprintf(path, sizeof(path) - 1, "/dev/bus/usb/%03d/%03d", + dev->bus_num, dev->dev_num); printf("Resetting %s ... ", dev->product_name); @@ -213,12 +201,6 @@ int main(int argc, char **argv) int id1, id2; struct usbentry *dev; - if (!find_usbfs()) - { - fprintf(stderr, "Unable to find usbfs, is it mounted?\n"); - return 1; - } - if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2)) { dev = find_device(&id1, &id2, NULL, NULL, NULL); |