diff options
Diffstat (limited to 'names.c')
-rw-r--r-- | names.c | 925 |
1 files changed, 187 insertions, 738 deletions
@@ -3,6 +3,7 @@ * names.c -- USB name database manipulation routines * * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 2013 Tom Gundersen (teg@jklm.no) * * 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 @@ -34,77 +35,15 @@ #include <stdio.h> #include <ctype.h> -#ifdef HAVE_LIBZ -#include <zlib.h> -#define usb_file gzFile -#define usb_fopen(path, mode) gzopen(path, mode) -#define usb_fgets(s, size, stream) gzgets(stream, s, size) -#define usb_close(f) gzclose(f) -#else -#define usb_file FILE * -#define usb_fopen(path, mode) fopen(path, mode) -#define usb_fgets(s, size, stream) fgets(s, size, stream) -#define usb_close(f) fclose(f) -#endif +#include <libudev.h> +#include "usb-spec.h" #include "names.h" -/* ---------------------------------------------------------------------- */ - -struct vendor { - struct vendor *next; - u_int16_t vendorid; - char name[1]; -}; - -struct product { - struct product *next; - u_int16_t vendorid, productid; - char name[1]; -}; - -struct class { - struct class *next; - u_int8_t classid; - char name[1]; -}; - -struct subclass { - struct subclass *next; - u_int8_t classid, subclassid; - char name[1]; -}; - -struct protocol { - struct protocol *next; - u_int8_t classid, subclassid, protocolid; - char name[1]; -}; - -struct audioterminal { - struct audioterminal *next; - u_int16_t termt; - char name[1]; -}; - -struct videoterminal { - struct videoterminal *next; - u_int16_t termt; - char name[1]; -}; - -struct genericstrtable { - struct genericstrtable *next; - unsigned int num; - char name[1]; -}; - -/* ---------------------------------------------------------------------- */ - #define HASH1 0x10 #define HASH2 0x02 -#define HASHSZ 16 +#define HASHSZ 512 static unsigned int hashnum(unsigned int num) { @@ -118,21 +57,18 @@ static unsigned int hashnum(unsigned int num) /* ---------------------------------------------------------------------- */ -static struct vendor *vendors[HASHSZ] = { NULL, }; -static struct product *products[HASHSZ] = { NULL, }; -static struct class *classes[HASHSZ] = { NULL, }; -static struct subclass *subclasses[HASHSZ] = { NULL, }; -static struct protocol *protocols[HASHSZ] = { NULL, }; -static struct audioterminal *audioterminals[HASHSZ] = { NULL, }; -static struct videoterminal *videoterminals[HASHSZ] = { NULL, }; -static struct genericstrtable *hiddescriptors[HASHSZ] = { NULL, }; -static struct genericstrtable *reports[HASHSZ] = { NULL, }; -static struct genericstrtable *huts[HASHSZ] = { NULL, }; -static struct genericstrtable *biass[HASHSZ] = { NULL, }; -static struct genericstrtable *physdess[HASHSZ] = { NULL, }; -static struct genericstrtable *hutus[HASHSZ] = { NULL, }; -static struct genericstrtable *langids[HASHSZ] = { NULL, }; -static struct genericstrtable *countrycodes[HASHSZ] = { NULL, }; +static struct udev *udev = NULL; +static struct udev_hwdb *hwdb = NULL; +static struct audioterminal *audioterminals_hash[HASHSZ] = { NULL, }; +static struct videoterminal *videoterminals_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *hiddescriptors_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *reports_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *huts_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *biass_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *physdess_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *hutus_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *langids_hash[HASHSZ] = { NULL, }; +static struct genericstrtable *countrycodes_hash[HASHSZ] = { NULL, }; /* ---------------------------------------------------------------------- */ @@ -149,104 +85,100 @@ static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], const char *names_hid(u_int8_t hidd) { - return names_genericstrtable(hiddescriptors, hidd); + return names_genericstrtable(hiddescriptors_hash, hidd); } const char *names_reporttag(u_int8_t rt) { - return names_genericstrtable(reports, rt); + return names_genericstrtable(reports_hash, rt); } const char *names_huts(unsigned int data) { - return names_genericstrtable(huts, data); + return names_genericstrtable(huts_hash, data); } const char *names_hutus(unsigned int data) { - return names_genericstrtable(hutus, data); + return names_genericstrtable(hutus_hash, data); } const char *names_langid(u_int16_t langid) { - return names_genericstrtable(langids, langid); + return names_genericstrtable(langids_hash, langid); } const char *names_physdes(u_int8_t ph) { - return names_genericstrtable(physdess, ph); + return names_genericstrtable(physdess_hash, ph); } const char *names_bias(u_int8_t b) { - return names_genericstrtable(biass, b); + return names_genericstrtable(biass_hash, b); } const char *names_countrycode(unsigned int countrycode) { - return names_genericstrtable(countrycodes, countrycode); + return names_genericstrtable(countrycodes_hash, countrycode); } -const char *names_vendor(u_int16_t vendorid) +static const char *hwdb_get(const char *modalias, const char *key) { - struct vendor *v; + struct udev_list_entry *entry; + + udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0)) + if (strcmp(udev_list_entry_get_name(entry), key) == 0) + return udev_list_entry_get_value(entry); - v = vendors[hashnum(vendorid)]; - for (; v; v = v->next) - if (v->vendorid == vendorid) - return v->name; return NULL; } +const char *names_vendor(u_int16_t vendorid) +{ + char modalias[64]; + + sprintf(modalias, "usb:v%04X*", vendorid); + return hwdb_get(modalias, "ID_VENDOR_FROM_DATABASE"); +} + const char *names_product(u_int16_t vendorid, u_int16_t productid) { - struct product *p; + char modalias[64]; - p = products[hashnum((vendorid << 16) | productid)]; - for (; p; p = p->next) - if (p->vendorid == vendorid && p->productid == productid) - return p->name; - return NULL; + sprintf(modalias, "usb:v%04Xp%04X*", vendorid, productid); + return hwdb_get(modalias, "ID_MODEL_FROM_DATABASE"); } const char *names_class(u_int8_t classid) { - struct class *c; + char modalias[64]; - c = classes[hashnum(classid)]; - for (; c; c = c->next) - if (c->classid == classid) - return c->name; - return NULL; + sprintf(modalias, "usb:v*p*d*dc%02X*", classid); + return hwdb_get(modalias, "ID_USB_CLASS_FROM_DATABASE"); } const char *names_subclass(u_int8_t classid, u_int8_t subclassid) { - struct subclass *s; + char modalias[64]; - s = subclasses[hashnum((classid << 8) | subclassid)]; - for (; s; s = s->next) - if (s->classid == classid && s->subclassid == subclassid) - return s->name; - return NULL; + sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02X*", classid, subclassid); + return hwdb_get(modalias, "ID_USB_SUBCLASS_FROM_DATABASE"); } const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid) { - struct protocol *p; + char modalias[64]; - p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)]; - for (; p; p = p->next) - if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid) - return p->name; - return NULL; + sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02Xdp%02X*", classid, subclassid, protocolid); + return hwdb_get(modalias, "ID_USB_PROTOCOL_FROM_DATABASE"); } const char *names_audioterminal(u_int16_t termt) { struct audioterminal *at; - at = audioterminals[hashnum(termt)]; + at = audioterminals_hash[hashnum(termt)]; for (; at; at = at->next) if (at->termt == termt) return at->name; @@ -257,7 +189,7 @@ const char *names_videoterminal(u_int16_t termt) { struct videoterminal *vt; - vt = videoterminals[hashnum(termt)]; + vt = videoterminals_hash[hashnum(termt)]; for (; vt; vt = vt->next) if (vt->termt == termt) return vt->name; @@ -290,704 +222,221 @@ int get_product_string(char *buf, size_t size, u_int16_t vid, u_int16_t pid) return snprintf(buf, size, "%s", cp); } -/* ---------------------------------------------------------------------- */ - -static int new_vendor(const char *name, u_int16_t vendorid) +int get_class_string(char *buf, size_t size, u_int8_t cls) { - struct vendor *v; - unsigned int h = hashnum(vendorid); + const char *cp; - v = vendors[h]; - for (; v; v = v->next) - if (v->vendorid == vendorid) - return -1; - v = malloc(sizeof(struct vendor) + strlen(name)); - if (!v) - return -1; - strcpy(v->name, name); - v->vendorid = vendorid; - v->next = vendors[h]; - vendors[h] = v; - return 0; + if (size < 1) + return 0; + *buf = 0; + if (!(cp = names_class(cls))) + return 0; + return snprintf(buf, size, "%s", cp); } -static int new_product(const char *name, u_int16_t vendorid, u_int16_t productid) +int get_subclass_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls) { - struct product *p; - unsigned int h = hashnum((vendorid << 16) | productid); + const char *cp; - p = products[h]; - for (; p; p = p->next) - if (p->vendorid == vendorid && p->productid == productid) - return -1; - p = malloc(sizeof(struct product) + strlen(name)); - if (!p) - return -1; - strcpy(p->name, name); - p->vendorid = vendorid; - p->productid = productid; - p->next = products[h]; - products[h] = p; - return 0; + if (size < 1) + return 0; + *buf = 0; + if (!(cp = names_subclass(cls, subcls))) + return 0; + return snprintf(buf, size, "%s", cp); } -static int new_class(const char *name, u_int8_t classid) -{ - struct class *c; - unsigned int h = hashnum(classid); - - c = classes[h]; - for (; c; c = c->next) - if (c->classid == classid) - return -1; - c = malloc(sizeof(struct class) + strlen(name)); - if (!c) - return -1; - strcpy(c->name, name); - c->classid = classid; - c->next = classes[h]; - classes[h] = c; - return 0; -} +/* ---------------------------------------------------------------------- */ -static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid) +static int hash_audioterminal(struct audioterminal *at) { - struct subclass *s; - unsigned int h = hashnum((classid << 8) | subclassid); + struct audioterminal *at_old; + unsigned int h = hashnum(at->termt); - s = subclasses[h]; - for (; s; s = s->next) - if (s->classid == classid && s->subclassid == subclassid) + for (at_old = audioterminals_hash[h]; at_old; at_old = at_old->next) + if (at_old->termt == at->termt) return -1; - s = malloc(sizeof(struct subclass) + strlen(name)); - if (!s) - return -1; - strcpy(s->name, name); - s->classid = classid; - s->subclassid = subclassid; - s->next = subclasses[h]; - subclasses[h] = s; + at->next = audioterminals_hash[h]; + audioterminals_hash[h] = at; return 0; } -static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid) +static int hash_audioterminals(void) { - struct protocol *p; - unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid); + int r = 0, i, k; - p = protocols[h]; - for (; p; p = p->next) - if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid) - return -1; - p = malloc(sizeof(struct protocol) + strlen(name)); - if (!p) - return -1; - strcpy(p->name, name); - p->classid = classid; - p->subclassid = subclassid; - p->protocolid = protocolid; - p->next = protocols[h]; - protocols[h] = p; - return 0; + for (i = 0; audioterminals[i].name; i++) + { + k = hash_audioterminal(&audioterminals[i]); + if (k < 0) + r = k; + } + + return r; } -static int new_audioterminal(const char *name, u_int16_t termt) +static int hash_videoterminal(struct videoterminal *vt) { - struct audioterminal *at; - unsigned int h = hashnum(termt); + struct videoterminal *vt_old; + unsigned int h = hashnum(vt->termt); - at = audioterminals[h]; - for (; at; at = at->next) - if (at->termt == termt) + for (vt_old = videoterminals_hash[h]; vt_old; vt_old = vt_old->next) + if (vt_old->termt == vt->termt) return -1; - at = malloc(sizeof(struct audioterminal) + strlen(name)); - if (!at) - return -1; - strcpy(at->name, name); - at->termt = termt; - at->next = audioterminals[h]; - audioterminals[h] = at; + vt->next = videoterminals_hash[h]; + videoterminals_hash[h] = vt; return 0; } -static int new_videoterminal(const char *name, u_int16_t termt) +static int hash_videoterminals(void) { - struct videoterminal *vt; - unsigned int h = hashnum(termt); + int r = 0, i, k; - vt = videoterminals[h]; - for (; vt; vt = vt->next) - if (vt->termt == termt) - return -1; - vt = malloc(sizeof(struct videoterminal) + strlen(name)); - if (!vt) - return -1; - strcpy(vt->name, name); - vt->termt = termt; - vt->next = videoterminals[h]; - videoterminals[h] = vt; - return 0; + for (i = 0; videoterminals[i].name; i++) + { + k = hash_videoterminal(&videoterminals[i]); + if (k < 0) + r = k; + } + + return r; } -static int new_genericstrtable(struct genericstrtable *t[HASHSZ], - const char *name, unsigned int idx) +static int hash_genericstrtable(struct genericstrtable *t[HASHSZ], + struct genericstrtable *g) { - struct genericstrtable *g; - unsigned int h = hashnum(idx); + struct genericstrtable *g_old; + unsigned int h = hashnum(g->num); - for (g = t[h]; g; g = g->next) - if (g->num == idx) + for (g_old = t[h]; g_old; g_old = g_old->next) + if (g_old->num == g->num) return -1; - g = malloc(sizeof(struct genericstrtable) + strlen(name)); - if (!g) - return -1; - strcpy(g->name, name); - g->num = idx; g->next = t[h]; t[h] = g; return 0; } -static int new_hid(const char *name, u_int8_t hidd) -{ - return new_genericstrtable(hiddescriptors, name, hidd); -} - -static int new_reporttag(const char *name, u_int8_t rt) -{ - return new_genericstrtable(reports, name, rt); -} +#define HASH_EACH(array, hash) \ + for (i = 0; array[i].name; i++) { \ + k = hash_genericstrtable(hash, &array[i]); \ + if (k < 0) { \ + r = k; \ + }\ + } -static int new_huts(const char *name, unsigned int data) +static int hash_tables(void) { - return new_genericstrtable(huts, name, data); -} + int r = 0, k, i; -static int new_hutus(const char *name, unsigned int data) -{ - return new_genericstrtable(hutus, name, data); -} + k = hash_audioterminals(); + if (k < 0) + r = k; -static int new_langid(const char *name, u_int16_t langid) -{ - return new_genericstrtable(langids, name, langid); -} + k = hash_videoterminals(); + if (k < 0) + r = k; -static int new_physdes(const char *name, u_int8_t ph) -{ - return new_genericstrtable(physdess, name, ph); -} -static int new_bias(const char *name, u_int8_t b) -{ - return new_genericstrtable(biass, name, b); -} + HASH_EACH(hiddescriptors, hiddescriptors_hash); -static int new_countrycode(const char *name, unsigned int countrycode) -{ - return new_genericstrtable(countrycodes, name, countrycode); -} + HASH_EACH(reports, reports_hash); -/* ---------------------------------------------------------------------- */ + HASH_EACH(huts, huts_hash); -static void free_vendor(void) -{ - struct vendor *cur, *tmp; - int i; + HASH_EACH(hutus, hutus_hash); - for (i = 0; i < HASHSZ; i++) { - cur = vendors[i]; - vendors[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } - } -} + HASH_EACH(langids, langids_hash); -static void free_product(void) -{ - struct product *cur, *tmp; - int i; + HASH_EACH(physdess, physdess_hash); - for (i = 0; i < HASHSZ; i++) { - cur = products[i]; - products[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } - } -} + HASH_EACH(biass, biass_hash); -static void free_class(void) -{ - struct class *cur, *tmp; - int i; + HASH_EACH(countrycodes, countrycodes_hash); - for (i = 0; i < HASHSZ; i++) { - cur = classes[i]; - classes[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } - } + return r; } -static void free_subclass(void) +/* ---------------------------------------------------------------------- */ + +/* +static void print_tables(void) { - struct subclass *cur, *tmp; int i; + struct audioterminal *at; + struct videoterminal *vt; + struct genericstrtable *li; + struct genericstrtable *hu; - for (i = 0; i < HASHSZ; i++) { - cur = subclasses[i]; - subclasses[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } - } -} -static void free_protocol(void) -{ - struct protocol *cur, *tmp; - int i; + printf("--------------------------------------------\n"); + printf("\t\t Audio Terminals\n"); + printf("--------------------------------------------\n"); for (i = 0; i < HASHSZ; i++) { - cur = protocols[i]; - protocols[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } + printf("hash: %d\n", i); + at = audioterminals_hash[i]; + for (; at; at = at->next) + printf("\tentry: %s\n", at->name); } -} -static void free_audioterminal(void) -{ - struct audioterminal *cur, *tmp; - int i; + printf("--------------------------------------------\n"); + printf("\t\t Video Terminals\n"); + printf("--------------------------------------------\n"); for (i = 0; i < HASHSZ; i++) { - cur = audioterminals[i]; - audioterminals[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } + printf("hash: %d\n", i); + vt = videoterminals_hash[i]; + for (; vt; vt = vt->next) + printf("\tentry: %s\n", vt->name); } - return; -} -static void free_videoterminal(void) -{ - struct videoterminal *cur, *tmp; - int i; + printf("--------------------------------------------\n"); + printf("\t\t Languages\n"); + printf("--------------------------------------------\n"); for (i = 0; i < HASHSZ; i++) { - cur = videoterminals[i]; - videoterminals[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } + li = langids_hash[i]; + if (li) + printf("hash: %d\n", i); + for (; li; li = li->next) + printf("\tid: %x, entry: %s\n", li->num, li->name); } -} -static void _free_genericstrtable(struct genericstrtable *t[HASHSZ]) -{ - struct genericstrtable *cur, *tmp; - int i; + printf("--------------------------------------------\n"); + printf("\t\t Conutry Codes\n"); + printf("--------------------------------------------\n"); for (i = 0; i < HASHSZ; i++) { - cur = t[i]; - t[i] = NULL; - while (cur) { - tmp = cur; - cur = cur->next; - free(tmp); - } + hu = countrycodes_hash[i]; + if (hu) + printf("hash: %d\n", i); + for (; hu; hu = hu->next) + printf("\tid: %x, entry: %s\n", hu->num, hu->name); } -} -static void free_genericstrtable(void) -{ - _free_genericstrtable(hiddescriptors); - _free_genericstrtable(reports); - _free_genericstrtable(huts); - _free_genericstrtable(biass); - _free_genericstrtable(physdess); - _free_genericstrtable(hutus); - _free_genericstrtable(langids); - _free_genericstrtable(countrycodes); + printf("--------------------------------------------\n"); } +*/ -#define DBG(x) - -static void parse(usb_file f) +int names_init(void) { - char buf[512], *cp; - unsigned int linectr = 0; - int lastvendor = -1; - int lastclass = -1; - int lastsubclass = -1; - int lasthut = -1; - int lastlang = -1; - unsigned int u; - - while (usb_fgets(buf, sizeof(buf), f)) { - linectr++; - /* remove line ends */ - cp = strchr(buf, 13); - if (cp) - *cp = 0; - cp = strchr(buf, 10); - if (cp) - *cp = 0; - if (buf[0] == '#' || !buf[0]) - continue; - cp = buf; - if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' && - buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') { - cp = buf + 8; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid Physdes type at line %u\n", linectr); - continue; - } - if (new_physdes(cp, u)) - fprintf(stderr, "Duplicate Physdes type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') { - cp = buf + 4; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid PHY type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid PHY type at line %u\n", linectr); - continue; - } - if (new_physdes(cp, u)) - fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') { - cp = buf + 5; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid BIAS type at line %u\n", linectr); - continue; - } - if (new_bias(cp, u)) - fprintf(stderr, "Duplicate BIAS type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') { - cp = buf+2; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr); - continue; - } - if (new_langid(cp, u)) - fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp); - DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp)); - lasthut = lastclass = lastvendor = lastsubclass = -1; - lastlang = u; - continue; - } - if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') { - /* class spec */ - cp = buf+2; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid class spec at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid class spec at line %u\n", linectr); - continue; - } - if (new_class(cp, u)) - fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", linectr, u, cp); - DBG(printf("line %5u class %02x %s\n", linectr, u, cp)); - lasthut = lastlang = lastvendor = lastsubclass = -1; - lastclass = u; - continue; - } - if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) { - /* audio terminal type spec */ - cp = buf+3; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr); - continue; - } - if (new_audioterminal(cp, u)) - fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u audio terminal type %02x %s\n", linectr, u, cp)); - continue; - } - if (buf[0] == 'V' && buf[1] == 'T' && isspace(buf[2])) { - /* video terminal type spec */ - cp = buf+3; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid video terminal type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid video terminal type at line %u\n", linectr); - continue; - } - if (new_videoterminal(cp, u)) - fprintf(stderr, "Duplicate video terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u video terminal type %02x %s\n", linectr, u, cp)); - continue; - } - if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) { - /* HID Descriptor bCountryCode */ - cp = buf+3; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HID country code at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 10); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid HID country code at line %u\n", linectr); - continue; - } - if (new_countrycode(cp, u)) - fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp); - DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp)); - continue; - } - if (isxdigit(*cp)) { - /* vendor */ - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid vendor spec at line %u\n", linectr); - continue; - } - if (new_vendor(cp, u)) - fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", linectr, u, cp); - DBG(printf("line %5u vendor %04x %s\n", linectr, u, cp)); - lastvendor = u; - lasthut = lastlang = lastclass = lastsubclass = -1; - continue; - } - if (buf[0] == '\t' && isxdigit(buf[1])) { - /* product or subclass spec */ - u = strtoul(buf+1, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr); - continue; - } - if (lastvendor != -1) { - if (new_product(cp, lastvendor, u)) - fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", linectr, lastvendor, u, cp); - DBG(printf("line %5u product %04x:%04x %s\n", linectr, lastvendor, u, cp)); - continue; - } - if (lastclass != -1) { - if (new_subclass(cp, lastclass, u)) - fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", linectr, lastclass, u, cp); - DBG(printf("line %5u subclass %02x:%02x %s\n", linectr, lastclass, u, cp)); - lastsubclass = u; - continue; - } - if (lasthut != -1) { - if (new_hutus(cp, (lasthut << 16)+u)) - fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr); - continue; - } - if (lastlang != -1) { - if (new_langid(cp, lastlang+(u<<10))) - fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr); - continue; - } - fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr); - continue; - } - if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) { - /* protocol spec */ - u = strtoul(buf+2, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid protocol spec at line %u\n", linectr); - continue; - } - if (lastclass != -1 && lastsubclass != -1) { - if (new_protocol(cp, lastclass, lastsubclass, u)) - fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp); - DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp)); - continue; - } - fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", linectr); - continue; - } - if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') { - cp = buf + 4; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HID type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid HID type at line %u\n", linectr); - continue; - } - if (new_hid(cp, u)) - fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') { - cp = buf + 4; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid HUT type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid HUT type at line %u\n", linectr); - continue; - } - if (new_huts(cp, u)) - fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp); - lastlang = lastclass = lastvendor = lastsubclass = -1; - lasthut = u; - DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp)); - continue; - - } - if (buf[0] == 'R' && buf[1] == ' ') { - cp = buf + 2; - while (isspace(*cp)) - cp++; - if (!isxdigit(*cp)) { - fprintf(stderr, "Invalid Report type at line %u\n", linectr); - continue; - } - u = strtoul(cp, &cp, 16); - while (isspace(*cp)) - cp++; - if (!*cp) { - fprintf(stderr, "Invalid Report type at line %u\n", linectr); - continue; - } - if (new_reporttag(cp, u)) - fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp); - DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp)); - continue; - - } - fprintf(stderr, "Unknown line at line %u\n", linectr); - } -} - -/* ---------------------------------------------------------------------- */ + int r; -int names_init(char *n) -{ - usb_file f; + udev = udev_new(); + if (!udev) + r = -1; + else { + hwdb = udev_hwdb_new(udev); + if (!hwdb) + r = -1; + } - f = usb_fopen(n, "r"); - if (!f) - return errno; + r = hash_tables(); - parse(f); - usb_close(f); - return 0; + return r; } void names_exit(void) { - free_vendor(); - free_product(); - free_class(); - free_subclass(); - free_protocol(); - free_audioterminal(); - free_videoterminal(); - free_genericstrtable(); + hwdb = udev_hwdb_unref(hwdb); + udev = udev_unref(udev); } |