/* parse parts of netlink message common to both libudev and the kernel */ static int linux_netlink_parse(char *buffer, size_t len, int *detached, const char **sys_name, uint8_t *busnum, uint8_t *devaddr) { const char *tmp; int i; errno = 0; *sys_name = NULL; *detached = 0; *busnum = 0; *devaddr = 0; tmp = netlink_message_parse((const char *) buffer, len, "ACTION"); if (tmp == NULL) return -1; if (0 == strcmp(tmp, "remove")) { *detached = 1; } else if (0 == strcmp(tmp, "add")) { // pass through } else if (0 != strcmp(tmp, "change")) { usbi_dbg("unknown device action [%s]", tmp); return -1; } /* check that this is a usb message */ tmp = netlink_message_parse(buffer, len, "SUBSYSTEM"); if (NULL == tmp || 0 != strcmp(tmp, "usb")) { /* not usb. ignore */ return -1; } tmp = netlink_message_parse(buffer, len, "BUSNUM"); if (NULL == tmp) { /* no bus number. try "DEVICE" */ tmp = netlink_message_parse(buffer, len, "DEVICE"); if (NULL == tmp) { /* not usb. ignore */ return -1; } /* Parse a device path such as /dev/bus/usb/003/004 */ char *pLastSlash = (char*)strrchr(tmp,'/'); if(NULL == pLastSlash) { return -1; } *devaddr = strtoul(pLastSlash + 1, NULL, 10); if (errno) { errno = 0; return -1; } *busnum = strtoul(pLastSlash - 3, NULL, 10); if (errno) { errno = 0; return -1; } return 0; } *busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); if (errno) { errno = 0; return -1; } tmp = netlink_message_parse(buffer, len, "DEVNUM"); if (NULL == tmp) { return -1; } *devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); if (errno) { errno = 0; return -1; } tmp = netlink_message_parse(buffer, len, "DEVPATH"); if (NULL == tmp) { return -1; } for (i = strlen(tmp) - 1 ; i ; --i) { if ('/' ==tmp[i]) { *sys_name = tmp + i + 1; break; } } /* found a usb device */ return 0; }
/* parse parts of netlink message common to both libudev and the kernel */ static int linux_netlink_parse(char *buffer, size_t len, int *detached, const char **sys_name, uint8_t *busnum, uint8_t *devaddr) { const char *tmp; int i; errno = 0; *sys_name = NULL; *detached = 0; *busnum = 0; *devaddr = 0; tmp = netlink_message_parse((const char *) buffer, len, "ACTION"); if (tmp == NULL) return -1; if (0 == strcmp(tmp, "remove")) { *detached = 1; } else if (0 != strcmp(tmp, "add")) { usbi_dbg("unknown device action %s", tmp); return -1; } /* check that this is a usb message */ tmp = netlink_message_parse(buffer, len, "SUBSYSTEM"); if (NULL == tmp || 0 != strcmp(tmp, "usb")) { /* not usb. ignore */ return -1; } tmp = netlink_message_parse(buffer, len, "BUSNUM"); if (NULL == tmp) { /* no bus number (likely a usb interface). ignore*/ return -1; } *busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); if (errno) { errno = 0; return -1; } tmp = netlink_message_parse(buffer, len, "DEVNUM"); if (NULL == tmp) { return -1; } *devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); if (errno) { errno = 0; return -1; } tmp = netlink_message_parse(buffer, len, "DEVPATH"); if (NULL == tmp) { return -1; } for (i = strlen(tmp) - 1 ; i ; --i) { if ('/' ==tmp[i]) { *sys_name = tmp + i + 1; break; } } /* found a usb device */ return 0; }