diff options
Diffstat (limited to 'gtk/usbutil.c')
-rw-r--r-- | gtk/usbutil.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/gtk/usbutil.c b/gtk/usbutil.c new file mode 100644 index 0000000..4f9502d --- /dev/null +++ b/gtk/usbutil.c @@ -0,0 +1,99 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2012 Red Hat, Inc. + + Red Hat Authors: + Hans de Goede <hdegoede@redhat.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "config.h" + +#include <glib-object.h> +#include <glib/gi18n.h> + +#include "glib-compat.h" + +#ifdef USE_USBREDIR +#ifdef __linux__ +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#endif +#include "usbutil.h" + +G_GNUC_INTERNAL +const char *spice_usbutil_libusb_strerror(enum libusb_error error_code) +{ + switch (error_code) { + case LIBUSB_SUCCESS: + return "Success"; + case LIBUSB_ERROR_IO: + return "Input/output error"; + case LIBUSB_ERROR_INVALID_PARAM: + return "Invalid parameter"; + case LIBUSB_ERROR_ACCESS: + return "Access denied (insufficient permissions)"; + case LIBUSB_ERROR_NO_DEVICE: + return "No such device (it may have been disconnected)"; + case LIBUSB_ERROR_NOT_FOUND: + return "Entity not found"; + case LIBUSB_ERROR_BUSY: + return "Resource busy"; + case LIBUSB_ERROR_TIMEOUT: + return "Operation timed out"; + case LIBUSB_ERROR_OVERFLOW: + return "Overflow"; + case LIBUSB_ERROR_PIPE: + return "Pipe error"; + case LIBUSB_ERROR_INTERRUPTED: + return "System call interrupted (perhaps due to signal)"; + case LIBUSB_ERROR_NO_MEM: + return "Insufficient memory"; + case LIBUSB_ERROR_NOT_SUPPORTED: + return "Operation not supported or unimplemented on this platform"; + case LIBUSB_ERROR_OTHER: + return "Other error"; + } + return "Unknown error"; +} + +#ifdef __linux__ +/* <Sigh> libusb does not allow getting the manufacturer and product strings + without opening the device, so grab them directly from sysfs */ +gchar *spice_usbutil_get_sysfs_attribute(int bus, int address, const char *attribute) +{ + struct stat stat_buf; + char filename[256]; + gchar *contents; + + snprintf(filename, sizeof(filename), "/dev/bus/usb/%03d/%03d", + bus, address); + if (stat(filename, &stat_buf) != 0) + return NULL; + + snprintf(filename, sizeof(filename), "/sys/dev/char/%d:%d/%s", + major(stat_buf.st_rdev), minor(stat_buf.st_rdev), attribute); + if (!g_file_get_contents(filename, &contents, NULL, NULL)) + return NULL; + + /* Remove the newline at the end */ + contents[strlen(contents) - 1] = '\0'; + + return contents; +} +#endif +#endif |