blob: fbd6503f22d42e9c2ae17957e85f2808fa0ac82b [file] [log] [blame]
Vadim Kochan4612d042015-03-03 18:41:18 +02001/*
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>
Vadim Kochan8b90a992015-03-25 05:14:37 +020014#include <errno.h>
Vadim Kochan4612d042015-03-03 18:41:18 +020015
16#include "names.h"
Vadim Kochan8b90a992015-03-25 05:14:37 +020017#include "utils.h"
Vadim Kochan4612d042015-03-03 18:41:18 +020018
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
Vadim Kochan8b90a992015-03-25 05:14:37 +020053struct db_names *db_names_alloc(void)
Vadim Kochan4612d042015-03-03 18:41:18 +020054{
55 struct db_names *db;
Vadim Kochan4612d042015-03-03 18:41:18 +020056
Phil Sutterf89bb022016-07-18 16:48:43 +020057 db = calloc(1, sizeof(*db));
Vadim Kochan8b90a992015-03-25 05:14:37 +020058 if (!db)
59 return NULL;
60
Vadim Kochan4612d042015-03-03 18:41:18 +020061 db->size = MAX_ENTRIES;
Phil Sutterf89bb022016-07-18 16:48:43 +020062 db->hash = calloc(db->size, sizeof(struct db_entry *));
Vadim Kochan4612d042015-03-03 18:41:18 +020063
Vadim Kochan8b90a992015-03-25 05:14:37 +020064 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
Vadim Kochan4612d042015-03-03 18:41:18 +020079 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);
Vadim Kochan8b90a992015-03-25 05:14:37 +020083 goto Exit;
Vadim Kochan4612d042015-03-03 18:41:18 +020084 }
Vadim Kochan8b90a992015-03-25 05:14:37 +020085 ret = -1;
Vadim Kochan4612d042015-03-03 18:41:18 +020086
87 if (id < 0)
88 continue;
89
90 entry = malloc(sizeof(*entry));
Vadim Kochan8b90a992015-03-25 05:14:37 +020091 if (!entry)
92 goto Exit;
93
Vadim Kochan4612d042015-03-03 18:41:18 +020094 entry->name = strdup(namebuf);
Vadim Kochan8b90a992015-03-25 05:14:37 +020095 if (!entry->name) {
96 free(entry);
97 goto Exit;
98 }
99
100 entry->id = id;
Vadim Kochan4612d042015-03-03 18:41:18 +0200101 entry->next = db->hash[id & (db->size - 1)];
102 db->hash[id & (db->size - 1)] = entry;
103 }
Vadim Kochan8b90a992015-03-25 05:14:37 +0200104 ret = 0;
Vadim Kochan4612d042015-03-03 18:41:18 +0200105
Vadim Kochan8b90a992015-03-25 05:14:37 +0200106Exit:
Vadim Kochan4612d042015-03-03 18:41:18 +0200107 fclose(fp);
Vadim Kochan8b90a992015-03-25 05:14:37 +0200108 return ret;
Vadim Kochan4612d042015-03-03 18:41:18 +0200109}
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{
Vadim Kochan8b90a992015-03-25 05:14:37 +0200136 struct db_entry *entry;
Vadim Kochan4612d042015-03-03 18:41:18 +0200137
Vadim Kochan8b90a992015-03-25 05:14:37 +0200138 if (!db)
139 return NULL;
140
141 entry = db->hash[id & (db->size - 1)];
Vadim Kochan4612d042015-03-03 18:41:18 +0200142 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
154int name_to_id(struct db_names *db, int *id, const char *name)
155{
156 struct db_entry *entry;
157 int i;
158
Vadim Kochan8b90a992015-03-25 05:14:37 +0200159 if (!db)
160 return -1;
161
Vadim Kochan4612d042015-03-03 18:41:18 +0200162 if (db->cached && strcmp(db->cached->name, name) == 0) {
163 *id = db->cached->id;
164 return 0;
165 }
166
167 for (i = 0; i < db->size; i++) {
168 entry = db->hash[i];
169 while (entry && strcmp(entry->name, name))
170 entry = entry->next;
Vadim Kochan8b90a992015-03-25 05:14:37 +0200171
Vadim Kochan4612d042015-03-03 18:41:18 +0200172 if (entry) {
173 db->cached = entry;
174 *id = entry->id;
175 return 0;
176 }
177 }
178
179 return -1;
180}