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