/[soft]/ldetect/branches/2/names.c
ViewVC logotype

Contents of /ldetect/branches/2/names.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6734 - (show annotations) (download)
Wed Dec 12 09:24:21 2012 UTC (11 years, 4 months ago) by tv
File MIME type: text/plain
File size: 24257 byte(s)
branch

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.30