/*****************************************************************************/ /* * usbmisc.c -- Misc USB routines * * Copyright (C) 2003 Aurelien Jarno (aurelien@aurel32.net) * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * */ /*****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "usbmisc.h" /* ---------------------------------------------------------------------- */ static const char *devbususb = "/dev/bus/usb"; /* ---------------------------------------------------------------------- */ static int readlink_recursive(const char *path, char *buf, size_t bufsize) { char temp[PATH_MAX + 1]; char *ptemp; int ret; ret = readlink(path, buf, bufsize); if (ret > 0) { buf[ret] = 0; if (*buf != '/') { strncpy(temp, path, sizeof(temp)); ptemp = temp + strlen(temp); while (*ptemp != '/' && ptemp != temp) ptemp--; ptemp++; strncpy(ptemp, buf, bufsize + temp - ptemp); } else strncpy(temp, buf, sizeof(temp)); return readlink_recursive(temp, buf, bufsize); } else { strncpy(buf, path, bufsize); return strlen(buf); } } static char *get_absolute_path(const char *path, char *result, size_t result_size) { const char *ppath; /* pointer on the input string */ char *presult; /* pointer on the output string */ ppath = path; presult = result; result[0] = 0; if (path == NULL) return result; if (*ppath != '/') { result = getcwd(result, result_size); presult += strlen(result); result_size -= strlen(result); *presult++ = '/'; result_size--; } while (*ppath != 0 && result_size > 1) { if (*ppath == '/') { do ppath++; while (*ppath == '/'); *presult++ = '/'; result_size--; } else if (*ppath == '.' && *(ppath + 1) == '.' && *(ppath + 2) == '/' && *(presult - 1) == '/') { if ((presult - 1) != result) { /* go one directory upper */ do { presult--; result_size++; } while (*(presult - 1) != '/'); } ppath += 3; } else if (*ppath == '.' && *(ppath + 1) == '/' && *(presult - 1) == '/') { ppath += 2; } else { *presult++ = *ppath++; result_size--; } } /* Don't forget to mark the end of the string! */ *presult = 0; return result; } libusb_device *get_usb_device(libusb_context *ctx, const char *path) { libusb_device **list; libusb_device *dev; ssize_t num_devs, i; char device_path[PATH_MAX + 1]; char absolute_path[PATH_MAX + 1]; readlink_recursive(path, device_path, sizeof(device_path)); get_absolute_path(device_path, absolute_path, sizeof(absolute_path)); dev = NULL; num_devs = libusb_get_device_list(ctx, &list); for (i = 0; i < num_devs; ++i) { uint8_t bnum = libusb_get_bus_number(list[i]); uint8_t dnum = libusb_get_device_address(list[i]); snprintf(device_path, sizeof(device_path), "%s/%03u/%03u", devbususb, bnum, dnum); if (!strcmp(device_path, absolute_path)) { dev = list[i]; break; } } libusb_free_device_list(list, 0); return dev; }