2 * usb-db, pci-db - lookup vendor/product database
4 * Copyright (C) 2009 Lennart Poettering <lennart@poettering.net>
5 * Copyright (C) 2011 Kay Sievers <kay.sievers@vrfy.org>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 static int get_id_attr(
31 struct udev_device *parent,
38 if (!(t = udev_device_get_sysattr_value(parent, name))) {
39 fprintf(stderr, "%s lacks %s.\n", udev_device_get_syspath(parent), name);
43 if (!strncmp(t, "0x", 2))
46 if (sscanf(t, "%04x", &u) != 1 || u > 0xFFFFU) {
47 fprintf(stderr, "Failed to parse %s on %s.\n", name, udev_device_get_syspath(parent));
51 *value = (uint16_t) u;
55 static int get_vid_pid(
56 struct udev_device *parent,
57 const char *vendor_attr,
58 const char *product_attr,
62 if (get_id_attr(parent, vendor_attr, vid) < 0)
65 fprintf(stderr, "Invalid vendor id.\n");
69 if (get_id_attr(parent, product_attr, pid) < 0)
75 static void rstrip(char *n) {
78 for (i = strlen(n); i > 0 && isspace(n[i-1]); i--)
82 #define HEXCHARS "0123456789abcdefABCDEF"
83 #define WHITESPACE " \t\n\r"
84 static int lookup_vid_pid(const char *database,
85 uint16_t vid, uint16_t pid,
86 char **vendor, char **product)
94 *vendor = *product = NULL;
96 if (!(f = fopen(database, "rme"))) {
97 fprintf(stderr, "Failed to open database file '%s': %s\n", database, strerror(errno));
109 if (getline(&line, &n, f) < 0)
114 if (line[0] == '#' || line[0] == 0)
117 if (strspn(line, HEXCHARS) == 4) {
123 if (sscanf(line, "%04x", &u) == 1 && u == vid) {
127 t += strspn(t, WHITESPACE);
129 if (!(*vendor = strdup(t))) {
130 fprintf(stderr, "Out of memory.\n");
140 if (found_vendor && line[0] == '\t' && strspn(line+1, HEXCHARS) == 4) {
143 if (sscanf(line+1, "%04x", &u) == 1 && u == pid) {
147 t += strspn(t, WHITESPACE);
149 if (!(*product = strdup(t))) {
150 fprintf(stderr, "Out of memory.\n");
169 *product = *vendor = NULL;
175 static struct udev_device *find_device(struct udev_device *dev, const char *subsys, const char *devtype)
179 str = udev_device_get_subsystem(dev);
182 if (strcmp(str, subsys) != 0)
185 if (devtype != NULL) {
186 str = udev_device_get_devtype(dev);
189 if (strcmp(str, devtype) != 0)
194 return udev_device_get_parent_with_subsystem_devtype(dev, subsys, devtype);
198 static int builtin_db(struct udev_device *dev, bool test,
199 const char *database,
200 const char *vendor_attr, const char *product_attr,
201 const char *subsys, const char *devtype)
203 struct udev_device *parent;
204 uint16_t vid = 0, pid = 0;
205 char *vendor = NULL, *product = NULL;
207 parent = find_device(dev, subsys, devtype);
209 fprintf(stderr, "Failed to find device.\n");
213 if (get_vid_pid(parent, vendor_attr, product_attr, &vid, &pid) < 0)
216 if (lookup_vid_pid(database, vid, pid, &vendor, &product) < 0)
220 udev_builtin_add_property(dev, test, "ID_VENDOR_FROM_DATABASE", vendor);
222 udev_builtin_add_property(dev, test, "ID_MODEL_FROM_DATABASE", product);
230 static int builtin_usb_db(struct udev_device *dev, int argc, char *argv[], bool test)
232 return builtin_db(dev, test, USB_DATABASE, "idVendor", "idProduct", "usb", "usb_device");
235 static int builtin_pci_db(struct udev_device *dev, int argc, char *argv[], bool test)
237 return builtin_db(dev, test, PCI_DATABASE, "vendor", "device", "pci", NULL);
240 const struct udev_builtin udev_builtin_usb_db = {
242 .cmd = builtin_usb_db,
243 .help = "USB vendor/product database",
247 const struct udev_builtin udev_builtin_pci_db = {
249 .cmd = builtin_pci_db,
250 .help = "PCI vendor/product database",