1 /*****************************************************************************/
2 /*
3  *      names.c  --  USB name database manipulation routines
4  *
5  *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
6  *
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.
11  *
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.
16  *
17  *      You should have received a copy of the GNU General Public License
18  *      along with this program; if not, write to the Free Software
19  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  *
22  */
23 
24 /*****************************************************************************/
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <dirent.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <stdio.h>
39 #include <ctype.h>
40 
41 #ifdef HAVE_LIBZ
42 #include <zlib.h>
43 #define 	usb_file			gzFile
44 #define 	usb_fopen(path, mode) 		gzopen(path, mode)
45 #define 	usb_fgets(s, size, stream)	gzgets(stream, s, size)
46 #define 	usb_close(f)			gzclose(f)
47 #else
48 #define 	usb_file			FILE *
49 #define 	usb_fopen(path, mode)		fopen(path, mode)
50 #define 	usb_fgets(s, size, stream)	fgets(s, size, stream)
51 #define 	usb_close(f)			fclose(f)
52 #endif
53 
54 #include "names.h"
55 
56 
57 /* ---------------------------------------------------------------------- */
58 
59 struct vendor {
60 	struct vendor *next;
61 	u_int16_t vendorid;
62 	char name[1];
63 };
64 
65 struct product {
66 	struct product *next;
67 	u_int16_t vendorid, productid;
68 	char name[1];
69 };
70 
71 struct class {
72 	struct class *next;
73 	u_int8_t classid;
74 	char name[1];
75 };
76 
77 struct subclass {
78 	struct subclass *next;
79 	u_int8_t classid, subclassid;
80 	char name[1];
81 };
82 
83 struct protocol {
84 	struct protocol *next;
85 	u_int8_t classid, subclassid, protocolid;
86 	char name[1];
87 };
88 
89 struct audioterminal {
90 	struct audioterminal *next;
91 	u_int16_t termt;
92 	char name[1];
93 };
94 
95 struct videoterminal {
96 	struct videoterminal *next;
97 	u_int16_t termt;
98 	char name[1];
99 };
100 
101 struct genericstrtable {
102 	struct genericstrtable *next;
103 	unsigned int num;
104 	char name[1];
105 };
106 
107 /* ---------------------------------------------------------------------- */
108 
109 #define HASH1  0x10
110 #define HASH2  0x02
111 #define HASHSZ 16
112 
hashnum(unsigned int num)113 static unsigned int hashnum(unsigned int num)
114 {
115 	unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27;
116 
117 	for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
118 		if (num & mask1)
119 			num ^= mask2;
120 	return num & (HASHSZ-1);
121 }
122 
123 /* ---------------------------------------------------------------------- */
124 
125 static struct vendor *vendors[HASHSZ] = { NULL, };
126 static struct product *products[HASHSZ] = { NULL, };
127 static struct class *classes[HASHSZ] = { NULL, };
128 static struct subclass *subclasses[HASHSZ] = { NULL, };
129 static struct protocol *protocols[HASHSZ] = { NULL, };
130 static struct audioterminal *audioterminals[HASHSZ] = { NULL, };
131 static struct videoterminal *videoterminals[HASHSZ] = { NULL, };
132 static struct genericstrtable *hiddescriptors[HASHSZ] = { NULL, };
133 static struct genericstrtable *reports[HASHSZ] = { NULL, };
134 static struct genericstrtable *huts[HASHSZ] = { NULL, };
135 static struct genericstrtable *biass[HASHSZ] = { NULL, };
136 static struct genericstrtable *physdess[HASHSZ] = { NULL, };
137 static struct genericstrtable *hutus[HASHSZ] = { NULL, };
138 static struct genericstrtable *langids[HASHSZ] = { NULL, };
139 static struct genericstrtable *countrycodes[HASHSZ] = { NULL, };
140 
141 /* ---------------------------------------------------------------------- */
142 
names_genericstrtable(struct genericstrtable * t[HASHSZ],unsigned int idx)143 static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ],
144 					 unsigned int idx)
145 {
146 	struct genericstrtable *h;
147 
148 	for (h = t[hashnum(idx)]; h; h = h->next)
149 		if (h->num == idx)
150 			return h->name;
151 	return NULL;
152 }
153 
names_hid(u_int8_t hidd)154 const char *names_hid(u_int8_t hidd)
155 {
156 	return names_genericstrtable(hiddescriptors, hidd);
157 }
158 
names_reporttag(u_int8_t rt)159 const char *names_reporttag(u_int8_t rt)
160 {
161 	return names_genericstrtable(reports, rt);
162 }
163 
names_huts(unsigned int data)164 const char *names_huts(unsigned int data)
165 {
166 	return names_genericstrtable(huts, data);
167 }
168 
names_hutus(unsigned int data)169 const char *names_hutus(unsigned int data)
170 {
171 	return names_genericstrtable(hutus, data);
172 }
173 
names_langid(u_int16_t langid)174 const char *names_langid(u_int16_t langid)
175 {
176 	return names_genericstrtable(langids, langid);
177 }
178 
names_physdes(u_int8_t ph)179 const char *names_physdes(u_int8_t ph)
180 {
181 	return names_genericstrtable(physdess, ph);
182 }
183 
names_bias(u_int8_t b)184 const char *names_bias(u_int8_t b)
185 {
186 	return names_genericstrtable(biass, b);
187 }
188 
names_countrycode(unsigned int countrycode)189 const char *names_countrycode(unsigned int countrycode)
190 {
191 	return names_genericstrtable(countrycodes, countrycode);
192 }
193 
names_vendor(u_int16_t vendorid)194 const char *names_vendor(u_int16_t vendorid)
195 {
196 	struct vendor *v;
197 
198 	v = vendors[hashnum(vendorid)];
199 	for (; v; v = v->next)
200 		if (v->vendorid == vendorid)
201 			return v->name;
202 	return NULL;
203 }
204 
names_product(u_int16_t vendorid,u_int16_t productid)205 const char *names_product(u_int16_t vendorid, u_int16_t productid)
206 {
207 	struct product *p;
208 
209 	p = products[hashnum((vendorid << 16) | productid)];
210 	for (; p; p = p->next)
211 		if (p->vendorid == vendorid && p->productid == productid)
212 			return p->name;
213 	return NULL;
214 }
215 
names_class(u_int8_t classid)216 const char *names_class(u_int8_t classid)
217 {
218 	struct class *c;
219 
220 	c = classes[hashnum(classid)];
221 	for (; c; c = c->next)
222 		if (c->classid == classid)
223 			return c->name;
224 	return NULL;
225 }
226 
names_subclass(u_int8_t classid,u_int8_t subclassid)227 const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
228 {
229 	struct subclass *s;
230 
231 	s = subclasses[hashnum((classid << 8) | subclassid)];
232 	for (; s; s = s->next)
233 		if (s->classid == classid && s->subclassid == subclassid)
234 			return s->name;
235 	return NULL;
236 }
237 
names_protocol(u_int8_t classid,u_int8_t subclassid,u_int8_t protocolid)238 const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid)
239 {
240 	struct protocol *p;
241 
242 	p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)];
243 	for (; p; p = p->next)
244 		if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
245 			return p->name;
246 	return NULL;
247 }
248 
names_audioterminal(u_int16_t termt)249 const char *names_audioterminal(u_int16_t termt)
250 {
251 	struct audioterminal *at;
252 
253 	at = audioterminals[hashnum(termt)];
254 	for (; at; at = at->next)
255 		if (at->termt == termt)
256 			return at->name;
257 	return NULL;
258 }
259 
names_videoterminal(u_int16_t termt)260 const char *names_videoterminal(u_int16_t termt)
261 {
262 	struct videoterminal *vt;
263 
264 	vt = videoterminals[hashnum(termt)];
265 	for (; vt; vt = vt->next)
266 		if (vt->termt == termt)
267 			return vt->name;
268 	return NULL;
269 }
270 
271 /* ---------------------------------------------------------------------- */
272 
new_vendor(const char * name,u_int16_t vendorid)273 static int new_vendor(const char *name, u_int16_t vendorid)
274 {
275 	struct vendor *v;
276 	unsigned int h = hashnum(vendorid);
277 
278 	v = vendors[h];
279 	for (; v; v = v->next)
280 		if (v->vendorid == vendorid)
281 			return -1;
282 	v = malloc(sizeof(struct vendor) + strlen(name));
283 	if (!v)
284 		return -1;
285 	strcpy(v->name, name);
286 	v->vendorid = vendorid;
287 	v->next = vendors[h];
288 	vendors[h] = v;
289 	return 0;
290 }
291 
new_product(const char * name,u_int16_t vendorid,u_int16_t productid)292 static int new_product(const char *name, u_int16_t vendorid, u_int16_t productid)
293 {
294 	struct product *p;
295 	unsigned int h = hashnum((vendorid << 16) | productid);
296 
297 	p = products[h];
298 	for (; p; p = p->next)
299 		if (p->vendorid == vendorid && p->productid == productid)
300 			return -1;
301 	p = malloc(sizeof(struct product) + strlen(name));
302 	if (!p)
303 		return -1;
304 	strcpy(p->name, name);
305 	p->vendorid = vendorid;
306 	p->productid = productid;
307 	p->next = products[h];
308 	products[h] = p;
309 	return 0;
310 }
311 
new_class(const char * name,u_int8_t classid)312 static int new_class(const char *name, u_int8_t classid)
313 {
314 	struct class *c;
315 	unsigned int h = hashnum(classid);
316 
317 	c = classes[h];
318 	for (; c; c = c->next)
319 		if (c->classid == classid)
320 			return -1;
321 	c = malloc(sizeof(struct class) + strlen(name));
322 	if (!c)
323 		return -1;
324 	strcpy(c->name, name);
325 	c->classid = classid;
326 	c->next = classes[h];
327 	classes[h] = c;
328 	return 0;
329 }
330 
new_subclass(const char * name,u_int8_t classid,u_int8_t subclassid)331 static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid)
332 {
333 	struct subclass *s;
334 	unsigned int h = hashnum((classid << 8) | subclassid);
335 
336 	s = subclasses[h];
337 	for (; s; s = s->next)
338 		if (s->classid == classid && s->subclassid == subclassid)
339 			return -1;
340 	s = malloc(sizeof(struct subclass) + strlen(name));
341 	if (!s)
342 		return -1;
343 	strcpy(s->name, name);
344 	s->classid = classid;
345 	s->subclassid = subclassid;
346 	s->next = subclasses[h];
347 	subclasses[h] = s;
348 	return 0;
349 }
350 
new_protocol(const char * name,u_int8_t classid,u_int8_t subclassid,u_int8_t protocolid)351 static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid)
352 {
353 	struct protocol *p;
354 	unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid);
355 
356 	p = protocols[h];
357 	for (; p; p = p->next)
358 		if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
359 			return -1;
360 	p = malloc(sizeof(struct protocol) + strlen(name));
361 	if (!p)
362 		return -1;
363 	strcpy(p->name, name);
364 	p->classid = classid;
365 	p->subclassid = subclassid;
366 	p->protocolid = protocolid;
367 	p->next = protocols[h];
368 	protocols[h] = p;
369 	return 0;
370 }
371 
new_audioterminal(const char * name,u_int16_t termt)372 static int new_audioterminal(const char *name, u_int16_t termt)
373 {
374 	struct audioterminal *at;
375 	unsigned int h = hashnum(termt);
376 
377 	at = audioterminals[h];
378 	for (; at; at = at->next)
379 		if (at->termt == termt)
380 			return -1;
381 	at = malloc(sizeof(struct audioterminal) + strlen(name));
382 	if (!at)
383 		return -1;
384 	strcpy(at->name, name);
385 	at->termt = termt;
386 	at->next = audioterminals[h];
387 	audioterminals[h] = at;
388 	return 0;
389 }
390 
new_videoterminal(const char * name,u_int16_t termt)391 static int new_videoterminal(const char *name, u_int16_t termt)
392 {
393 	struct videoterminal *vt;
394 	unsigned int h = hashnum(termt);
395 
396 	vt = videoterminals[h];
397 	for (; vt; vt = vt->next)
398 		if (vt->termt == termt)
399 			return -1;
400 	vt = malloc(sizeof(struct videoterminal) + strlen(name));
401 	if (!vt)
402 		return -1;
403 	strcpy(vt->name, name);
404 	vt->termt = termt;
405 	vt->next = videoterminals[h];
406 	videoterminals[h] = vt;
407 	return 0;
408 }
409 
new_genericstrtable(struct genericstrtable * t[HASHSZ],const char * name,unsigned int idx)410 static int new_genericstrtable(struct genericstrtable *t[HASHSZ],
411 			       const char *name, unsigned int idx)
412 {
413 	struct genericstrtable *g;
414 	unsigned int h = hashnum(idx);
415 
416 	for (g = t[h]; g; g = g->next)
417 		if (g->num == idx)
418 			return -1;
419 	g = malloc(sizeof(struct genericstrtable) + strlen(name));
420 	if (!g)
421 		return -1;
422 	strcpy(g->name, name);
423 	g->num = idx;
424 	g->next = t[h];
425 	t[h] = g;
426 	return 0;
427 }
428 
new_hid(const char * name,u_int8_t hidd)429 static int new_hid(const char *name, u_int8_t hidd)
430 {
431 	return new_genericstrtable(hiddescriptors, name, hidd);
432 }
433 
new_reporttag(const char * name,u_int8_t rt)434 static int new_reporttag(const char *name, u_int8_t rt)
435 {
436 	return new_genericstrtable(reports, name, rt);
437 }
438 
new_huts(const char * name,unsigned int data)439 static int new_huts(const char *name, unsigned int data)
440 {
441 	return new_genericstrtable(huts, name, data);
442 }
443 
new_hutus(const char * name,unsigned int data)444 static int new_hutus(const char *name, unsigned int data)
445 {
446 	return new_genericstrtable(hutus, name, data);
447 }
448 
new_langid(const char * name,u_int16_t langid)449 static int new_langid(const char *name, u_int16_t langid)
450 {
451 	return new_genericstrtable(langids, name, langid);
452 }
453 
new_physdes(const char * name,u_int8_t ph)454 static int new_physdes(const char *name, u_int8_t ph)
455 {
456 	return new_genericstrtable(physdess, name, ph);
457 }
new_bias(const char * name,u_int8_t b)458 static int new_bias(const char *name, u_int8_t b)
459 {
460 	return new_genericstrtable(biass, name, b);
461 }
462 
new_countrycode(const char * name,unsigned int countrycode)463 static int new_countrycode(const char *name, unsigned int countrycode)
464 {
465 	return new_genericstrtable(countrycodes, name, countrycode);
466 }
467 
468 /* ---------------------------------------------------------------------- */
469 
free_vendor(void)470 static void free_vendor(void)
471 {
472 	struct vendor *cur, *tmp;
473 	int i;
474 
475 	for (i = 0; i < HASHSZ; i++) {
476 		cur = vendors[i];
477 		while (cur) {
478 			tmp = cur;
479 			cur = cur->next;
480 			free(tmp);
481 		}
482 	}
483 }
484 
free_product(void)485 static void free_product(void)
486 {
487 	struct product *cur, *tmp;
488 	int i;
489 
490 	for (i = 0; i < HASHSZ; i++) {
491 		cur = products[i];
492 		while (cur) {
493 			tmp = cur;
494 			cur = cur->next;
495 			free(tmp);
496 		}
497 	}
498 }
499 
free_class(void)500 static void free_class(void)
501 {
502 	struct class *cur, *tmp;
503 	int i;
504 
505 	for (i = 0; i < HASHSZ; i++) {
506 		cur = classes[i];
507 		while (cur) {
508 			tmp = cur;
509 			cur = cur->next;
510 			free(tmp);
511 		}
512 	}
513 }
514 
free_subclass(void)515 static void free_subclass(void)
516 {
517 	struct subclass *cur, *tmp;
518 	int i;
519 
520 	for (i = 0; i < HASHSZ; i++) {
521 		cur = subclasses[i];
522 		while (cur) {
523 			tmp = cur;
524 			cur = cur->next;
525 			free(tmp);
526 		}
527 	}
528 }
529 
free_protocol(void)530 static void free_protocol(void)
531 {
532 	struct protocol *cur, *tmp;
533 	int i;
534 
535 	for (i = 0; i < HASHSZ; i++) {
536 		cur = protocols[i];
537 		while (cur) {
538 			tmp = cur;
539 			cur = cur->next;
540 			free(tmp);
541 		}
542 	}
543 }
544 
free_audioterminal(void)545 static void free_audioterminal(void)
546 {
547 	struct audioterminal *cur, *tmp;
548 	int i;
549 
550 	for (i = 0; i < HASHSZ; i++) {
551 		cur = audioterminals[i];
552 		while (cur) {
553 			tmp = cur;
554 			cur = cur->next;
555 			free(tmp);
556 		}
557 	}
558 	return;
559 }
560 
free_videoterminal(void)561 static void free_videoterminal(void)
562 {
563 	struct videoterminal *cur, *tmp;
564 	int i;
565 
566 	for (i = 0; i < HASHSZ; i++) {
567 		cur = videoterminals[i];
568 		while (cur) {
569 			tmp = cur;
570 			cur = cur->next;
571 			free(tmp);
572 		}
573 	}
574 }
575 
_free_genericstrtable(struct genericstrtable * t[HASHSZ])576 static void _free_genericstrtable(struct genericstrtable *t[HASHSZ])
577 {
578 	struct genericstrtable *cur, *tmp;
579 	int i;
580 
581 	for (i = 0; i < HASHSZ; i++) {
582 		cur = t[i];
583 		while (cur) {
584 			tmp = cur;
585 			cur = cur->next;
586 			free(tmp);
587 		}
588 	}
589 }
590 
free_genericstrtable(void)591 static void free_genericstrtable(void)
592 {
593 	_free_genericstrtable(hiddescriptors);
594 	_free_genericstrtable(reports);
595 	_free_genericstrtable(huts);
596 	_free_genericstrtable(biass);
597 	_free_genericstrtable(physdess);
598 	_free_genericstrtable(hutus);
599 	_free_genericstrtable(langids);
600 	_free_genericstrtable(countrycodes);
601 }
602 
603 #define DBG(x)
604 
parse(usb_file f)605 static void parse(usb_file f)
606 {
607 	char buf[512], *cp;
608 	unsigned int linectr = 0;
609 	int lastvendor = -1;
610 	int lastclass = -1;
611 	int lastsubclass = -1;
612 	int lasthut = -1;
613 	int lastlang = -1;
614 	unsigned int u;
615 
616 	while (usb_fgets(buf, sizeof(buf), f)) {
617 		linectr++;
618 		/* remove line ends */
619 		cp = strchr(buf, 13);
620 		if (cp)
621 			*cp = 0;
622 		cp = strchr(buf, 10);
623 		if (cp)
624 			*cp = 0;
625 		if (buf[0] == '#' || !buf[0])
626 			continue;
627 		cp = buf;
628 		if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' &&
629 		    buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') {
630 			cp = buf + 8;
631 			while (isspace(*cp))
632 				cp++;
633 			if (!isxdigit(*cp)) {
634 				fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
635 				continue;
636 			}
637 			u = strtoul(cp, &cp, 16);
638 			while (isspace(*cp))
639 				cp++;
640 			if (!*cp) {
641 				fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
642 				continue;
643 			}
644 			if (new_physdes(cp, u))
645 				fprintf(stderr, "Duplicate Physdes  type spec at line %u terminal type %04x %s\n", linectr, u, cp);
646 			DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp));
647 			continue;
648 
649 		}
650 		if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
651 			cp = buf + 4;
652 			while (isspace(*cp))
653 				cp++;
654 			if (!isxdigit(*cp)) {
655 				fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
656 				continue;
657 			}
658 			u = strtoul(cp, &cp, 16);
659 			while (isspace(*cp))
660 				cp++;
661 			if (!*cp) {
662 				fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
663 				continue;
664 			}
665 			if (new_physdes(cp, u))
666 				fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp);
667 			DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp));
668 			continue;
669 
670 		}
671 		if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
672 			cp = buf + 5;
673 			while (isspace(*cp))
674 				cp++;
675 			if (!isxdigit(*cp)) {
676 				fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
677 				continue;
678 			}
679 			u = strtoul(cp, &cp, 16);
680 			while (isspace(*cp))
681 				cp++;
682 			if (!*cp) {
683 				fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
684 				continue;
685 			}
686 			if (new_bias(cp, u))
687 				fprintf(stderr, "Duplicate BIAS  type spec at line %u terminal type %04x %s\n", linectr, u, cp);
688 			DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp));
689 			continue;
690 
691 		}
692 		if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
693 			cp =  buf+2;
694 			while (isspace(*cp))
695 				cp++;
696 			if (!isxdigit(*cp)) {
697 				fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
698 				continue;
699 			}
700 			u = strtoul(cp, &cp, 16);
701 			while (isspace(*cp))
702 				cp++;
703 			if (!*cp) {
704 				fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
705 				continue;
706 			}
707 			if (new_langid(cp, u))
708 				fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp);
709 			DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp));
710 			lasthut = lastclass = lastvendor = lastsubclass = -1;
711 			lastlang = u;
712 			continue;
713 		}
714 		if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
715 			/* class spec */
716 			cp = buf+2;
717 			while (isspace(*cp))
718 				cp++;
719 			if (!isxdigit(*cp)) {
720 				fprintf(stderr, "Invalid class spec at line %u\n", linectr);
721 				continue;
722 			}
723 			u = strtoul(cp, &cp, 16);
724 			while (isspace(*cp))
725 				cp++;
726 			if (!*cp) {
727 				fprintf(stderr, "Invalid class spec at line %u\n", linectr);
728 				continue;
729 			}
730 			if (new_class(cp, u))
731 				fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", linectr, u, cp);
732 			DBG(printf("line %5u class %02x %s\n", linectr, u, cp));
733 			lasthut = lastlang = lastvendor = lastsubclass = -1;
734 			lastclass = u;
735 			continue;
736 		}
737 		if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
738 			/* audio terminal type spec */
739 			cp = buf+3;
740 			while (isspace(*cp))
741 				cp++;
742 			if (!isxdigit(*cp)) {
743 				fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
744 				continue;
745 			}
746 			u = strtoul(cp, &cp, 16);
747 			while (isspace(*cp))
748 				cp++;
749 			if (!*cp) {
750 				fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
751 				continue;
752 			}
753 			if (new_audioterminal(cp, u))
754 				fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
755 			DBG(printf("line %5u audio terminal type %02x %s\n", linectr, u, cp));
756 			continue;
757 		}
758 		if (buf[0] == 'V' && buf[1] == 'T' && isspace(buf[2])) {
759 			/* video terminal type spec */
760 			cp = buf+3;
761 			while (isspace(*cp))
762 				cp++;
763 			if (!isxdigit(*cp)) {
764 				fprintf(stderr, "Invalid video terminal type at line %u\n", linectr);
765 				continue;
766 			}
767 			u = strtoul(cp, &cp, 16);
768 			while (isspace(*cp))
769 				cp++;
770 			if (!*cp) {
771 				fprintf(stderr, "Invalid video terminal type at line %u\n", linectr);
772 				continue;
773 			}
774 			if (new_videoterminal(cp, u))
775 				fprintf(stderr, "Duplicate video terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
776 			DBG(printf("line %5u video terminal type %02x %s\n", linectr, u, cp));
777 			continue;
778 		}
779 		if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) {
780 			/* HID Descriptor bCountryCode */
781 			cp =  buf+3;
782 			while (isspace(*cp))
783 				cp++;
784 			if (!isxdigit(*cp)) {
785 				fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
786 				continue;
787 			}
788 			u = strtoul(cp, &cp, 10);
789 			while (isspace(*cp))
790 				cp++;
791 			if (!*cp) {
792 				fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
793 				continue;
794 			}
795 			if (new_countrycode(cp, u))
796 				fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp);
797 			DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp));
798 			continue;
799 		}
800 		if (isxdigit(*cp)) {
801 			/* vendor */
802 			u = strtoul(cp, &cp, 16);
803 			while (isspace(*cp))
804 				cp++;
805 			if (!*cp) {
806 				fprintf(stderr, "Invalid vendor spec at line %u\n", linectr);
807 				continue;
808 			}
809 			if (new_vendor(cp, u))
810 				fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", linectr, u, cp);
811 			DBG(printf("line %5u vendor %04x %s\n", linectr, u, cp));
812 			lastvendor = u;
813 			lasthut = lastlang = lastclass = lastsubclass = -1;
814 			continue;
815 		}
816 		if (buf[0] == '\t' && isxdigit(buf[1])) {
817 			/* product or subclass spec */
818 			u = strtoul(buf+1, &cp, 16);
819 			while (isspace(*cp))
820 				cp++;
821 			if (!*cp) {
822 				fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr);
823 				continue;
824 			}
825 			if (lastvendor != -1) {
826 				if (new_product(cp, lastvendor, u))
827 					fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", linectr, lastvendor, u, cp);
828 				DBG(printf("line %5u product %04x:%04x %s\n", linectr, lastvendor, u, cp));
829 				continue;
830 			}
831 			if (lastclass != -1) {
832 				if (new_subclass(cp, lastclass, u))
833 					fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", linectr, lastclass, u, cp);
834 				DBG(printf("line %5u subclass %02x:%02x %s\n", linectr, lastclass, u, cp));
835 				lastsubclass = u;
836 				continue;
837 			}
838 			if (lasthut != -1) {
839 				if (new_hutus(cp, (lasthut << 16)+u))
840 					fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr);
841 				continue;
842 			}
843 			if (lastlang != -1) {
844 				if (new_langid(cp, lastlang+(u<<10)))
845 					fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr);
846 				continue;
847 			}
848 			fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr);
849 			continue;
850 		}
851 		if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
852 			/* protocol spec */
853 			u = strtoul(buf+2, &cp, 16);
854 			while (isspace(*cp))
855 				cp++;
856 			if (!*cp) {
857 				fprintf(stderr, "Invalid protocol spec at line %u\n", linectr);
858 				continue;
859 			}
860 			if (lastclass != -1 && lastsubclass != -1) {
861 				if (new_protocol(cp, lastclass, lastsubclass, u))
862 					fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp);
863 				DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp));
864 				continue;
865 			}
866 			fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", linectr);
867 			continue;
868 		}
869 		if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
870 			cp = buf + 4;
871 			while (isspace(*cp))
872 				cp++;
873 			if (!isxdigit(*cp)) {
874 				fprintf(stderr, "Invalid HID type at line %u\n", linectr);
875 				continue;
876 			}
877 			u = strtoul(cp, &cp, 16);
878 			while (isspace(*cp))
879 				cp++;
880 			if (!*cp) {
881 				fprintf(stderr, "Invalid HID type at line %u\n", linectr);
882 				continue;
883 			}
884 			if (new_hid(cp, u))
885 				fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp);
886 			DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp));
887 			continue;
888 
889 		}
890 		if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
891 			cp = buf + 4;
892 			while (isspace(*cp))
893 				cp++;
894 			if (!isxdigit(*cp)) {
895 				fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
896 				continue;
897 			}
898 			u = strtoul(cp, &cp, 16);
899 			while (isspace(*cp))
900 				cp++;
901 			if (!*cp) {
902 				fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
903 				continue;
904 			}
905 			if (new_huts(cp, u))
906 				fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp);
907 			lastlang = lastclass = lastvendor = lastsubclass = -1;
908 			lasthut = u;
909 			DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp));
910 			continue;
911 
912 		}
913 		if (buf[0] == 'R' && buf[1] == ' ') {
914 			cp = buf + 2;
915 			while (isspace(*cp))
916 				cp++;
917 			if (!isxdigit(*cp)) {
918 				fprintf(stderr, "Invalid Report type at line %u\n", linectr);
919 				continue;
920 			}
921 			u = strtoul(cp, &cp, 16);
922 			while (isspace(*cp))
923 				cp++;
924 			if (!*cp) {
925 				fprintf(stderr, "Invalid Report type at line %u\n", linectr);
926 				continue;
927 			}
928 			if (new_reporttag(cp, u))
929 				fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp);
930 			DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp));
931 			continue;
932 
933 		}
934 		fprintf(stderr, "Unknown line at line %u\n", linectr);
935 	}
936 }
937 
938 /* ---------------------------------------------------------------------- */
939 
names_init(char * n)940 int names_init(char *n)
941 {
942 	usb_file f;
943 
944 	f = usb_fopen(n, "r");
945 	if (!f)
946 		return errno;
947 
948 	parse(f);
949 	usb_close(f);
950 	return 0;
951 }
952 
names_exit(void)953 void names_exit(void)
954 {
955 	free_vendor();
956 	free_product();
957 	free_class();
958 	free_subclass();
959 	free_protocol();
960 	free_audioterminal();
961 	free_videoterminal();
962 	free_genericstrtable();
963 }
964