Commit 74ce259c authored by matt mooney's avatar matt mooney Committed by Greg Kroah-Hartman

staging: usbip: userspace: usbip_list.c: refactor local USB device listing

Combines the different list display types for local devices into one
function. Removes dependence on utils.h, which only exists as a way to
circumvent libsysfs and will be removed. The devices are now sorted as
an added benefit of this refactor.
Signed-off-by: default avatarmatt mooney <mfm@muteddisk.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3e4fda9f
...@@ -23,17 +23,15 @@ ...@@ -23,17 +23,15 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <dirent.h>
#include <getopt.h> #include <getopt.h>
#include <netdb.h> #include <netdb.h>
#include <regex.h>
#include <unistd.h> #include <unistd.h>
#include "usbip_common.h" #include "usbip_common.h"
#include "usbip_network.h" #include "usbip_network.h"
#include "utils.h"
#include "usbip.h" #include "usbip.h"
static const char usbip_list_usage_string[] = static const char usbip_list_usage_string[] =
...@@ -149,113 +147,104 @@ static int show_exported_devices(char *host) ...@@ -149,113 +147,104 @@ static int show_exported_devices(char *host)
return 0; return 0;
} }
static int is_usb_device(char *busid) static void print_device(char *busid, char *vendor, char *product,
bool parsable)
{ {
int ret; if (parsable)
printf("busid=%s#usbid=%.4s:%.4s#", busid, vendor, product);
regex_t regex; else
regmatch_t pmatch[1]; printf(" - busid %s (%.4s:%.4s)\n", busid, vendor, product);
ret = regcomp(&regex, "^[0-9]+-[0-9]+(\\.[0-9]+)*$", REG_NOSUB|REG_EXTENDED);
if (ret < 0)
err("regcomp: %s\n", strerror(errno));
ret = regexec(&regex, busid, 0, pmatch, 0);
if (ret)
return 0; /* not matched */
return 1;
} }
static int show_devices(void) static void print_interface(char *busid, char *driver, bool parsable)
{ {
DIR *dir; if (parsable)
printf("%s=%s#", busid, driver);
dir = opendir("/sys/bus/usb/devices/"); else
if (!dir) printf("%9s%s -> %s\n", "", busid, driver);
err("opendir: %s", strerror(errno)); }
printf("List USB devices\n");
for (;;) {
struct dirent *dirent;
char *busid;
dirent = readdir(dir);
if (!dirent)
break;
busid = dirent->d_name;
if (is_usb_device(busid)) {
char name[100] = {'\0'};
char driver[100] = {'\0'};
int conf, ninf = 0;
int i;
conf = read_bConfigurationValue(busid);
ninf = read_bNumInterfaces(busid);
getdevicename(busid, name, sizeof(name));
printf(" - busid %s (%s)\n", busid, name);
for (i = 0; i < ninf; i++) { static int is_device(void *x)
getdriver(busid, conf, i, driver, {
sizeof(driver)); struct sysfs_attribute *devpath;
printf(" %s:%d.%d -> %s\n", busid, conf, struct sysfs_device *dev = x;
i, driver); int ret = 0;
}
printf("\n");
}
}
closedir(dir); devpath = sysfs_get_device_attr(dev, "devpath");
if (devpath && *devpath->value != '0')
ret = 1;
return 0; return ret;
} }
static int show_devices2(void) static int devcmp(void *a, void *b)
{ {
DIR *dir; return strcmp(a, b);
}
dir = opendir("/sys/bus/usb/devices/");
if (!dir)
err("opendir: %s", strerror(errno));
for (;;) {
struct dirent *dirent;
char *busid;
dirent = readdir(dir); static int list_devices(bool parsable)
if (!dirent) {
break; char bus_type[] = "usb";
char busid[SYSFS_BUS_ID_SIZE];
struct sysfs_bus *ubus;
struct sysfs_device *dev;
struct sysfs_device *intf;
struct sysfs_attribute *idVendor;
struct sysfs_attribute *idProduct;
struct sysfs_attribute *bConfValue;
struct sysfs_attribute *bNumIntfs;
struct dlist *devlist;
int i;
int ret = -1;
busid = dirent->d_name; ubus = sysfs_open_bus(bus_type);
if (!ubus) {
err("sysfs_open_bus: %s", strerror(errno));
return -1;
}
if (is_usb_device(busid)) { devlist = sysfs_get_bus_devices(ubus);
char name[100] = {'\0'}; if (!devlist) {
char driver[100] = {'\0'}; err("sysfs_get_bus_devices: %s", strerror(errno));
int conf, ninf = 0; goto err_out;
int i; }
conf = read_bConfigurationValue(busid); /* remove interfaces and root hubs from device list */
ninf = read_bNumInterfaces(busid); dlist_filter_sort(devlist, is_device, devcmp);
getdevicename(busid, name, sizeof(name)); if (!parsable) {
printf("Local USB devices\n");
printf("=================\n");
}
dlist_for_each_data(devlist, dev, struct sysfs_device) {
idVendor = sysfs_get_device_attr(dev, "idVendor");
idProduct = sysfs_get_device_attr(dev, "idProduct");
bConfValue = sysfs_get_device_attr(dev, "bConfigurationValue");
bNumIntfs = sysfs_get_device_attr(dev, "bNumInterfaces");
if (!idVendor || !idProduct || !bConfValue || !bNumIntfs)
goto err_out;
printf("busid=%s#usbid=%s#", busid, name); print_device(dev->bus_id, idVendor->value, idProduct->value,
parsable);
for (i = 0; i < ninf; i++) { for (i = 0; i < atoi(bNumIntfs->value); i++) {
getdriver(busid, conf, i, driver, sizeof(driver)); snprintf(busid, sizeof(busid), "%s:%.1s.%d",
printf("%s:%d.%d=%s#", busid, conf, i, driver); dev->bus_id, bConfValue->value, i);
intf = sysfs_open_device(bus_type, busid);
if (!intf)
goto err_out;
print_interface(busid, intf->driver_name, parsable);
sysfs_close_device(intf);
} }
printf("\n"); printf("\n");
} }
}
closedir(dir); ret = 0;
return 0; err_out:
sysfs_close_bus(ubus);
return ret;
} }
int usbip_list(int argc, char *argv[]) int usbip_list(int argc, char *argv[])
...@@ -266,12 +255,12 @@ int usbip_list(int argc, char *argv[]) ...@@ -266,12 +255,12 @@ int usbip_list(int argc, char *argv[])
{ "local", no_argument, NULL, 'l' }, { "local", no_argument, NULL, 'l' },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
bool is_parsable = false; bool parsable = false;
int opt; int opt;
int ret = -1; int ret = -1;
if (usbip_names_init(USBIDS_FILE)) if (usbip_names_init(USBIDS_FILE))
err("failed to open %s\n", USBIDS_FILE); err("failed to open %s", USBIDS_FILE);
for (;;) { for (;;) {
opt = getopt_long(argc, argv, "pr:l", opts, NULL); opt = getopt_long(argc, argv, "pr:l", opts, NULL);
...@@ -281,16 +270,13 @@ int usbip_list(int argc, char *argv[]) ...@@ -281,16 +270,13 @@ int usbip_list(int argc, char *argv[])
switch (opt) { switch (opt) {
case 'p': case 'p':
is_parsable = true; parsable = true;
break; break;
case 'r': case 'r':
ret = show_exported_devices(optarg); ret = show_exported_devices(optarg);
goto out; goto out;
case 'l': case 'l':
if (is_parsable) ret = list_devices(parsable);
ret = show_devices2();
else
ret = show_devices();
goto out; goto out;
default: default:
goto err_out; goto err_out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment