xref: /openbmc/linux/tools/usb/usbip/libsrc/names.c (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
1*74ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2588b48caSValentina Manea /*
3588b48caSValentina Manea  *      names.c  --  USB name database manipulation routines
4588b48caSValentina Manea  *
5588b48caSValentina Manea  *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
6588b48caSValentina Manea  *
7588b48caSValentina Manea  *	Copyright (C) 2005 Takahiro Hirofuchi
8588b48caSValentina Manea  *		- names_deinit() is added.
9588b48caSValentina Manea  */
10588b48caSValentina Manea 
11588b48caSValentina Manea #include <sys/types.h>
12588b48caSValentina Manea #include <sys/stat.h>
13588b48caSValentina Manea #include <fcntl.h>
14588b48caSValentina Manea #include <dirent.h>
15588b48caSValentina Manea #include <string.h>
16588b48caSValentina Manea #include <errno.h>
17588b48caSValentina Manea #include <stdlib.h>
18588b48caSValentina Manea #include <unistd.h>
19588b48caSValentina Manea #include <stdio.h>
20588b48caSValentina Manea #include <ctype.h>
21588b48caSValentina Manea 
22588b48caSValentina Manea #include "names.h"
23588b48caSValentina Manea #include "usbip_common.h"
24588b48caSValentina Manea 
25588b48caSValentina Manea struct vendor {
26588b48caSValentina Manea 	struct vendor *next;
27588b48caSValentina Manea 	u_int16_t vendorid;
28588b48caSValentina Manea 	char name[1];
29588b48caSValentina Manea };
30588b48caSValentina Manea 
31588b48caSValentina Manea struct product {
32588b48caSValentina Manea 	struct product *next;
33588b48caSValentina Manea 	u_int16_t vendorid, productid;
34588b48caSValentina Manea 	char name[1];
35588b48caSValentina Manea };
36588b48caSValentina Manea 
37588b48caSValentina Manea struct class {
38588b48caSValentina Manea 	struct class *next;
39588b48caSValentina Manea 	u_int8_t classid;
40588b48caSValentina Manea 	char name[1];
41588b48caSValentina Manea };
42588b48caSValentina Manea 
43588b48caSValentina Manea struct subclass {
44588b48caSValentina Manea 	struct subclass *next;
45588b48caSValentina Manea 	u_int8_t classid, subclassid;
46588b48caSValentina Manea 	char name[1];
47588b48caSValentina Manea };
48588b48caSValentina Manea 
49588b48caSValentina Manea struct protocol {
50588b48caSValentina Manea 	struct protocol *next;
51588b48caSValentina Manea 	u_int8_t classid, subclassid, protocolid;
52588b48caSValentina Manea 	char name[1];
53588b48caSValentina Manea };
54588b48caSValentina Manea 
55588b48caSValentina Manea struct genericstrtable {
56588b48caSValentina Manea 	struct genericstrtable *next;
57588b48caSValentina Manea 	unsigned int num;
58588b48caSValentina Manea 	char name[1];
59588b48caSValentina Manea };
60588b48caSValentina Manea 
61588b48caSValentina Manea 
62588b48caSValentina Manea #define HASH1  0x10
63588b48caSValentina Manea #define HASH2  0x02
64588b48caSValentina Manea #define HASHSZ 16
65588b48caSValentina Manea 
hashnum(unsigned int num)66588b48caSValentina Manea static unsigned int hashnum(unsigned int num)
67588b48caSValentina Manea {
68588b48caSValentina Manea 	unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27;
69588b48caSValentina Manea 
70588b48caSValentina Manea 	for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
71588b48caSValentina Manea 		if (num & mask1)
72588b48caSValentina Manea 			num ^= mask2;
73588b48caSValentina Manea 	return num & (HASHSZ-1);
74588b48caSValentina Manea }
75588b48caSValentina Manea 
76588b48caSValentina Manea 
77588b48caSValentina Manea static struct vendor *vendors[HASHSZ] = { NULL, };
78588b48caSValentina Manea static struct product *products[HASHSZ] = { NULL, };
79588b48caSValentina Manea static struct class *classes[HASHSZ] = { NULL, };
80588b48caSValentina Manea static struct subclass *subclasses[HASHSZ] = { NULL, };
81588b48caSValentina Manea static struct protocol *protocols[HASHSZ] = { NULL, };
82588b48caSValentina Manea 
names_vendor(u_int16_t vendorid)83588b48caSValentina Manea const char *names_vendor(u_int16_t vendorid)
84588b48caSValentina Manea {
85588b48caSValentina Manea 	struct vendor *v;
86588b48caSValentina Manea 
87588b48caSValentina Manea 	v = vendors[hashnum(vendorid)];
88588b48caSValentina Manea 	for (; v; v = v->next)
89588b48caSValentina Manea 		if (v->vendorid == vendorid)
90588b48caSValentina Manea 			return v->name;
91588b48caSValentina Manea 	return NULL;
92588b48caSValentina Manea }
93588b48caSValentina Manea 
names_product(u_int16_t vendorid,u_int16_t productid)94588b48caSValentina Manea const char *names_product(u_int16_t vendorid, u_int16_t productid)
95588b48caSValentina Manea {
96588b48caSValentina Manea 	struct product *p;
97588b48caSValentina Manea 
98588b48caSValentina Manea 	p = products[hashnum((vendorid << 16) | productid)];
99588b48caSValentina Manea 	for (; p; p = p->next)
100588b48caSValentina Manea 		if (p->vendorid == vendorid && p->productid == productid)
101588b48caSValentina Manea 			return p->name;
102588b48caSValentina Manea 	return NULL;
103588b48caSValentina Manea }
104588b48caSValentina Manea 
names_class(u_int8_t classid)105588b48caSValentina Manea const char *names_class(u_int8_t classid)
106588b48caSValentina Manea {
107588b48caSValentina Manea 	struct class *c;
108588b48caSValentina Manea 
109588b48caSValentina Manea 	c = classes[hashnum(classid)];
110588b48caSValentina Manea 	for (; c; c = c->next)
111588b48caSValentina Manea 		if (c->classid == classid)
112588b48caSValentina Manea 			return c->name;
113588b48caSValentina Manea 	return NULL;
114588b48caSValentina Manea }
115588b48caSValentina Manea 
names_subclass(u_int8_t classid,u_int8_t subclassid)116588b48caSValentina Manea const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
117588b48caSValentina Manea {
118588b48caSValentina Manea 	struct subclass *s;
119588b48caSValentina Manea 
120588b48caSValentina Manea 	s = subclasses[hashnum((classid << 8) | subclassid)];
121588b48caSValentina Manea 	for (; s; s = s->next)
122588b48caSValentina Manea 		if (s->classid == classid && s->subclassid == subclassid)
123588b48caSValentina Manea 			return s->name;
124588b48caSValentina Manea 	return NULL;
125588b48caSValentina Manea }
126588b48caSValentina Manea 
names_protocol(u_int8_t classid,u_int8_t subclassid,u_int8_t protocolid)127588b48caSValentina Manea const char *names_protocol(u_int8_t classid, u_int8_t subclassid,
128588b48caSValentina Manea 			   u_int8_t protocolid)
129588b48caSValentina Manea {
130588b48caSValentina Manea 	struct protocol *p;
131588b48caSValentina Manea 
132588b48caSValentina Manea 	p = protocols[hashnum((classid << 16) | (subclassid << 8)
133588b48caSValentina Manea 			      | protocolid)];
134588b48caSValentina Manea 	for (; p; p = p->next)
135588b48caSValentina Manea 		if (p->classid == classid && p->subclassid == subclassid &&
136588b48caSValentina Manea 		    p->protocolid == protocolid)
137588b48caSValentina Manea 			return p->name;
138588b48caSValentina Manea 	return NULL;
139588b48caSValentina Manea }
140588b48caSValentina Manea 
141588b48caSValentina Manea /* add a cleanup function by takahiro */
142588b48caSValentina Manea struct pool {
143588b48caSValentina Manea 	struct pool *next;
144588b48caSValentina Manea 	void *mem;
145588b48caSValentina Manea };
146588b48caSValentina Manea 
147588b48caSValentina Manea static struct pool *pool_head;
148588b48caSValentina Manea 
my_malloc(size_t size)149588b48caSValentina Manea static void *my_malloc(size_t size)
150588b48caSValentina Manea {
151588b48caSValentina Manea 	struct pool *p;
152588b48caSValentina Manea 
153588b48caSValentina Manea 	p = calloc(1, sizeof(struct pool));
154588b48caSValentina Manea 	if (!p)
155588b48caSValentina Manea 		return NULL;
156588b48caSValentina Manea 
157588b48caSValentina Manea 	p->mem = calloc(1, size);
158588b48caSValentina Manea 	if (!p->mem) {
159588b48caSValentina Manea 		free(p);
160588b48caSValentina Manea 		return NULL;
161588b48caSValentina Manea 	}
162588b48caSValentina Manea 
163588b48caSValentina Manea 	p->next = pool_head;
164588b48caSValentina Manea 	pool_head = p;
165588b48caSValentina Manea 
166588b48caSValentina Manea 	return p->mem;
167588b48caSValentina Manea }
168588b48caSValentina Manea 
names_free(void)169588b48caSValentina Manea void names_free(void)
170588b48caSValentina Manea {
171588b48caSValentina Manea 	struct pool *pool;
172588b48caSValentina Manea 
173588b48caSValentina Manea 	if (!pool_head)
174588b48caSValentina Manea 		return;
175588b48caSValentina Manea 
176588b48caSValentina Manea 	for (pool = pool_head; pool != NULL; ) {
177588b48caSValentina Manea 		struct pool *tmp;
178588b48caSValentina Manea 
179588b48caSValentina Manea 		if (pool->mem)
180588b48caSValentina Manea 			free(pool->mem);
181588b48caSValentina Manea 
182588b48caSValentina Manea 		tmp = pool;
183588b48caSValentina Manea 		pool = pool->next;
184588b48caSValentina Manea 		free(tmp);
185588b48caSValentina Manea 	}
186588b48caSValentina Manea }
187588b48caSValentina Manea 
new_vendor(const char * name,u_int16_t vendorid)188588b48caSValentina Manea static int new_vendor(const char *name, u_int16_t vendorid)
189588b48caSValentina Manea {
190588b48caSValentina Manea 	struct vendor *v;
191588b48caSValentina Manea 	unsigned int h = hashnum(vendorid);
192588b48caSValentina Manea 
193588b48caSValentina Manea 	v = vendors[h];
194588b48caSValentina Manea 	for (; v; v = v->next)
195588b48caSValentina Manea 		if (v->vendorid == vendorid)
196588b48caSValentina Manea 			return -1;
197588b48caSValentina Manea 	v = my_malloc(sizeof(struct vendor) + strlen(name));
198588b48caSValentina Manea 	if (!v)
199588b48caSValentina Manea 		return -1;
200588b48caSValentina Manea 	strcpy(v->name, name);
201588b48caSValentina Manea 	v->vendorid = vendorid;
202588b48caSValentina Manea 	v->next = vendors[h];
203588b48caSValentina Manea 	vendors[h] = v;
204588b48caSValentina Manea 	return 0;
205588b48caSValentina Manea }
206588b48caSValentina Manea 
new_product(const char * name,u_int16_t vendorid,u_int16_t productid)207588b48caSValentina Manea static int new_product(const char *name, u_int16_t vendorid,
208588b48caSValentina Manea 		       u_int16_t productid)
209588b48caSValentina Manea {
210588b48caSValentina Manea 	struct product *p;
211588b48caSValentina Manea 	unsigned int h = hashnum((vendorid << 16) | productid);
212588b48caSValentina Manea 
213588b48caSValentina Manea 	p = products[h];
214588b48caSValentina Manea 	for (; p; p = p->next)
215588b48caSValentina Manea 		if (p->vendorid == vendorid && p->productid == productid)
216588b48caSValentina Manea 			return -1;
217588b48caSValentina Manea 	p = my_malloc(sizeof(struct product) + strlen(name));
218588b48caSValentina Manea 	if (!p)
219588b48caSValentina Manea 		return -1;
220588b48caSValentina Manea 	strcpy(p->name, name);
221588b48caSValentina Manea 	p->vendorid = vendorid;
222588b48caSValentina Manea 	p->productid = productid;
223588b48caSValentina Manea 	p->next = products[h];
224588b48caSValentina Manea 	products[h] = p;
225588b48caSValentina Manea 	return 0;
226588b48caSValentina Manea }
227588b48caSValentina Manea 
new_class(const char * name,u_int8_t classid)228588b48caSValentina Manea static int new_class(const char *name, u_int8_t classid)
229588b48caSValentina Manea {
230588b48caSValentina Manea 	struct class *c;
231588b48caSValentina Manea 	unsigned int h = hashnum(classid);
232588b48caSValentina Manea 
233588b48caSValentina Manea 	c = classes[h];
234588b48caSValentina Manea 	for (; c; c = c->next)
235588b48caSValentina Manea 		if (c->classid == classid)
236588b48caSValentina Manea 			return -1;
237588b48caSValentina Manea 	c = my_malloc(sizeof(struct class) + strlen(name));
238588b48caSValentina Manea 	if (!c)
239588b48caSValentina Manea 		return -1;
240588b48caSValentina Manea 	strcpy(c->name, name);
241588b48caSValentina Manea 	c->classid = classid;
242588b48caSValentina Manea 	c->next = classes[h];
243588b48caSValentina Manea 	classes[h] = c;
244588b48caSValentina Manea 	return 0;
245588b48caSValentina Manea }
246588b48caSValentina Manea 
new_subclass(const char * name,u_int8_t classid,u_int8_t subclassid)247588b48caSValentina Manea static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid)
248588b48caSValentina Manea {
249588b48caSValentina Manea 	struct subclass *s;
250588b48caSValentina Manea 	unsigned int h = hashnum((classid << 8) | subclassid);
251588b48caSValentina Manea 
252588b48caSValentina Manea 	s = subclasses[h];
253588b48caSValentina Manea 	for (; s; s = s->next)
254588b48caSValentina Manea 		if (s->classid == classid && s->subclassid == subclassid)
255588b48caSValentina Manea 			return -1;
256588b48caSValentina Manea 	s = my_malloc(sizeof(struct subclass) + strlen(name));
257588b48caSValentina Manea 	if (!s)
258588b48caSValentina Manea 		return -1;
259588b48caSValentina Manea 	strcpy(s->name, name);
260588b48caSValentina Manea 	s->classid = classid;
261588b48caSValentina Manea 	s->subclassid = subclassid;
262588b48caSValentina Manea 	s->next = subclasses[h];
263588b48caSValentina Manea 	subclasses[h] = s;
264588b48caSValentina Manea 	return 0;
265588b48caSValentina Manea }
266588b48caSValentina Manea 
new_protocol(const char * name,u_int8_t classid,u_int8_t subclassid,u_int8_t protocolid)267588b48caSValentina Manea static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid,
268588b48caSValentina Manea 			u_int8_t protocolid)
269588b48caSValentina Manea {
270588b48caSValentina Manea 	struct protocol *p;
271588b48caSValentina Manea 	unsigned int h = hashnum((classid << 16) | (subclassid << 8)
272588b48caSValentina Manea 				 | protocolid);
273588b48caSValentina Manea 
274588b48caSValentina Manea 	p = protocols[h];
275588b48caSValentina Manea 	for (; p; p = p->next)
276588b48caSValentina Manea 		if (p->classid == classid && p->subclassid == subclassid
277588b48caSValentina Manea 		    && p->protocolid == protocolid)
278588b48caSValentina Manea 			return -1;
279588b48caSValentina Manea 	p = my_malloc(sizeof(struct protocol) + strlen(name));
280588b48caSValentina Manea 	if (!p)
281588b48caSValentina Manea 		return -1;
282588b48caSValentina Manea 	strcpy(p->name, name);
283588b48caSValentina Manea 	p->classid = classid;
284588b48caSValentina Manea 	p->subclassid = subclassid;
285588b48caSValentina Manea 	p->protocolid = protocolid;
286588b48caSValentina Manea 	p->next = protocols[h];
287588b48caSValentina Manea 	protocols[h] = p;
288588b48caSValentina Manea 	return 0;
289588b48caSValentina Manea }
290588b48caSValentina Manea 
parse(FILE * f)291588b48caSValentina Manea static void parse(FILE *f)
292588b48caSValentina Manea {
293588b48caSValentina Manea 	char buf[512], *cp;
294588b48caSValentina Manea 	unsigned int linectr = 0;
295588b48caSValentina Manea 	int lastvendor = -1;
296588b48caSValentina Manea 	int lastclass = -1;
297588b48caSValentina Manea 	int lastsubclass = -1;
298588b48caSValentina Manea 	int lasthut = -1;
299588b48caSValentina Manea 	int lastlang = -1;
300588b48caSValentina Manea 	unsigned int u;
301588b48caSValentina Manea 
302588b48caSValentina Manea 	while (fgets(buf, sizeof(buf), f)) {
303588b48caSValentina Manea 		linectr++;
304588b48caSValentina Manea 		/* remove line ends */
305588b48caSValentina Manea 		cp = strchr(buf, '\r');
306588b48caSValentina Manea 		if (cp)
307588b48caSValentina Manea 			*cp = 0;
308588b48caSValentina Manea 		cp = strchr(buf, '\n');
309588b48caSValentina Manea 		if (cp)
310588b48caSValentina Manea 			*cp = 0;
311588b48caSValentina Manea 		if (buf[0] == '#' || !buf[0])
312588b48caSValentina Manea 			continue;
313588b48caSValentina Manea 		cp = buf;
314588b48caSValentina Manea 		if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' &&
315588b48caSValentina Manea 		    buf[3] == 'S' && buf[4] == 'D' &&
316588b48caSValentina Manea 		    buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/
317588b48caSValentina Manea 		    buf[7] == ' ') {
318588b48caSValentina Manea 			continue;
319588b48caSValentina Manea 		}
320588b48caSValentina Manea 		if (buf[0] == 'P' && buf[1] == 'H' &&
321588b48caSValentina Manea 		    buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
322588b48caSValentina Manea 			continue;
323588b48caSValentina Manea 		}
324588b48caSValentina Manea 		if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' &&
325588b48caSValentina Manea 		    buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
326588b48caSValentina Manea 			continue;
327588b48caSValentina Manea 		}
328588b48caSValentina Manea 		if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
329588b48caSValentina Manea 			lasthut = lastclass = lastvendor = lastsubclass = -1;
330588b48caSValentina Manea 			/*
331588b48caSValentina Manea 			 * set 1 as pseudo-id to indicate that the parser is
332588b48caSValentina Manea 			 * in a `L' section.
333588b48caSValentina Manea 			 */
334588b48caSValentina Manea 			lastlang = 1;
335588b48caSValentina Manea 			continue;
336588b48caSValentina Manea 		}
337588b48caSValentina Manea 		if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
338588b48caSValentina Manea 			/* class spec */
339588b48caSValentina Manea 			cp = buf+2;
340588b48caSValentina Manea 			while (isspace(*cp))
341588b48caSValentina Manea 				cp++;
342588b48caSValentina Manea 			if (!isxdigit(*cp)) {
343588b48caSValentina Manea 				err("Invalid class spec at line %u", linectr);
344588b48caSValentina Manea 				continue;
345588b48caSValentina Manea 			}
346588b48caSValentina Manea 			u = strtoul(cp, &cp, 16);
347588b48caSValentina Manea 			while (isspace(*cp))
348588b48caSValentina Manea 				cp++;
349588b48caSValentina Manea 			if (!*cp) {
350588b48caSValentina Manea 				err("Invalid class spec at line %u", linectr);
351588b48caSValentina Manea 				continue;
352588b48caSValentina Manea 			}
353588b48caSValentina Manea 			if (new_class(cp, u))
354588b48caSValentina Manea 				err("Duplicate class spec at line %u class %04x %s",
355588b48caSValentina Manea 				    linectr, u, cp);
356588b48caSValentina Manea 			dbg("line %5u class %02x %s", linectr, u, cp);
357588b48caSValentina Manea 			lasthut = lastlang = lastvendor = lastsubclass = -1;
358588b48caSValentina Manea 			lastclass = u;
359588b48caSValentina Manea 			continue;
360588b48caSValentina Manea 		}
361588b48caSValentina Manea 		if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
362588b48caSValentina Manea 			/* audio terminal type spec */
363588b48caSValentina Manea 			continue;
364588b48caSValentina Manea 		}
365588b48caSValentina Manea 		if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C'
366588b48caSValentina Manea 		    && isspace(buf[3])) {
367588b48caSValentina Manea 			/* HID Descriptor bCountryCode */
368588b48caSValentina Manea 			continue;
369588b48caSValentina Manea 		}
370588b48caSValentina Manea 		if (isxdigit(*cp)) {
371588b48caSValentina Manea 			/* vendor */
372588b48caSValentina Manea 			u = strtoul(cp, &cp, 16);
373588b48caSValentina Manea 			while (isspace(*cp))
374588b48caSValentina Manea 				cp++;
375588b48caSValentina Manea 			if (!*cp) {
376588b48caSValentina Manea 				err("Invalid vendor spec at line %u", linectr);
377588b48caSValentina Manea 				continue;
378588b48caSValentina Manea 			}
379588b48caSValentina Manea 			if (new_vendor(cp, u))
380588b48caSValentina Manea 				err("Duplicate vendor spec at line %u vendor %04x %s",
381588b48caSValentina Manea 				    linectr, u, cp);
382588b48caSValentina Manea 			dbg("line %5u vendor %04x %s", linectr, u, cp);
383588b48caSValentina Manea 			lastvendor = u;
384588b48caSValentina Manea 			lasthut = lastlang = lastclass = lastsubclass = -1;
385588b48caSValentina Manea 			continue;
386588b48caSValentina Manea 		}
387588b48caSValentina Manea 		if (buf[0] == '\t' && isxdigit(buf[1])) {
388588b48caSValentina Manea 			/* product or subclass spec */
389588b48caSValentina Manea 			u = strtoul(buf+1, &cp, 16);
390588b48caSValentina Manea 			while (isspace(*cp))
391588b48caSValentina Manea 				cp++;
392588b48caSValentina Manea 			if (!*cp) {
393588b48caSValentina Manea 				err("Invalid product/subclass spec at line %u",
394588b48caSValentina Manea 				    linectr);
395588b48caSValentina Manea 				continue;
396588b48caSValentina Manea 			}
397588b48caSValentina Manea 			if (lastvendor != -1) {
398588b48caSValentina Manea 				if (new_product(cp, lastvendor, u))
399588b48caSValentina Manea 					err("Duplicate product spec at line %u product %04x:%04x %s",
400588b48caSValentina Manea 					    linectr, lastvendor, u, cp);
401588b48caSValentina Manea 				dbg("line %5u product %04x:%04x %s", linectr,
402588b48caSValentina Manea 				    lastvendor, u, cp);
403588b48caSValentina Manea 				continue;
404588b48caSValentina Manea 			}
405588b48caSValentina Manea 			if (lastclass != -1) {
406588b48caSValentina Manea 				if (new_subclass(cp, lastclass, u))
407588b48caSValentina Manea 					err("Duplicate subclass spec at line %u class %02x:%02x %s",
408588b48caSValentina Manea 					    linectr, lastclass, u, cp);
409588b48caSValentina Manea 				dbg("line %5u subclass %02x:%02x %s", linectr,
410588b48caSValentina Manea 				    lastclass, u, cp);
411588b48caSValentina Manea 				lastsubclass = u;
412588b48caSValentina Manea 				continue;
413588b48caSValentina Manea 			}
414588b48caSValentina Manea 			if (lasthut != -1) {
415588b48caSValentina Manea 				/* do not store hut */
416588b48caSValentina Manea 				continue;
417588b48caSValentina Manea 			}
418588b48caSValentina Manea 			if (lastlang != -1) {
419588b48caSValentina Manea 				/* do not store langid */
420588b48caSValentina Manea 				continue;
421588b48caSValentina Manea 			}
422588b48caSValentina Manea 			err("Product/Subclass spec without prior Vendor/Class spec at line %u",
423588b48caSValentina Manea 			    linectr);
424588b48caSValentina Manea 			continue;
425588b48caSValentina Manea 		}
426588b48caSValentina Manea 		if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
427588b48caSValentina Manea 			/* protocol spec */
428588b48caSValentina Manea 			u = strtoul(buf+2, &cp, 16);
429588b48caSValentina Manea 			while (isspace(*cp))
430588b48caSValentina Manea 				cp++;
431588b48caSValentina Manea 			if (!*cp) {
432588b48caSValentina Manea 				err("Invalid protocol spec at line %u",
433588b48caSValentina Manea 				    linectr);
434588b48caSValentina Manea 				continue;
435588b48caSValentina Manea 			}
436588b48caSValentina Manea 			if (lastclass != -1 && lastsubclass != -1) {
437588b48caSValentina Manea 				if (new_protocol(cp, lastclass, lastsubclass,
438588b48caSValentina Manea 						 u))
439588b48caSValentina Manea 					err("Duplicate protocol spec at line %u class %02x:%02x:%02x %s",
440588b48caSValentina Manea 					    linectr, lastclass, lastsubclass,
441588b48caSValentina Manea 					    u, cp);
442588b48caSValentina Manea 				dbg("line %5u protocol %02x:%02x:%02x %s",
443588b48caSValentina Manea 				    linectr, lastclass, lastsubclass, u, cp);
444588b48caSValentina Manea 				continue;
445588b48caSValentina Manea 			}
446588b48caSValentina Manea 			err("Protocol spec without prior Class and Subclass spec at line %u",
447588b48caSValentina Manea 			    linectr);
448588b48caSValentina Manea 			continue;
449588b48caSValentina Manea 		}
450588b48caSValentina Manea 		if (buf[0] == 'H' && buf[1] == 'I' &&
451588b48caSValentina Manea 		    buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
452588b48caSValentina Manea 			continue;
453588b48caSValentina Manea 		}
454588b48caSValentina Manea 		if (buf[0] == 'H' && buf[1] == 'U' &&
455588b48caSValentina Manea 		    buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
456588b48caSValentina Manea 			lastlang = lastclass = lastvendor = lastsubclass = -1;
457588b48caSValentina Manea 			/*
458588b48caSValentina Manea 			 * set 1 as pseudo-id to indicate that the parser is
459588b48caSValentina Manea 			 * in a `HUT' section.
460588b48caSValentina Manea 			 */
461588b48caSValentina Manea 			lasthut = 1;
462588b48caSValentina Manea 			continue;
463588b48caSValentina Manea 		}
464588b48caSValentina Manea 		if (buf[0] == 'R' && buf[1] == ' ')
465588b48caSValentina Manea 			continue;
466588b48caSValentina Manea 
467588b48caSValentina Manea 		if (buf[0] == 'V' && buf[1] == 'T')
468588b48caSValentina Manea 			continue;
469588b48caSValentina Manea 
470588b48caSValentina Manea 		err("Unknown line at line %u", linectr);
471588b48caSValentina Manea 	}
472588b48caSValentina Manea }
473588b48caSValentina Manea 
474588b48caSValentina Manea 
names_init(char * n)475588b48caSValentina Manea int names_init(char *n)
476588b48caSValentina Manea {
477588b48caSValentina Manea 	FILE *f;
478588b48caSValentina Manea 
479588b48caSValentina Manea 	f = fopen(n, "r");
480588b48caSValentina Manea 	if (!f)
481588b48caSValentina Manea 		return errno;
482588b48caSValentina Manea 
483588b48caSValentina Manea 	parse(f);
484588b48caSValentina Manea 	fclose(f);
485588b48caSValentina Manea 	return 0;
486588b48caSValentina Manea }
487