]>
Commit | Line | Data |
---|---|---|
4612d04d VK |
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> | |
8b90a990 | 14 | #include <errno.h> |
4612d04d VK |
15 | |
16 | #include "names.h" | |
8b90a990 | 17 | #include "utils.h" |
4612d04d VK |
18 | |
19 | #define MAX_ENTRIES 256 | |
20 | #define NAME_MAX_LEN 512 | |
21 | ||
22 | static 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 | ||
8b90a990 | 53 | struct db_names *db_names_alloc(void) |
4612d04d VK |
54 | { |
55 | struct db_names *db; | |
4612d04d | 56 | |
f89bb021 | 57 | db = calloc(1, sizeof(*db)); |
8b90a990 | 58 | if (!db) |
4612d04d | 59 | return NULL; |
4612d04d | 60 | |
4612d04d | 61 | db->size = MAX_ENTRIES; |
f89bb021 | 62 | db->hash = calloc(db->size, sizeof(struct db_entry *)); |
4612d04d | 63 | |
8b90a990 VK |
64 | return db; |
65 | } | |
66 | ||
67 | int 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 | ||
4612d04d VK |
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); | |
8b90a990 | 83 | goto Exit; |
4612d04d | 84 | } |
8b90a990 | 85 | ret = -1; |
4612d04d VK |
86 | |
87 | if (id < 0) | |
88 | continue; | |
89 | ||
90 | entry = malloc(sizeof(*entry)); | |
8b90a990 VK |
91 | if (!entry) |
92 | goto Exit; | |
93 | ||
4612d04d | 94 | entry->name = strdup(namebuf); |
8b90a990 VK |
95 | if (!entry->name) { |
96 | free(entry); | |
97 | goto Exit; | |
98 | } | |
99 | ||
100 | entry->id = id; | |
4612d04d VK |
101 | entry->next = db->hash[id & (db->size - 1)]; |
102 | db->hash[id & (db->size - 1)] = entry; | |
103 | } | |
8b90a990 | 104 | ret = 0; |
4612d04d | 105 | |
8b90a990 | 106 | Exit: |
4612d04d | 107 | fclose(fp); |
8b90a990 | 108 | return ret; |
4612d04d VK |
109 | } |
110 | ||
111 | void 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 | ||
134 | char *id_to_name(struct db_names *db, int id, char *name) | |
135 | { | |
8b90a990 VK |
136 | struct db_entry *entry; |
137 | ||
138 | if (!db) | |
139 | return NULL; | |
4612d04d | 140 | |
8b90a990 | 141 | entry = db->hash[id & (db->size - 1)]; |
4612d04d VK |
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 | } |