"Fossies" - the Fresh Open Source Software Archive

Member "usbutils-015/names.c" (3 Dec 2022, 9460 Bytes) of package /linux/misc/usbutils-015.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "names.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 014_vs_015.

    1 // SPDX-License-Identifier: GPL-2.0-or-later
    2 /*
    3  * USB name database manipulation routines
    4  *
    5  * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
    6  * Copyright (C) 2013 Tom Gundersen (teg@jklm.no)
    7  */
    8 
    9 #ifdef HAVE_CONFIG_H
   10 #include "config.h"
   11 #endif
   12 
   13 #include <stdint.h>
   14 #include <sys/stat.h>
   15 #include <fcntl.h>
   16 #include <dirent.h>
   17 #include <string.h>
   18 #include <errno.h>
   19 #include <stdlib.h>
   20 #include <unistd.h>
   21 #include <stdio.h>
   22 #include <ctype.h>
   23 
   24 #include <libudev.h>
   25 
   26 #include "usb-spec.h"
   27 #include "names.h"
   28 
   29 
   30 #define HASH1  0x10
   31 #define HASH2  0x02
   32 #define HASHSZ 512
   33 
   34 static unsigned int hashnum(unsigned int num)
   35 {
   36     unsigned int mask1 = (unsigned int)HASH1 << 27, mask2 = (unsigned int)HASH2 << 27;
   37 
   38     for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
   39         if (num & mask1)
   40             num ^= mask2;
   41     return num & (HASHSZ-1);
   42 }
   43 
   44 /* ---------------------------------------------------------------------- */
   45 
   46 static struct udev *udev = NULL;
   47 static struct udev_hwdb *hwdb = NULL;
   48 static struct audioterminal *audioterminals_hash[HASHSZ] = { NULL, };
   49 static struct videoterminal *videoterminals_hash[HASHSZ] = { NULL, };
   50 static struct genericstrtable *hiddescriptors_hash[HASHSZ] = { NULL, };
   51 static struct genericstrtable *reports_hash[HASHSZ] = { NULL, };
   52 static struct genericstrtable *huts_hash[HASHSZ] = { NULL, };
   53 static struct genericstrtable *biass_hash[HASHSZ] = { NULL, };
   54 static struct genericstrtable *physdess_hash[HASHSZ] = { NULL, };
   55 static struct genericstrtable *hutus_hash[HASHSZ] = { NULL, };
   56 static struct genericstrtable *langids_hash[HASHSZ] = { NULL, };
   57 static struct genericstrtable *countrycodes_hash[HASHSZ] = { NULL, };
   58 
   59 /* ---------------------------------------------------------------------- */
   60 
   61 static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ],
   62                      unsigned int idx)
   63 {
   64     struct genericstrtable *h;
   65 
   66     for (h = t[hashnum(idx)]; h; h = h->next)
   67         if (h->num == idx)
   68             return h->name;
   69     return NULL;
   70 }
   71 
   72 const char *names_hid(uint8_t hidd)
   73 {
   74     return names_genericstrtable(hiddescriptors_hash, hidd);
   75 }
   76 
   77 const char *names_reporttag(uint8_t rt)
   78 {
   79     return names_genericstrtable(reports_hash, rt);
   80 }
   81 
   82 const char *names_huts(unsigned int data)
   83 {
   84     return names_genericstrtable(huts_hash, data);
   85 }
   86 
   87 const char *names_hutus(unsigned int data)
   88 {
   89     return names_genericstrtable(hutus_hash, data);
   90 }
   91 
   92 const char *names_langid(uint16_t langid)
   93 {
   94     return names_genericstrtable(langids_hash, langid);
   95 }
   96 
   97 const char *names_physdes(uint8_t ph)
   98 {
   99     return names_genericstrtable(physdess_hash, ph);
  100 }
  101 
  102 const char *names_bias(uint8_t b)
  103 {
  104     return names_genericstrtable(biass_hash, b);
  105 }
  106 
  107 const char *names_countrycode(unsigned int countrycode)
  108 {
  109     return names_genericstrtable(countrycodes_hash, countrycode);
  110 }
  111 
  112 static const char *hwdb_get(const char *modalias, const char *key)
  113 {
  114     struct udev_list_entry *entry;
  115 
  116     udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
  117         if (strcmp(udev_list_entry_get_name(entry), key) == 0)
  118             return udev_list_entry_get_value(entry);
  119 
  120     return NULL;
  121 }
  122 
  123 const char *names_vendor(uint16_t vendorid)
  124 {
  125     char modalias[64];
  126 
  127     sprintf(modalias, "usb:v%04X*", vendorid);
  128     return hwdb_get(modalias, "ID_VENDOR_FROM_DATABASE");
  129 }
  130 
  131 const char *names_product(uint16_t vendorid, uint16_t productid)
  132 {
  133     char modalias[64];
  134 
  135     sprintf(modalias, "usb:v%04Xp%04X*", vendorid, productid);
  136     return hwdb_get(modalias, "ID_MODEL_FROM_DATABASE");
  137 }
  138 
  139 const char *names_class(uint8_t classid)
  140 {
  141     char modalias[64];
  142 
  143     sprintf(modalias, "usb:v*p*d*dc%02X*", classid);
  144     return hwdb_get(modalias, "ID_USB_CLASS_FROM_DATABASE");
  145 }
  146 
  147 const char *names_subclass(uint8_t classid, uint8_t subclassid)
  148 {
  149     char modalias[64];
  150 
  151     sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02X*", classid, subclassid);
  152     return hwdb_get(modalias, "ID_USB_SUBCLASS_FROM_DATABASE");
  153 }
  154 
  155 const char *names_protocol(uint8_t classid, uint8_t subclassid, uint8_t protocolid)
  156 {
  157     char modalias[64];
  158 
  159     sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02Xdp%02X*", classid, subclassid, protocolid);
  160     return hwdb_get(modalias, "ID_USB_PROTOCOL_FROM_DATABASE");
  161 }
  162 
  163 const char *names_audioterminal(uint16_t termt)
  164 {
  165     struct audioterminal *at;
  166 
  167     at = audioterminals_hash[hashnum(termt)];
  168     for (; at; at = at->next)
  169         if (at->termt == termt)
  170             return at->name;
  171     return NULL;
  172 }
  173 
  174 const char *names_videoterminal(uint16_t termt)
  175 {
  176     struct videoterminal *vt;
  177 
  178     vt = videoterminals_hash[hashnum(termt)];
  179     for (; vt; vt = vt->next)
  180         if (vt->termt == termt)
  181             return vt->name;
  182     return NULL;
  183 }
  184 
  185 /* ---------------------------------------------------------------------- */
  186 
  187 int get_vendor_string(char *buf, size_t size, uint16_t vid)
  188 {
  189         const char *cp;
  190 
  191         if (size < 1)
  192                 return 0;
  193         *buf = 0;
  194         if (!(cp = names_vendor(vid)))
  195                 return 0;
  196         return snprintf(buf, size, "%s", cp);
  197 }
  198 
  199 int get_product_string(char *buf, size_t size, uint16_t vid, uint16_t pid)
  200 {
  201         const char *cp;
  202 
  203         if (size < 1)
  204                 return 0;
  205         *buf = 0;
  206         if (!(cp = names_product(vid, pid)))
  207                 return 0;
  208         return snprintf(buf, size, "%s", cp);
  209 }
  210 
  211 int get_class_string(char *buf, size_t size, uint8_t cls)
  212 {
  213     const char *cp;
  214 
  215     if (size < 1)
  216         return 0;
  217     *buf = 0;
  218     if (!(cp = names_class(cls)))
  219         return 0;
  220     return snprintf(buf, size, "%s", cp);
  221 }
  222 
  223 int get_subclass_string(char *buf, size_t size, uint8_t cls, uint8_t subcls)
  224 {
  225     const char *cp;
  226 
  227     if (size < 1)
  228         return 0;
  229     *buf = 0;
  230     if (!(cp = names_subclass(cls, subcls)))
  231         return 0;
  232     return snprintf(buf, size, "%s", cp);
  233 }
  234 
  235 /* ---------------------------------------------------------------------- */
  236 
  237 static int hash_audioterminal(struct audioterminal *at)
  238 {
  239     struct audioterminal *at_old;
  240     unsigned int h = hashnum(at->termt);
  241 
  242     for (at_old = audioterminals_hash[h]; at_old; at_old = at_old->next)
  243         if (at_old->termt == at->termt)
  244             return -1;
  245     at->next = audioterminals_hash[h];
  246     audioterminals_hash[h] = at;
  247     return 0;
  248 }
  249 
  250 static int hash_audioterminals(void)
  251 {
  252     int r = 0, i, k;
  253 
  254     for (i = 0; audioterminals[i].name; i++)
  255     {
  256         k = hash_audioterminal(&audioterminals[i]);
  257         if (k < 0)
  258             r = k;
  259     }
  260 
  261     return r;
  262 }
  263 
  264 static int hash_videoterminal(struct videoterminal *vt)
  265 {
  266     struct videoterminal *vt_old;
  267     unsigned int h = hashnum(vt->termt);
  268 
  269     for (vt_old = videoterminals_hash[h]; vt_old; vt_old = vt_old->next)
  270         if (vt_old->termt == vt->termt)
  271             return -1;
  272     vt->next = videoterminals_hash[h];
  273     videoterminals_hash[h] = vt;
  274     return 0;
  275 }
  276 
  277 static int hash_videoterminals(void)
  278 {
  279     int r = 0, i, k;
  280 
  281     for (i = 0; videoterminals[i].name; i++)
  282     {
  283         k = hash_videoterminal(&videoterminals[i]);
  284         if (k < 0)
  285             r = k;
  286     }
  287 
  288     return r;
  289 }
  290 
  291 static int hash_genericstrtable(struct genericstrtable *t[HASHSZ],
  292                    struct genericstrtable *g)
  293 {
  294     struct genericstrtable *g_old;
  295     unsigned int h = hashnum(g->num);
  296 
  297     for (g_old = t[h]; g_old; g_old = g_old->next)
  298         if (g_old->num == g->num)
  299             return -1;
  300     g->next = t[h];
  301     t[h] = g;
  302     return 0;
  303 }
  304 
  305 #define HASH_EACH(array, hash) \
  306     for (i = 0; array[i].name; i++) { \
  307         k = hash_genericstrtable(hash, &array[i]); \
  308         if (k < 0) { \
  309             r = k; \
  310         }\
  311     }
  312 
  313 static int hash_tables(void)
  314 {
  315     int r = 0, k, i;
  316 
  317     k = hash_audioterminals();
  318     if (k < 0)
  319         r = k;
  320 
  321     k = hash_videoterminals();
  322     if (k < 0)
  323         r = k;
  324 
  325     HASH_EACH(hiddescriptors, hiddescriptors_hash);
  326 
  327     HASH_EACH(reports, reports_hash);
  328 
  329     HASH_EACH(huts, huts_hash);
  330 
  331     HASH_EACH(hutus, hutus_hash);
  332 
  333     HASH_EACH(langids, langids_hash);
  334 
  335     HASH_EACH(physdess, physdess_hash);
  336 
  337     HASH_EACH(biass, biass_hash);
  338 
  339     HASH_EACH(countrycodes, countrycodes_hash);
  340 
  341     return r;
  342 }
  343 
  344 /* ---------------------------------------------------------------------- */
  345 
  346 /*
  347 static void print_tables(void)
  348 {
  349     int i;
  350     struct audioterminal *at;
  351     struct videoterminal *vt;
  352     struct genericstrtable *li;
  353     struct genericstrtable *hu;
  354 
  355 
  356     printf("--------------------------------------------\n");
  357     printf("\t\t Audio Terminals\n");
  358     printf("--------------------------------------------\n");
  359 
  360     for (i = 0; i < HASHSZ; i++) {
  361         printf("hash: %d\n", i);
  362         at = audioterminals_hash[i];
  363         for (; at; at = at->next)
  364             printf("\tentry: %s\n", at->name);
  365     }
  366 
  367     printf("--------------------------------------------\n");
  368     printf("\t\t Video Terminals\n");
  369     printf("--------------------------------------------\n");
  370 
  371     for (i = 0; i < HASHSZ; i++) {
  372         printf("hash: %d\n", i);
  373         vt = videoterminals_hash[i];
  374         for (; vt; vt = vt->next)
  375             printf("\tentry: %s\n", vt->name);
  376     }
  377 
  378     printf("--------------------------------------------\n");
  379     printf("\t\t Languages\n");
  380     printf("--------------------------------------------\n");
  381 
  382     for (i = 0; i < HASHSZ; i++) {
  383         li = langids_hash[i];
  384         if (li)
  385             printf("hash: %d\n", i);
  386         for (; li; li = li->next)
  387             printf("\tid: %x, entry: %s\n", li->num, li->name);
  388     }
  389 
  390     printf("--------------------------------------------\n");
  391     printf("\t\t Conutry Codes\n");
  392     printf("--------------------------------------------\n");
  393 
  394     for (i = 0; i < HASHSZ; i++) {
  395         hu = countrycodes_hash[i];
  396         if (hu)
  397             printf("hash: %d\n", i);
  398         for (; hu; hu = hu->next)
  399             printf("\tid: %x, entry: %s\n", hu->num, hu->name);
  400     }
  401 
  402     printf("--------------------------------------------\n");
  403 }
  404 */
  405 
  406 int names_init(void)
  407 {
  408     int r;
  409 
  410     udev = udev_new();
  411     if (!udev)
  412         r = -1;
  413     else {
  414         hwdb = udev_hwdb_new(udev);
  415         if (!hwdb)
  416             r = -1;
  417     }
  418 
  419     r = hash_tables();
  420 
  421     return r;
  422 }
  423 
  424 void names_exit(void)
  425 {
  426     hwdb = udev_hwdb_unref(hwdb);
  427     udev = udev_unref(udev);
  428 }