Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
names.c
Go to the documentation of this file.
1 /*****************************************************************************/
2 /*
3  * names.c -- USB name database manipulation routines
4  *
5  * Copyright (C) 1999, 2000 Thomas Sailer ([email protected])
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  * Copyright (C) 2005 Takahiro Hirofuchi
26  * - names_deinit() is added.
27  */
28 
29 /*****************************************************************************/
30 
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <dirent.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <stdio.h>
40 #include <ctype.h>
41 
42 
43 #include "names.h"
44 
45 
46 /* ---------------------------------------------------------------------- */
47 
48 struct vendor {
49  struct vendor *next;
51  char name[1];
52 };
53 
54 struct product {
55  struct product *next;
57  char name[1];
58 };
59 
60 struct class {
61  struct class *next;
63  char name[1];
64 };
65 
66 struct subclass {
67  struct subclass *next;
69  char name[1];
70 };
71 
72 struct protocol {
73  struct protocol *next;
75  char name[1];
76 };
77 
78 struct audioterminal {
81  char name[1];
82 };
83 
86  unsigned int num;
87  char name[1];
88 };
89 
90 /* ---------------------------------------------------------------------- */
91 
92 #define HASH1 0x10
93 #define HASH2 0x02
94 #define HASHSZ 16
95 
96 static unsigned int hashnum(unsigned int num)
97 {
98  unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27;
99 
100  for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
101  if (num & mask1)
102  num ^= mask2;
103  return num & (HASHSZ-1);
104 }
105 
106 /* ---------------------------------------------------------------------- */
107 
108 static struct vendor *vendors[HASHSZ] = { NULL, };
109 static struct product *products[HASHSZ] = { NULL, };
110 static struct class *classes[HASHSZ] = { NULL, };
111 static struct subclass *subclasses[HASHSZ] = { NULL, };
112 static struct protocol *protocols[HASHSZ] = { NULL, };
113 static struct audioterminal *audioterminals[HASHSZ] = { NULL, };
114 static struct genericstrtable *hiddescriptors[HASHSZ] = { NULL, };
115 static struct genericstrtable *reports[HASHSZ] = { NULL, };
116 static struct genericstrtable *huts[HASHSZ] = { NULL, };
117 static struct genericstrtable *biass[HASHSZ] = { NULL, };
118 static struct genericstrtable *physdess[HASHSZ] = { NULL, };
119 static struct genericstrtable *hutus[HASHSZ] = { NULL, };
120 static struct genericstrtable *langids[HASHSZ] = { NULL, };
121 static struct genericstrtable *countrycodes[HASHSZ] = { NULL, };
122 
123 /* ---------------------------------------------------------------------- */
124 
125 static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], unsigned int index)
126 {
127  struct genericstrtable *h;
128 
129  for (h = t[hashnum(index)]; h; h = h->next)
130  if (h->num == index)
131  return h->name;
132  return NULL;
133 }
134 
135 const char *names_hid(u_int8_t hidd)
136 {
137  return names_genericstrtable(hiddescriptors, hidd);
138 }
139 
140 const char *names_reporttag(u_int8_t rt)
141 {
142  return names_genericstrtable(reports, rt);
143 }
144 
145 const char *names_huts(unsigned int data)
146 {
147  return names_genericstrtable(huts, data);
148 }
149 
150 const char *names_hutus(unsigned int data)
151 {
152  return names_genericstrtable(hutus, data);
153 }
154 
155 const char *names_langid(u_int16_t langid)
156 {
157  return names_genericstrtable(langids, langid);
158 }
159 
161 {
162  return names_genericstrtable(physdess, ph);
163 }
164 
165 const char *names_bias(u_int8_t b)
166 {
167  return names_genericstrtable(biass, b);
168 }
169 
170 const char *names_countrycode(unsigned int countrycode)
171 {
172  return names_genericstrtable(countrycodes, countrycode);
173 }
174 
175 const char *names_vendor(u_int16_t vendorid)
176 {
177  struct vendor *v;
178 
179  v = vendors[hashnum(vendorid)];
180  for (; v; v = v->next)
181  if (v->vendorid == vendorid)
182  return v->name;
183  return NULL;
184 }
185 
186 const char *names_product(u_int16_t vendorid, u_int16_t productid)
187 {
188  struct product *p;
189 
190  p = products[hashnum((vendorid << 16) | productid)];
191  for (; p; p = p->next)
192  if (p->vendorid == vendorid && p->productid == productid)
193  return p->name;
194  return NULL;
195 }
196 
197 const char *names_class(u_int8_t classid)
198 {
199  struct class *c;
200 
201  c = classes[hashnum(classid)];
202  for (; c; c = c->next)
203  if (c->classid == classid)
204  return c->name;
205  return NULL;
206 }
207 
208 const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
209 {
210  struct subclass *s;
211 
212  s = subclasses[hashnum((classid << 8) | subclassid)];
213  for (; s; s = s->next)
214  if (s->classid == classid && s->subclassid == subclassid)
215  return s->name;
216  return NULL;
217 }
218 
220 {
221  struct protocol *p;
222 
223  p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)];
224  for (; p; p = p->next)
225  if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
226  return p->name;
227  return NULL;
228 }
229 
230 const char *names_audioterminal(u_int16_t termt)
231 {
232  struct audioterminal *at;
233 
234  at = audioterminals[hashnum(termt)];
235  for (; at; at = at->next)
236  if (at->termt == termt)
237  return at->name;
238  return NULL;
239 }
240 
241 /* ---------------------------------------------------------------------- */
242 /* add a cleanup function by takahiro */
243 
244 struct pool {
245  struct pool *next;
246  void *mem;
247 };
248 
249 static struct pool *pool_head = NULL;
250 
251 static void *my_malloc(size_t size)
252 {
253  struct pool *p;
254 
255  p = calloc(1, sizeof(struct pool));
256  if (!p) {
257  free(p);
258  return NULL;
259  }
260 
261  p->mem = calloc(1, size);
262  if (!p->mem)
263  return NULL;
264 
265  p->next = pool_head;
266  pool_head = p;
267 
268  return p->mem;
269 }
270 
271 void names_free(void)
272 {
273  struct pool *pool;
274 
275  if (!pool_head)
276  return;
277 
278  for (pool = pool_head; pool != NULL; ) {
279  struct pool *tmp;
280 
281  if (pool->mem)
282  free(pool->mem);
283 
284  tmp = pool;
285  pool = pool->next;
286  free(tmp);
287  }
288 }
289 
290 /* ---------------------------------------------------------------------- */
291 
292 static int new_vendor(const char *name, u_int16_t vendorid)
293 {
294  struct vendor *v;
295  unsigned int h = hashnum(vendorid);
296 
297  v = vendors[h];
298  for (; v; v = v->next)
299  if (v->vendorid == vendorid)
300  return -1;
301  v = my_malloc(sizeof(struct vendor) + strlen(name));
302  if (!v)
303  return -1;
304  strcpy(v->name, name);
305  v->vendorid = vendorid;
306  v->next = vendors[h];
307  vendors[h] = v;
308  return 0;
309 }
310 
311 static int new_product(const char *name, u_int16_t vendorid, u_int16_t productid)
312 {
313  struct product *p;
314  unsigned int h = hashnum((vendorid << 16) | productid);
315 
316  p = products[h];
317  for (; p; p = p->next)
318  if (p->vendorid == vendorid && p->productid == productid)
319  return -1;
320  p = my_malloc(sizeof(struct product) + strlen(name));
321  if (!p)
322  return -1;
323  strcpy(p->name, name);
324  p->vendorid = vendorid;
325  p->productid = productid;
326  p->next = products[h];
327  products[h] = p;
328  return 0;
329 }
330 
331 static int new_class(const char *name, u_int8_t classid)
332 {
333  struct class *c;
334  unsigned int h = hashnum(classid);
335 
336  c = classes[h];
337  for (; c; c = c->next)
338  if (c->classid == classid)
339  return -1;
340  c = my_malloc(sizeof(struct class) + strlen(name));
341  if (!c)
342  return -1;
343  strcpy(c->name, name);
344  c->classid = classid;
345  c->next = classes[h];
346  classes[h] = c;
347  return 0;
348 }
349 
350 static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid)
351 {
352  struct subclass *s;
353  unsigned int h = hashnum((classid << 8) | subclassid);
354 
355  s = subclasses[h];
356  for (; s; s = s->next)
357  if (s->classid == classid && s->subclassid == subclassid)
358  return -1;
359  s = my_malloc(sizeof(struct subclass) + strlen(name));
360  if (!s)
361  return -1;
362  strcpy(s->name, name);
363  s->classid = classid;
364  s->subclassid = subclassid;
365  s->next = subclasses[h];
366  subclasses[h] = s;
367  return 0;
368 }
369 
370 static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid)
371 {
372  struct protocol *p;
373  unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid);
374 
375  p = protocols[h];
376  for (; p; p = p->next)
377  if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
378  return -1;
379  p = my_malloc(sizeof(struct protocol) + strlen(name));
380  if (!p)
381  return -1;
382  strcpy(p->name, name);
383  p->classid = classid;
384  p->subclassid = subclassid;
385  p->protocolid = protocolid;
386  p->next = protocols[h];
387  protocols[h] = p;
388  return 0;
389 }
390 
391 static int new_audioterminal(const char *name, u_int16_t termt)
392 {
393  struct audioterminal *at;
394  unsigned int h = hashnum(termt);
395 
396  at = audioterminals[h];
397  for (; at; at = at->next)
398  if (at->termt == termt)
399  return -1;
400  at = my_malloc(sizeof(struct audioterminal) + strlen(name));
401  if (!at)
402  return -1;
403  strcpy(at->name, name);
404  at->termt = termt;
405  at->next = audioterminals[h];
406  audioterminals[h] = at;
407  return 0;
408 }
409 
410 static int new_genericstrtable(struct genericstrtable *t[HASHSZ], const char *name, unsigned int index)
411 {
412  struct genericstrtable *g;
413  unsigned int h = hashnum(index);
414 
415  for (g = t[h]; g; g = g->next)
416  if (g->num == index)
417  return -1;
418  g = my_malloc(sizeof(struct genericstrtable) + strlen(name));
419  if (!g)
420  return -1;
421  strcpy(g->name, name);
422  g->num = index;
423  g->next = t[h];
424  t[h] = g;
425  return 0;
426 }
427 
428 static int new_hid(const char *name, u_int8_t hidd)
429 {
430  return new_genericstrtable(hiddescriptors, name, hidd);
431 }
432 
433 static int new_reporttag(const char *name, u_int8_t rt)
434 {
435  return new_genericstrtable(reports, name, rt);
436 }
437 
438 static int new_huts(const char *name, unsigned int data)
439 {
440  return new_genericstrtable(huts, name, data);
441 }
442 
443 static int new_hutus(const char *name, unsigned int data)
444 {
445  return new_genericstrtable(hutus, name, data);
446 }
447 
448 static int new_langid(const char *name, u_int16_t langid)
449 {
450  return new_genericstrtable(langids, name, langid);
451 }
452 
453 static int new_physdes(const char *name, u_int8_t ph)
454 {
455  return new_genericstrtable(physdess, name, ph);
456 }
457 static int new_bias(const char *name, u_int8_t b)
458 {
459  return new_genericstrtable(biass, name, b);
460 }
461 
462 static int new_countrycode(const char *name, unsigned int countrycode)
463 {
464  return new_genericstrtable(countrycodes, name, countrycode);
465 }
466 
467 /* ---------------------------------------------------------------------- */
468 
469 #define DBG(x)
470 
471 static void parse(FILE *f)
472 {
473  char buf[512], *cp;
474  unsigned int linectr = 0;
475  int lastvendor = -1, lastclass = -1, lastsubclass = -1, lasthut=-1, lastlang=-1;
476  unsigned int u;
477 
478  while (fgets(buf, sizeof(buf), f)) {
479  linectr++;
480  /* remove line ends */
481  if ((cp = strchr(buf, 13)))
482  *cp = 0;
483  if ((cp = strchr(buf, 10)))
484  *cp = 0;
485  if (buf[0] == '#' || !buf[0])
486  continue;
487  cp = buf;
488  if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' &&
489  buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') {
490  cp = buf + 8;
491  while (isspace(*cp))
492  cp++;
493  if (!isxdigit(*cp)) {
494  fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
495  continue;
496  }
497  u = strtoul(cp, &cp, 16);
498  while (isspace(*cp))
499  cp++;
500  if (!*cp) {
501  fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
502  continue;
503  }
504  if (new_physdes(cp, u))
505  fprintf(stderr, "Duplicate Physdes type spec at line %u terminal type %04x %s\n", linectr, u, cp);
506  DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp));
507  continue;
508 
509  }
510  if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
511  cp = buf + 4;
512  while (isspace(*cp))
513  cp++;
514  if (!isxdigit(*cp)) {
515  fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
516  continue;
517  }
518  u = strtoul(cp, &cp, 16);
519  while (isspace(*cp))
520  cp++;
521  if (!*cp) {
522  fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
523  continue;
524  }
525  if (new_physdes(cp, u))
526  fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp);
527  DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp));
528  continue;
529 
530  }
531  if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
532  cp = buf + 5;
533  while (isspace(*cp))
534  cp++;
535  if (!isxdigit(*cp)) {
536  fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
537  continue;
538  }
539  u = strtoul(cp, &cp, 16);
540  while (isspace(*cp))
541  cp++;
542  if (!*cp) {
543  fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
544  continue;
545  }
546  if (new_bias(cp, u))
547  fprintf(stderr, "Duplicate BIAS type spec at line %u terminal type %04x %s\n", linectr, u, cp);
548  DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp));
549  continue;
550 
551  }
552  if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
553  cp = buf+2;
554  while (isspace(*cp))
555  cp++;
556  if (!isxdigit(*cp)) {
557  fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
558  continue;
559  }
560  u = strtoul(cp, &cp, 16);
561  while (isspace(*cp))
562  cp++;
563  if (!*cp) {
564  fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
565  continue;
566  }
567  if (new_langid(cp, u))
568  fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp);
569  DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp));
570  lasthut = lastclass = lastvendor = lastsubclass = -1;
571  lastlang = u;
572  continue;
573  }
574  if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
575  /* class spec */
576  cp = buf+2;
577  while (isspace(*cp))
578  cp++;
579  if (!isxdigit(*cp)) {
580  fprintf(stderr, "Invalid class spec at line %u\n", linectr);
581  continue;
582  }
583  u = strtoul(cp, &cp, 16);
584  while (isspace(*cp))
585  cp++;
586  if (!*cp) {
587  fprintf(stderr, "Invalid class spec at line %u\n", linectr);
588  continue;
589  }
590  if (new_class(cp, u))
591  fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", linectr, u, cp);
592  DBG(printf("line %5u class %02x %s\n", linectr, u, cp));
593  lasthut = lastlang = lastvendor = lastsubclass = -1;
594  lastclass = u;
595  continue;
596  }
597  if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
598  /* audio terminal type spec */
599  cp = buf+3;
600  while (isspace(*cp))
601  cp++;
602  if (!isxdigit(*cp)) {
603  fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
604  continue;
605  }
606  u = strtoul(cp, &cp, 16);
607  while (isspace(*cp))
608  cp++;
609  if (!*cp) {
610  fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
611  continue;
612  }
613  if (new_audioterminal(cp, u))
614  fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
615  DBG(printf("line %5u audio terminal type %02x %s\n", linectr, u, cp));
616  continue;
617  }
618  if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) {
619  /* HID Descriptor bCountryCode */
620  cp = buf+3;
621  while (isspace(*cp))
622  cp++;
623  if (!isxdigit(*cp)) {
624  fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
625  continue;
626  }
627  u = strtoul(cp, &cp, 10);
628  while (isspace(*cp))
629  cp++;
630  if (!*cp) {
631  fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
632  continue;
633  }
634  if (new_countrycode(cp, u))
635  fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp);
636  DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp));
637  continue;
638  }
639  if (isxdigit(*cp)) {
640  /* vendor */
641  u = strtoul(cp, &cp, 16);
642  while (isspace(*cp))
643  cp++;
644  if (!*cp) {
645  fprintf(stderr, "Invalid vendor spec at line %u\n", linectr);
646  continue;
647  }
648  if (new_vendor(cp, u))
649  fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", linectr, u, cp);
650  DBG(printf("line %5u vendor %04x %s\n", linectr, u, cp));
651  lastvendor = u;
652  lasthut = lastlang = lastclass = lastsubclass = -1;
653  continue;
654  }
655  if (buf[0] == '\t' && isxdigit(buf[1])) {
656  /* product or subclass spec */
657  u = strtoul(buf+1, &cp, 16);
658  while (isspace(*cp))
659  cp++;
660  if (!*cp) {
661  fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr);
662  continue;
663  }
664  if (lastvendor != -1) {
665  if (new_product(cp, lastvendor, u))
666  fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", linectr, lastvendor, u, cp);
667  DBG(printf("line %5u product %04x:%04x %s\n", linectr, lastvendor, u, cp));
668  continue;
669  }
670  if (lastclass != -1) {
671  if (new_subclass(cp, lastclass, u))
672  fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", linectr, lastclass, u, cp);
673  DBG(printf("line %5u subclass %02x:%02x %s\n", linectr, lastclass, u, cp));
674  lastsubclass = u;
675  continue;
676  }
677  if (lasthut != -1) {
678  if (new_hutus(cp, (lasthut << 16)+u))
679  fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr);
680  continue;
681  }
682  if (lastlang != -1) {
683  if (new_langid(cp, lastlang+(u<<10)))
684  fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr);
685  continue;
686  }
687  fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr);
688  continue;
689  }
690  if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
691  /* protocol spec */
692  u = strtoul(buf+2, &cp, 16);
693  while (isspace(*cp))
694  cp++;
695  if (!*cp) {
696  fprintf(stderr, "Invalid protocol spec at line %u\n", linectr);
697  continue;
698  }
699  if (lastclass != -1 && lastsubclass != -1) {
700  if (new_protocol(cp, lastclass, lastsubclass, u))
701  fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp);
702  DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp));
703  continue;
704  }
705  fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", linectr);
706  continue;
707  }
708  if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
709  cp = buf + 4;
710  while (isspace(*cp))
711  cp++;
712  if (!isxdigit(*cp)) {
713  fprintf(stderr, "Invalid HID type at line %u\n", linectr);
714  continue;
715  }
716  u = strtoul(cp, &cp, 16);
717  while (isspace(*cp))
718  cp++;
719  if (!*cp) {
720  fprintf(stderr, "Invalid HID type at line %u\n", linectr);
721  continue;
722  }
723  if (new_hid(cp, u))
724  fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp);
725  DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp));
726  continue;
727 
728  }
729  if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
730  cp = buf + 4;
731  while (isspace(*cp))
732  cp++;
733  if (!isxdigit(*cp)) {
734  fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
735  continue;
736  }
737  u = strtoul(cp, &cp, 16);
738  while (isspace(*cp))
739  cp++;
740  if (!*cp) {
741  fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
742  continue;
743  }
744  if (new_huts(cp, u))
745  fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp);
746  lastlang = lastclass = lastvendor = lastsubclass = -1;
747  lasthut = u;
748  DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp));
749  continue;
750 
751  }
752  if (buf[0] == 'R' && buf[1] == ' ') {
753  cp = buf + 2;
754  while (isspace(*cp))
755  cp++;
756  if (!isxdigit(*cp)) {
757  fprintf(stderr, "Invalid Report type at line %u\n", linectr);
758  continue;
759  }
760  u = strtoul(cp, &cp, 16);
761  while (isspace(*cp))
762  cp++;
763  if (!*cp) {
764  fprintf(stderr, "Invalid Report type at line %u\n", linectr);
765  continue;
766  }
767  if (new_reporttag(cp, u))
768  fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp);
769  DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp));
770  continue;
771 
772  }
773  if (buf[0] == 'V' && buf[1] == 'T') {
774  /* add here */
775  continue;
776  }
777  fprintf(stderr, "Unknown line at line %u\n", linectr);
778  }
779 }
780 
781 /* ---------------------------------------------------------------------- */
782 
783 int names_init(char *n)
784 {
785  FILE *f;
786 
787  if (!(f = fopen(n, "r"))) {
788  return errno;
789  }
790  parse(f);
791  fclose(f);
792  return 0;
793 }