From d4b800ce34c7060080ec40d97c88d17982961e39 Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Thu, 5 Jan 2012 19:06:33 +0000 Subject: sync with names with usbutils-005 which have better memory management (needed for next commit) --- NEWS | 1 + names.c | 658 ++++++++++++++++++++++++++++++++++++++++------------------------ names.h | 36 ++-- 3 files changed, 435 insertions(+), 260 deletions(-) diff --git a/NEWS b/NEWS index 6b5c835..da285c4 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ - plug some memleaks +- sync with names with usbutils-005 Version 0.11.3 - 21 November 2011, Thierry Vignaud diff --git a/names.c b/names.c index a39425d..480f579 100644 --- a/names.c +++ b/names.c @@ -14,15 +14,15 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * * */ /*****************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -34,18 +34,14 @@ #include #include -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #ifdef HAVE_LIBZ #include -#define usb_file gzFile +#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_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) @@ -58,50 +54,50 @@ struct vendor { struct vendor *next; - uint16_t vendorid; + u_int16_t vendorid; char name[1]; }; struct product { struct product *next; - uint16_t vendorid, productid; + u_int16_t vendorid, productid; char name[1]; }; struct class { struct class *next; - uint8_t classid; + u_int8_t classid; char name[1]; }; struct subclass { struct subclass *next; - uint8_t classid, subclassid; + u_int8_t classid, subclassid; char name[1]; }; struct protocol { struct protocol *next; - uint8_t classid, subclassid, protocolid; + u_int8_t classid, subclassid, protocolid; char name[1]; }; struct audioterminal { struct audioterminal *next; - uint16_t termt; + u_int16_t termt; char name[1]; }; struct videoterminal { struct videoterminal *next; - uint16_t termt; + u_int16_t termt; char name[1]; }; struct genericstrtable { - struct genericstrtable *next; - unsigned int num; - char name[1]; + struct genericstrtable *next; + unsigned int num; + char name[1]; }; /* ---------------------------------------------------------------------- */ @@ -138,26 +134,25 @@ static struct genericstrtable *hutus[HASHSZ] = { NULL, }; static struct genericstrtable *langids[HASHSZ] = { NULL, }; static struct genericstrtable *countrycodes[HASHSZ] = { NULL, }; -static int init_done = 0; - /* ---------------------------------------------------------------------- */ -static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], unsigned int index) +static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], + unsigned int idx) { - struct genericstrtable *h; + struct genericstrtable *h; - for (h = t[hashnum(index)]; h; h = h->next) - if (h->num == index) - return h->name; - return NULL; + for (h = t[hashnum(idx)]; h; h = h->next) + if (h->num == idx) + return h->name; + return NULL; } -const char *names_hid(uint8_t hidd) +const char *names_hid(u_int8_t hidd) { return names_genericstrtable(hiddescriptors, hidd); } -const char *names_reporttag(uint8_t rt) +const char *names_reporttag(u_int8_t rt) { return names_genericstrtable(reports, rt); } @@ -172,17 +167,17 @@ const char *names_hutus(unsigned int data) return names_genericstrtable(hutus, data); } -const char *names_langid(uint16_t langid) +const char *names_langid(u_int16_t langid) { return names_genericstrtable(langids, langid); } -const char *names_physdes(uint8_t ph) +const char *names_physdes(u_int8_t ph) { return names_genericstrtable(physdess, ph); } -const char *names_bias(uint8_t b) +const char *names_bias(u_int8_t b) { return names_genericstrtable(biass, b); } @@ -192,7 +187,7 @@ const char *names_countrycode(unsigned int countrycode) return names_genericstrtable(countrycodes, countrycode); } -const char *names_vendor(uint16_t vendorid) +const char *names_vendor(u_int16_t vendorid) { struct vendor *v; @@ -203,7 +198,7 @@ const char *names_vendor(uint16_t vendorid) return NULL; } -const char *names_product(uint16_t vendorid, uint16_t productid) +const char *names_product(u_int16_t vendorid, u_int16_t productid) { struct product *p; @@ -214,7 +209,7 @@ const char *names_product(uint16_t vendorid, uint16_t productid) return NULL; } -const char *names_class(uint8_t classid) +const char *names_class(u_int8_t classid) { struct class *c; @@ -225,7 +220,7 @@ const char *names_class(uint8_t classid) return NULL; } -const char *names_subclass(uint8_t classid, uint8_t subclassid) +const char *names_subclass(u_int8_t classid, u_int8_t subclassid) { struct subclass *s; @@ -236,7 +231,7 @@ const char *names_subclass(uint8_t classid, uint8_t subclassid) return NULL; } -const char *names_protocol(uint8_t classid, uint8_t subclassid, uint8_t protocolid) +const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid) { struct protocol *p; @@ -247,7 +242,7 @@ const char *names_protocol(uint8_t classid, uint8_t subclassid, uint8_t protocol return NULL; } -const char *names_audioterminal(uint16_t termt) +const char *names_audioterminal(u_int16_t termt) { struct audioterminal *at; @@ -258,7 +253,7 @@ const char *names_audioterminal(uint16_t termt) return NULL; } -const char *names_videoterminal(uint16_t termt) +const char *names_videoterminal(u_int16_t termt) { struct videoterminal *vt; @@ -271,7 +266,33 @@ const char *names_videoterminal(uint16_t termt) /* ---------------------------------------------------------------------- */ -static int new_vendor(const char *name, uint16_t vendorid) +int get_vendor_string(char *buf, size_t size, u_int16_t vid) +{ + const char *cp; + + if (size < 1) + return 0; + *buf = 0; + if (!(cp = names_vendor(vid))) + return 0; + return snprintf(buf, size, "%s", cp); +} + +int get_product_string(char *buf, size_t size, u_int16_t vid, u_int16_t pid) +{ + const char *cp; + + if (size < 1) + return 0; + *buf = 0; + if (!(cp = names_product(vid, pid))) + return 0; + return snprintf(buf, size, "%s", cp); +} + +/* ---------------------------------------------------------------------- */ + +static int new_vendor(const char *name, u_int16_t vendorid) { struct vendor *v; unsigned int h = hashnum(vendorid); @@ -290,7 +311,7 @@ static int new_vendor(const char *name, uint16_t vendorid) return 0; } -static int new_product(const char *name, uint16_t vendorid, uint16_t productid) +static int new_product(const char *name, u_int16_t vendorid, u_int16_t productid) { struct product *p; unsigned int h = hashnum((vendorid << 16) | productid); @@ -310,7 +331,7 @@ static int new_product(const char *name, uint16_t vendorid, uint16_t productid) return 0; } -static int new_class(const char *name, uint8_t classid) +static int new_class(const char *name, u_int8_t classid) { struct class *c; unsigned int h = hashnum(classid); @@ -329,7 +350,7 @@ static int new_class(const char *name, uint8_t classid) return 0; } -static int new_subclass(const char *name, uint8_t classid, uint8_t subclassid) +static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid) { struct subclass *s; unsigned int h = hashnum((classid << 8) | subclassid); @@ -349,7 +370,7 @@ static int new_subclass(const char *name, uint8_t classid, uint8_t subclassid) return 0; } -static int new_protocol(const char *name, uint8_t classid, uint8_t subclassid, uint8_t protocolid) +static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid) { struct protocol *p; unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid); @@ -370,7 +391,7 @@ static int new_protocol(const char *name, uint8_t classid, uint8_t subclassid, u return 0; } -static int new_audioterminal(const char *name, uint16_t termt) +static int new_audioterminal(const char *name, u_int16_t termt) { struct audioterminal *at; unsigned int h = hashnum(termt); @@ -389,7 +410,7 @@ static int new_audioterminal(const char *name, uint16_t termt) return 0; } -static int new_videoterminal(const char *name, uint16_t termt) +static int new_videoterminal(const char *name, u_int16_t termt) { struct videoterminal *vt; unsigned int h = hashnum(termt); @@ -408,30 +429,31 @@ static int new_videoterminal(const char *name, uint16_t termt) return 0; } -static int new_genericstrtable(struct genericstrtable *t[HASHSZ], const char *name, unsigned int index) +static int new_genericstrtable(struct genericstrtable *t[HASHSZ], + const char *name, unsigned int idx) { - struct genericstrtable *g; - unsigned int h = hashnum(index); - - for (g = t[h]; g; g = g->next) - if (g->num == index) - return -1; - g = malloc(sizeof(struct genericstrtable) + strlen(name)); - if (!g) - return -1; - strcpy(g->name, name); - g->num = index; - g->next = t[h]; - t[h] = g; - return 0; + struct genericstrtable *g; + unsigned int h = hashnum(idx); + + for (g = t[h]; g; g = g->next) + if (g->num == idx) + 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, uint8_t hidd) +static int new_hid(const char *name, u_int8_t hidd) { return new_genericstrtable(hiddescriptors, name, hidd); } -static int new_reporttag(const char *name, uint8_t rt) +static int new_reporttag(const char *name, u_int8_t rt) { return new_genericstrtable(reports, name, rt); } @@ -446,16 +468,16 @@ static int new_hutus(const char *name, unsigned int data) return new_genericstrtable(hutus, name, data); } -static int new_langid(const char *name, uint16_t langid) +static int new_langid(const char *name, u_int16_t langid) { return new_genericstrtable(langids, name, langid); } -static int new_physdes(const char *name, uint8_t ph) +static int new_physdes(const char *name, u_int8_t ph) { return new_genericstrtable(physdess, name, ph); } -static int new_bias(const char *name, uint8_t b) +static int new_bias(const char *name, u_int8_t b) { return new_genericstrtable(biass, name, b); } @@ -467,111 +489,250 @@ static int new_countrycode(const char *name, unsigned int countrycode) /* ---------------------------------------------------------------------- */ -#define DBG(x) +static void free_vendor(void) +{ + struct vendor *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = vendors[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } +} + +static void free_product(void) +{ + struct product *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = products[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } +} + +static void free_class(void) +{ + struct class *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = classes[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } +} + +static void free_subclass(void) +{ + struct subclass *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = subclasses[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } +} + +static void free_protocol(void) +{ + struct protocol *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = protocols[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } +} + +static void free_audioterminal(void) +{ + struct audioterminal *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = audioterminals[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } + return; +} + +static void free_videoterminal(void) +{ + struct videoterminal *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = videoterminals[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } +} + +static void _free_genericstrtable(struct genericstrtable *t[HASHSZ]) +{ + struct genericstrtable *cur, *tmp; + int i; + + for (i = 0; i < HASHSZ; i++) { + cur = t[i]; + while (cur) { + tmp = cur; + cur = cur->next; + free(tmp); + } + } +} + +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); +} + +#define DBG(x) static void parse(usb_file f) { char buf[512], *cp; unsigned int linectr = 0; - int lastvendor = -1, lastclass = -1, lastsubclass = -1, lasthut=-1, lastlang=-1; + 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 */ - if ((cp = strchr(buf, 13))) + cp = strchr(buf, 13); + if (cp) *cp = 0; - if ((cp = strchr(buf, 10))) + 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] == '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; @@ -639,24 +800,24 @@ static void parse(usb_file f) } 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; + 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 */ @@ -702,10 +863,10 @@ static void parse(usb_file f) continue; } if (lastlang != -1) { - if (new_langid(cp, lastlang+(u<<10))) - fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr); - continue; - } + 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; } @@ -729,69 +890,69 @@ static void parse(usb_file f) } 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; + 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); + 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; - - } + 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); } } @@ -801,13 +962,24 @@ static void parse(usb_file f) int names_init(char *n) { usb_file f; - if(init_done) - return 0; - init_done = 1; - if (!(f = usb_fopen(n, "r"))) { + + f = usb_fopen(n, "r"); + if (!f) return errno; - } + parse(f); usb_close(f); return 0; } + +void names_exit(void) +{ + free_vendor(); + free_product(); + free_class(); + free_subclass(); + free_protocol(); + free_audioterminal(); + free_videoterminal(); + free_genericstrtable(); +} diff --git a/names.h b/names.h index 71c27d4..8227a45 100644 --- a/names.h +++ b/names.h @@ -15,10 +15,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * * */ @@ -27,26 +23,32 @@ #ifndef _NAMES_H #define _NAMES_H -#include +#include /* ---------------------------------------------------------------------- */ -extern const char *names_vendor(uint16_t vendorid); -extern const char *names_product(uint16_t vendorid, uint16_t productid); -extern const char *names_class(uint8_t classid); -extern const char *names_subclass(uint8_t classid, uint8_t subclassid); -extern const char *names_protocol(uint8_t classid, uint8_t subclassid, uint8_t protocolid); -extern const char *names_audioterminal(uint16_t termt); -extern const char *names_videoterminal(uint16_t termt); -extern const char *names_hid(uint8_t hidd); -extern const char *names_reporttag(uint8_t rt); +extern const char *names_vendor(u_int16_t vendorid); +extern const char *names_product(u_int16_t vendorid, u_int16_t productid); +extern const char *names_class(u_int8_t classid); +extern const char *names_subclass(u_int8_t classid, u_int8_t subclassid); +extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, + u_int8_t protocolid); +extern const char *names_audioterminal(u_int16_t termt); +extern const char *names_videoterminal(u_int16_t termt); +extern const char *names_hid(u_int8_t hidd); +extern const char *names_reporttag(u_int8_t rt); extern const char *names_huts(unsigned int data); extern const char *names_hutus(unsigned int data); -extern const char *names_langid(uint16_t langid); -extern const char *names_physdes(uint8_t ph); -extern const char *names_bias(uint8_t b); +extern const char *names_langid(u_int16_t langid); +extern const char *names_physdes(u_int8_t ph); +extern const char *names_bias(u_int8_t b); extern const char *names_countrycode(unsigned int countrycode); + +extern int get_vendor_string(char *buf, size_t size, u_int16_t vid); +extern int get_product_string(char *buf, size_t size, u_int16_t vid, u_int16_t pid); + extern int names_init(char *n); +extern void names_exit(void); /* ---------------------------------------------------------------------- */ #endif /* _NAMES_H */ -- cgit v1.2.1