blob: 3b5b0b1e1201a0197ed1420bcb9f04a3bd5d3c6f [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
57 db = malloc(sizeof(*db));
Vadim Kochan8b90a992015-03-25 05:14:37 +020058 if (!db)
59 return NULL;
60
Vadim Kochan4612d042015-03-03 18:41:18 +020061 memset(db, 0, sizeof(*db));
62
63 db->size = MAX_ENTRIES;
64 db->hash = malloc(sizeof(struct db_entry *) * db->size);
65 memset(db->hash, 0, sizeof(struct db_entry *) * db->size);
66
Vadim Kochan8b90a992015-03-25 05:14:37 +020067 return db;
68}
69
70int db_names_load(struct db_names *db, const char *path)
71{
72 struct db_entry *entry;
73 FILE *fp;
74 int id;
75 char namebuf[NAME_MAX_LEN] = {0};
76 int ret = -1;
77
78 fp = fopen(path, "r");
79 if (!fp)
80 return -ENOENT;
81
Vadim Kochan4612d042015-03-03 18:41:18 +020082 while ((ret = read_id_name(fp, &id, &namebuf[0]))) {
83 if (ret == -1) {
84 fprintf(stderr, "Database %s is corrupted at %s\n",
85 path, namebuf);
Vadim Kochan8b90a992015-03-25 05:14:37 +020086 goto Exit;
Vadim Kochan4612d042015-03-03 18:41:18 +020087 }
Vadim Kochan8b90a992015-03-25 05:14:37 +020088 ret = -1;
Vadim Kochan4612d042015-03-03 18:41:18 +020089
90 if (id < 0)
91 continue;
92
93 entry = malloc(sizeof(*entry));
Vadim Kochan8b90a992015-03-25 05:14:37 +020094 if (!entry)
95 goto Exit;
96
Vadim Kochan4612d042015-03-03 18:41:18 +020097 entry->name = strdup(namebuf);
Vadim Kochan8b90a992015-03-25 05:14:37 +020098 if (!entry->name) {
99 free(entry);
100 goto Exit;
101 }
102
103 entry->id = id;
Vadim Kochan4612d042015-03-03 18:41:18 +0200104 entry->next = db->hash[id & (db->size - 1)];
105 db->hash[id & (db->size - 1)] = entry;
106 }
Vadim Kochan8b90a992015-03-25 05:14:37 +0200107 ret = 0;
Vadim Kochan4612d042015-03-03 18:41:18 +0200108
Vadim Kochan8b90a992015-03-25 05:14:37 +0200109Exit:
Vadim Kochan4612d042015-03-03 18:41:18 +0200110 fclose(fp);
Vadim Kochan8b90a992015-03-25 05:14:37 +0200111 return ret;
Vadim Kochan4612d042015-03-03 18:41:18 +0200112}
113
114void db_names_free(struct db_names *db)
115{
116 int i;
117
118 if (!db)
119 return;
120
121 for (i = 0; i < db->size; i++) {
122 struct db_entry *entry = db->hash[i];
123
124 while (entry) {
125 struct db_entry *next = entry->next;
126
127 free(entry->name);
128 free(entry);
129 entry = next;
130 }
131 }
132
133 free(db->hash);
134 free(db);
135}
136
137char *id_to_name(struct db_names *db, int id, char *name)
138{
Vadim Kochan8b90a992015-03-25 05:14:37 +0200139 struct db_entry *entry;
Vadim Kochan4612d042015-03-03 18:41:18 +0200140
Vadim Kochan8b90a992015-03-25 05:14:37 +0200141 if (!db)
142 return NULL;
143
144 entry = db->hash[id & (db->size - 1)];
Vadim Kochan4612d042015-03-03 18:41:18 +0200145 while (entry && entry->id != id)
146 entry = entry->next;
147
148 if (entry) {
149 strncpy(name, entry->name, IDNAME_MAX);
150 return name;
151 }
152
153 snprintf(name, IDNAME_MAX, "%d", id);
154 return NULL;
155}
156
157int name_to_id(struct db_names *db, int *id, const char *name)
158{
159 struct db_entry *entry;
160 int i;
161
Vadim Kochan8b90a992015-03-25 05:14:37 +0200162 if (!db)
163 return -1;
164
Vadim Kochan4612d042015-03-03 18:41:18 +0200165 if (db->cached && strcmp(db->cached->name, name) == 0) {
166 *id = db->cached->id;
167 return 0;
168 }
169
170 for (i = 0; i < db->size; i++) {
171 entry = db->hash[i];
172 while (entry && strcmp(entry->name, name))
173 entry = entry->next;
Vadim Kochan8b90a992015-03-25 05:14:37 +0200174
Vadim Kochan4612d042015-03-03 18:41:18 +0200175 if (entry) {
176 db->cached = entry;
177 *id = entry->id;
178 return 0;
179 }
180 }
181
182 return -1;
183}