iproute2/lib/names.c
<<
>>
Prefs
   1/*
   2 * names.c              db names
   3 *
   4 *              This program is free software; you can redistribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 */
  10
  11#include <stdio.h>
  12#include <string.h>
  13#include <stdlib.h>
  14#include <errno.h>
  15
  16#include "names.h"
  17#include "utils.h"
  18
  19#define MAX_ENTRIES  256
  20#define NAME_MAX_LEN 512
  21
  22static int read_id_name(FILE *fp, int *id, char *name)
  23{
  24        char buf[NAME_MAX_LEN];
  25        int min, maj;
  26
  27        while (fgets(buf, sizeof(buf), fp)) {
  28                char *p = buf;
  29
  30                while (*p == ' ' || *p == '\t')
  31                        p++;
  32
  33                if (*p == '#' || *p == '\n' || *p == 0)
  34                        continue;
  35
  36                if (sscanf(p, "%x:%x %s\n", &maj, &min, name) == 3) {
  37                        *id = (maj << 16) | min;
  38                } else if (sscanf(p, "%x:%x %s #", &maj, &min, name) == 3) {
  39                        *id = (maj << 16) | min;
  40                } else if (sscanf(p, "0x%x %s\n", id, name) != 2 &&
  41                                sscanf(p, "0x%x %s #", id, name) != 2 &&
  42                                sscanf(p, "%d %s\n", id, name) != 2 &&
  43                                sscanf(p, "%d %s #", id, name) != 2) {
  44                        strcpy(name, p);
  45                        return -1;
  46                }
  47                return 1;
  48        }
  49
  50        return 0;
  51}
  52
  53struct db_names *db_names_alloc(void)
  54{
  55        struct db_names *db;
  56
  57        db = calloc(1, sizeof(*db));
  58        if (!db)
  59                return NULL;
  60
  61        db->size = MAX_ENTRIES;
  62        db->hash = calloc(db->size, sizeof(struct db_entry *));
  63
  64        return db;
  65}
  66
  67int db_names_load(struct db_names *db, const char *path)
  68{
  69        struct db_entry *entry;
  70        FILE *fp;
  71        int id;
  72        char namebuf[NAME_MAX_LEN] = {0};
  73        int ret = -1;
  74
  75        fp = fopen(path, "r");
  76        if (!fp)
  77                return -ENOENT;
  78
  79        while ((ret = read_id_name(fp, &id, &namebuf[0]))) {
  80                if (ret == -1) {
  81                        fprintf(stderr, "Database %s is corrupted at %s\n",
  82                                        path, namebuf);
  83                        goto Exit;
  84                }
  85                ret = -1;
  86
  87                if (id < 0)
  88                        continue;
  89
  90                entry = malloc(sizeof(*entry));
  91                if (!entry)
  92                        goto Exit;
  93
  94                entry->name = strdup(namebuf);
  95                if (!entry->name) {
  96                        free(entry);
  97                        goto Exit;
  98                }
  99
 100                entry->id   = id;
 101                entry->next = db->hash[id & (db->size - 1)];
 102                db->hash[id & (db->size - 1)] = entry;
 103        }
 104        ret = 0;
 105
 106Exit:
 107        fclose(fp);
 108        return ret;
 109}
 110
 111void db_names_free(struct db_names *db)
 112{
 113        int i;
 114
 115        if (!db)
 116                return;
 117
 118        for (i = 0; i < db->size; i++) {
 119                struct db_entry *entry = db->hash[i];
 120
 121                while (entry) {
 122                        struct db_entry *next = entry->next;
 123
 124                        free(entry->name);
 125                        free(entry);
 126                        entry = next;
 127                }
 128        }
 129
 130        free(db->hash);
 131        free(db);
 132}
 133
 134char *id_to_name(struct db_names *db, int id, char *name)
 135{
 136        struct db_entry *entry;
 137
 138        if (!db)
 139                return NULL;
 140
 141        entry = db->hash[id & (db->size - 1)];
 142        while (entry && entry->id != id)
 143                entry = entry->next;
 144
 145        if (entry) {
 146                strncpy(name, entry->name, IDNAME_MAX);
 147                return name;
 148        }
 149
 150        snprintf(name, IDNAME_MAX, "%d", id);
 151        return NULL;
 152}
 153