names.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /*
  2. * names.c -- USB name database manipulation routines
  3. *
  4. * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. *
  21. *
  22. *
  23. *
  24. * Copyright (C) 2005 Takahiro Hirofuchi
  25. * - names_deinit() is added.
  26. *
  27. */
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <fcntl.h>
  31. #include <dirent.h>
  32. #include <string.h>
  33. #include <errno.h>
  34. #include <stdlib.h>
  35. #include <unistd.h>
  36. #include <stdio.h>
  37. #include <ctype.h>
  38. #include "names.h"
  39. #include "usbip_common.h"
  40. struct vendor {
  41. struct vendor *next;
  42. u_int16_t vendorid;
  43. char name[1];
  44. };
  45. struct product {
  46. struct product *next;
  47. u_int16_t vendorid, productid;
  48. char name[1];
  49. };
  50. struct class {
  51. struct class *next;
  52. u_int8_t classid;
  53. char name[1];
  54. };
  55. struct subclass {
  56. struct subclass *next;
  57. u_int8_t classid, subclassid;
  58. char name[1];
  59. };
  60. struct protocol {
  61. struct protocol *next;
  62. u_int8_t classid, subclassid, protocolid;
  63. char name[1];
  64. };
  65. struct genericstrtable {
  66. struct genericstrtable *next;
  67. unsigned int num;
  68. char name[1];
  69. };
  70. #define HASH1 0x10
  71. #define HASH2 0x02
  72. #define HASHSZ 16
  73. static unsigned int hashnum(unsigned int num)
  74. {
  75. unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27;
  76. for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
  77. if (num & mask1)
  78. num ^= mask2;
  79. return num & (HASHSZ-1);
  80. }
  81. static struct vendor *vendors[HASHSZ] = { NULL, };
  82. static struct product *products[HASHSZ] = { NULL, };
  83. static struct class *classes[HASHSZ] = { NULL, };
  84. static struct subclass *subclasses[HASHSZ] = { NULL, };
  85. static struct protocol *protocols[HASHSZ] = { NULL, };
  86. const char *names_vendor(u_int16_t vendorid)
  87. {
  88. struct vendor *v;
  89. v = vendors[hashnum(vendorid)];
  90. for (; v; v = v->next)
  91. if (v->vendorid == vendorid)
  92. return v->name;
  93. return NULL;
  94. }
  95. const char *names_product(u_int16_t vendorid, u_int16_t productid)
  96. {
  97. struct product *p;
  98. p = products[hashnum((vendorid << 16) | productid)];
  99. for (; p; p = p->next)
  100. if (p->vendorid == vendorid && p->productid == productid)
  101. return p->name;
  102. return NULL;
  103. }
  104. const char *names_class(u_int8_t classid)
  105. {
  106. struct class *c;
  107. c = classes[hashnum(classid)];
  108. for (; c; c = c->next)
  109. if (c->classid == classid)
  110. return c->name;
  111. return NULL;
  112. }
  113. const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
  114. {
  115. struct subclass *s;
  116. s = subclasses[hashnum((classid << 8) | subclassid)];
  117. for (; s; s = s->next)
  118. if (s->classid == classid && s->subclassid == subclassid)
  119. return s->name;
  120. return NULL;
  121. }
  122. const char *names_protocol(u_int8_t classid, u_int8_t subclassid,
  123. u_int8_t protocolid)
  124. {
  125. struct protocol *p;
  126. p = protocols[hashnum((classid << 16) | (subclassid << 8)
  127. | protocolid)];
  128. for (; p; p = p->next)
  129. if (p->classid == classid && p->subclassid == subclassid &&
  130. p->protocolid == protocolid)
  131. return p->name;
  132. return NULL;
  133. }
  134. /* add a cleanup function by takahiro */
  135. struct pool {
  136. struct pool *next;
  137. void *mem;
  138. };
  139. static struct pool *pool_head;
  140. static void *my_malloc(size_t size)
  141. {
  142. struct pool *p;
  143. p = calloc(1, sizeof(struct pool));
  144. if (!p)
  145. return NULL;
  146. p->mem = calloc(1, size);
  147. if (!p->mem) {
  148. free(p);
  149. return NULL;
  150. }
  151. p->next = pool_head;
  152. pool_head = p;
  153. return p->mem;
  154. }
  155. void names_free(void)
  156. {
  157. struct pool *pool;
  158. if (!pool_head)
  159. return;
  160. for (pool = pool_head; pool != NULL; ) {
  161. struct pool *tmp;
  162. if (pool->mem)
  163. free(pool->mem);
  164. tmp = pool;
  165. pool = pool->next;
  166. free(tmp);
  167. }
  168. }
  169. static int new_vendor(const char *name, u_int16_t vendorid)
  170. {
  171. struct vendor *v;
  172. unsigned int h = hashnum(vendorid);
  173. v = vendors[h];
  174. for (; v; v = v->next)
  175. if (v->vendorid == vendorid)
  176. return -1;
  177. v = my_malloc(sizeof(struct vendor) + strlen(name));
  178. if (!v)
  179. return -1;
  180. strcpy(v->name, name);
  181. v->vendorid = vendorid;
  182. v->next = vendors[h];
  183. vendors[h] = v;
  184. return 0;
  185. }
  186. static int new_product(const char *name, u_int16_t vendorid,
  187. u_int16_t productid)
  188. {
  189. struct product *p;
  190. unsigned int h = hashnum((vendorid << 16) | productid);
  191. p = products[h];
  192. for (; p; p = p->next)
  193. if (p->vendorid == vendorid && p->productid == productid)
  194. return -1;
  195. p = my_malloc(sizeof(struct product) + strlen(name));
  196. if (!p)
  197. return -1;
  198. strcpy(p->name, name);
  199. p->vendorid = vendorid;
  200. p->productid = productid;
  201. p->next = products[h];
  202. products[h] = p;
  203. return 0;
  204. }
  205. static int new_class(const char *name, u_int8_t classid)
  206. {
  207. struct class *c;
  208. unsigned int h = hashnum(classid);
  209. c = classes[h];
  210. for (; c; c = c->next)
  211. if (c->classid == classid)
  212. return -1;
  213. c = my_malloc(sizeof(struct class) + strlen(name));
  214. if (!c)
  215. return -1;
  216. strcpy(c->name, name);
  217. c->classid = classid;
  218. c->next = classes[h];
  219. classes[h] = c;
  220. return 0;
  221. }
  222. static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid)
  223. {
  224. struct subclass *s;
  225. unsigned int h = hashnum((classid << 8) | subclassid);
  226. s = subclasses[h];
  227. for (; s; s = s->next)
  228. if (s->classid == classid && s->subclassid == subclassid)
  229. return -1;
  230. s = my_malloc(sizeof(struct subclass) + strlen(name));
  231. if (!s)
  232. return -1;
  233. strcpy(s->name, name);
  234. s->classid = classid;
  235. s->subclassid = subclassid;
  236. s->next = subclasses[h];
  237. subclasses[h] = s;
  238. return 0;
  239. }
  240. static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid,
  241. u_int8_t protocolid)
  242. {
  243. struct protocol *p;
  244. unsigned int h = hashnum((classid << 16) | (subclassid << 8)
  245. | protocolid);
  246. p = protocols[h];
  247. for (; p; p = p->next)
  248. if (p->classid == classid && p->subclassid == subclassid
  249. && p->protocolid == protocolid)
  250. return -1;
  251. p = my_malloc(sizeof(struct protocol) + strlen(name));
  252. if (!p)
  253. return -1;
  254. strcpy(p->name, name);
  255. p->classid = classid;
  256. p->subclassid = subclassid;
  257. p->protocolid = protocolid;
  258. p->next = protocols[h];
  259. protocols[h] = p;
  260. return 0;
  261. }
  262. static void parse(FILE *f)
  263. {
  264. char buf[512], *cp;
  265. unsigned int linectr = 0;
  266. int lastvendor = -1;
  267. int lastclass = -1;
  268. int lastsubclass = -1;
  269. int lasthut = -1;
  270. int lastlang = -1;
  271. unsigned int u;
  272. while (fgets(buf, sizeof(buf), f)) {
  273. linectr++;
  274. /* remove line ends */
  275. cp = strchr(buf, '\r');
  276. if (cp)
  277. *cp = 0;
  278. cp = strchr(buf, '\n');
  279. if (cp)
  280. *cp = 0;
  281. if (buf[0] == '#' || !buf[0])
  282. continue;
  283. cp = buf;
  284. if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' &&
  285. buf[3] == 'S' && buf[4] == 'D' &&
  286. buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/
  287. buf[7] == ' ') {
  288. continue;
  289. }
  290. if (buf[0] == 'P' && buf[1] == 'H' &&
  291. buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
  292. continue;
  293. }
  294. if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' &&
  295. buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
  296. continue;
  297. }
  298. if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
  299. lasthut = lastclass = lastvendor = lastsubclass = -1;
  300. /*
  301. * set 1 as pseudo-id to indicate that the parser is
  302. * in a `L' section.
  303. */
  304. lastlang = 1;
  305. continue;
  306. }
  307. if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
  308. /* class spec */
  309. cp = buf+2;
  310. while (isspace(*cp))
  311. cp++;
  312. if (!isxdigit(*cp)) {
  313. err("Invalid class spec at line %u", linectr);
  314. continue;
  315. }
  316. u = strtoul(cp, &cp, 16);
  317. while (isspace(*cp))
  318. cp++;
  319. if (!*cp) {
  320. err("Invalid class spec at line %u", linectr);
  321. continue;
  322. }
  323. if (new_class(cp, u))
  324. err("Duplicate class spec at line %u class %04x %s",
  325. linectr, u, cp);
  326. dbg("line %5u class %02x %s", linectr, u, cp);
  327. lasthut = lastlang = lastvendor = lastsubclass = -1;
  328. lastclass = u;
  329. continue;
  330. }
  331. if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
  332. /* audio terminal type spec */
  333. continue;
  334. }
  335. if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C'
  336. && isspace(buf[3])) {
  337. /* HID Descriptor bCountryCode */
  338. continue;
  339. }
  340. if (isxdigit(*cp)) {
  341. /* vendor */
  342. u = strtoul(cp, &cp, 16);
  343. while (isspace(*cp))
  344. cp++;
  345. if (!*cp) {
  346. err("Invalid vendor spec at line %u", linectr);
  347. continue;
  348. }
  349. if (new_vendor(cp, u))
  350. err("Duplicate vendor spec at line %u vendor %04x %s",
  351. linectr, u, cp);
  352. dbg("line %5u vendor %04x %s", linectr, u, cp);
  353. lastvendor = u;
  354. lasthut = lastlang = lastclass = lastsubclass = -1;
  355. continue;
  356. }
  357. if (buf[0] == '\t' && isxdigit(buf[1])) {
  358. /* product or subclass spec */
  359. u = strtoul(buf+1, &cp, 16);
  360. while (isspace(*cp))
  361. cp++;
  362. if (!*cp) {
  363. err("Invalid product/subclass spec at line %u",
  364. linectr);
  365. continue;
  366. }
  367. if (lastvendor != -1) {
  368. if (new_product(cp, lastvendor, u))
  369. err("Duplicate product spec at line %u product %04x:%04x %s",
  370. linectr, lastvendor, u, cp);
  371. dbg("line %5u product %04x:%04x %s", linectr,
  372. lastvendor, u, cp);
  373. continue;
  374. }
  375. if (lastclass != -1) {
  376. if (new_subclass(cp, lastclass, u))
  377. err("Duplicate subclass spec at line %u class %02x:%02x %s",
  378. linectr, lastclass, u, cp);
  379. dbg("line %5u subclass %02x:%02x %s", linectr,
  380. lastclass, u, cp);
  381. lastsubclass = u;
  382. continue;
  383. }
  384. if (lasthut != -1) {
  385. /* do not store hut */
  386. continue;
  387. }
  388. if (lastlang != -1) {
  389. /* do not store langid */
  390. continue;
  391. }
  392. err("Product/Subclass spec without prior Vendor/Class spec at line %u",
  393. linectr);
  394. continue;
  395. }
  396. if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
  397. /* protocol spec */
  398. u = strtoul(buf+2, &cp, 16);
  399. while (isspace(*cp))
  400. cp++;
  401. if (!*cp) {
  402. err("Invalid protocol spec at line %u",
  403. linectr);
  404. continue;
  405. }
  406. if (lastclass != -1 && lastsubclass != -1) {
  407. if (new_protocol(cp, lastclass, lastsubclass,
  408. u))
  409. err("Duplicate protocol spec at line %u class %02x:%02x:%02x %s",
  410. linectr, lastclass, lastsubclass,
  411. u, cp);
  412. dbg("line %5u protocol %02x:%02x:%02x %s",
  413. linectr, lastclass, lastsubclass, u, cp);
  414. continue;
  415. }
  416. err("Protocol spec without prior Class and Subclass spec at line %u",
  417. linectr);
  418. continue;
  419. }
  420. if (buf[0] == 'H' && buf[1] == 'I' &&
  421. buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
  422. continue;
  423. }
  424. if (buf[0] == 'H' && buf[1] == 'U' &&
  425. buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
  426. lastlang = lastclass = lastvendor = lastsubclass = -1;
  427. /*
  428. * set 1 as pseudo-id to indicate that the parser is
  429. * in a `HUT' section.
  430. */
  431. lasthut = 1;
  432. continue;
  433. }
  434. if (buf[0] == 'R' && buf[1] == ' ')
  435. continue;
  436. if (buf[0] == 'V' && buf[1] == 'T')
  437. continue;
  438. err("Unknown line at line %u", linectr);
  439. }
  440. }
  441. int names_init(char *n)
  442. {
  443. FILE *f;
  444. f = fopen(n, "r");
  445. if (!f)
  446. return errno;
  447. parse(f);
  448. fclose(f);
  449. return 0;
  450. }