Annotation of embedaddon/ntp/sntp/kod_management.c, revision 1.1.1.1
1.1 misho 1: #include <config.h>
2: #include <string.h>
3: #include <sys/types.h>
4: #include <sys/stat.h>
5:
6: #include "kod_management.h"
7: #include "log.h"
8: #include "sntp-opts.h"
9: #include "ntp_stdlib.h"
10: //#define DEBUG
11:
12: int kod_init = 0, kod_db_cnt = 0;
13: const char *kod_db_file;
14: struct kod_entry **kod_db; /* array of pointers to kod_entry */
15:
16:
17: /*
18: * Search for a KOD entry
19: */
20: int
21: search_entry (
22: char *hostname,
23: struct kod_entry **dst
24: )
25: {
26: register int a, b, resc = 0;
27:
28: for (a = 0; a < kod_db_cnt; a++)
29: if (!strcmp(kod_db[a]->hostname, hostname))
30: resc++;
31:
32: if (!resc) {
33: *dst = NULL;
34: return 0;
35: }
36:
37: *dst = emalloc(resc * sizeof(**dst));
38:
39: b = 0;
40: for (a = 0; a < kod_db_cnt; a++)
41: if (!strcmp(kod_db[a]->hostname, hostname)) {
42: (*dst)[b] = *kod_db[a];
43: b++;
44: }
45:
46: return resc;
47: }
48:
49:
50: void
51: add_entry(
52: char *hostname,
53: char *type /* 4 bytes not \0 terminated */
54: )
55: {
56: int n;
57: struct kod_entry *pke;
58:
59: pke = emalloc(sizeof(*pke));
60: pke->timestamp = time(NULL);
61: memcpy(pke->type, type, 4);
62: pke->type[sizeof(pke->type) - 1] = '\0';
63: strncpy(pke->hostname, hostname,
64: sizeof(pke->hostname));
65: pke->hostname[sizeof(pke->hostname) - 1] = '\0';
66:
67: /*
68: * insert in address ("hostname") order to find duplicates
69: */
70: for (n = 0; n < kod_db_cnt; n++)
71: if (strcmp(kod_db[n]->hostname, pke->hostname) >= 0)
72: break;
73:
74: if (n < kod_db_cnt &&
75: 0 == strcmp(kod_db[n]->hostname, pke->hostname)) {
76: kod_db[n]->timestamp = pke->timestamp;
77: free(pke);
78: return;
79: }
80:
81: kod_db_cnt++;
82: kod_db = erealloc(kod_db, kod_db_cnt * sizeof(kod_db[0]));
83: if (n != kod_db_cnt - 1)
84: memmove(&kod_db[n + 1], &kod_db[n],
85: sizeof(kod_db[0]) * ((kod_db_cnt - 1) - n));
86: kod_db[n] = pke;
87: }
88:
89:
90: void
91: delete_entry(
92: char *hostname,
93: char *type
94: )
95: {
96: register int a;
97:
98: for (a = 0; a < kod_db_cnt; a++)
99: if (!strcmp(kod_db[a]->hostname, hostname)
100: && !strcmp(kod_db[a]->type, type))
101: break;
102:
103: if (a == kod_db_cnt)
104: return;
105:
106: free(kod_db[a]);
107: kod_db_cnt--;
108:
109: if (a < kod_db_cnt)
110: memmove(&kod_db[a], &kod_db[a + 1],
111: (kod_db_cnt - a) * sizeof(kod_db[0]));
112: }
113:
114:
115: void
116: write_kod_db(void)
117: {
118: FILE *db_s;
119: char *pch;
120: int dirmode;
121: register int a;
122:
123: db_s = fopen(kod_db_file, "w");
124:
125: /*
126: * If opening fails, blindly attempt to create each directory
127: * in the path first, then retry the open.
128: */
129: if (NULL == db_s && strlen(kod_db_file)) {
130: dirmode = S_IRUSR | S_IWUSR | S_IXUSR
131: | S_IRGRP | S_IXGRP
132: | S_IROTH | S_IXOTH;
133: pch = strchr(kod_db_file + 1, DIR_SEP);
134: while (NULL != pch) {
135: *pch = '\0';
136: mkdir(kod_db_file, dirmode);
137: *pch = DIR_SEP;
138: pch = strchr(pch + 1, DIR_SEP);
139: }
140: db_s = fopen(kod_db_file, "w");
141: }
142:
143: if (NULL == db_s) {
144: msyslog(LOG_WARNING, "Can't open KOD db file %s for writing!",
145: kod_db_file);
146:
147: return;
148: }
149:
150: for (a = 0; a < kod_db_cnt; a++) {
151: fprintf(db_s, "%16.16llx %s %s\n", (unsigned long long)
152: kod_db[a]->timestamp, kod_db[a]->type,
153: kod_db[a]->hostname);
154: }
155:
156: fflush(db_s);
157: fclose(db_s);
158: }
159:
160:
161: void
162: kod_init_kod_db(
163: const char *db_file
164: )
165: {
166: /*
167: * Max. of 254 characters for hostname, 10 for timestamp, 4 for
168: * kisscode, 2 for spaces, 1 for \n, and 1 for \0
169: */
170: char fbuf[254+10+4+2+1+1];
171: FILE *db_s;
172: int a, b, sepc, len;
173: unsigned long long ull;
174: char *str_ptr;
175: char error = 0;
176:
177: atexit(write_kod_db);
178:
179: #ifdef DEBUG
180: printf("Initializing KOD DB...\n");
181: #endif
182:
183: kod_db_file = estrdup(db_file);
184:
185:
186: db_s = fopen(db_file, "r");
187:
188: if (NULL == db_s) {
189: msyslog(LOG_WARNING, "kod_init_kod_db(): Cannot open KoD db file %s",
190: db_file);
191:
192: return;
193: }
194:
195: if (ENABLED_OPT(NORMALVERBOSE))
196: printf("Starting to read KoD file %s...\n", db_file);
197: /* First let's see how many entries there are and check for right syntax */
198:
199: while (!feof(db_s) && NULL != fgets(fbuf, sizeof(fbuf), db_s)) {
200:
201: /* ignore blank lines */
202: if ('\n' == fbuf[0])
203: continue;
204:
205: sepc = 0;
206: len = strlen(fbuf);
207: for (a = 0; a < len; a++) {
208: if (' ' == fbuf[a])
209: sepc++;
210:
211: if ('\n' == fbuf[a]) {
212: if (sepc != 2) {
213: if (strcmp(db_file, "/dev/null"))
214: msyslog(LOG_DEBUG,
215: "Syntax error in KoD db file %s in line %i (missing space)",
216: db_file,
217: kod_db_cnt + 1);
218: fclose(db_s);
219: return;
220: }
221: sepc = 0;
222: kod_db_cnt++;
223: }
224: }
225: }
226:
227: if (0 == kod_db_cnt) {
228: #ifdef DEBUG
229: printf("KoD DB %s empty.\n", db_file);
230: #endif
231: fclose(db_s);
232: return;
233: }
234:
235: #ifdef DEBUG
236: printf("KoD DB %s contains %d entries, reading...\n", db_file, kod_db_cnt);
237: #endif
238:
239: rewind(db_s);
240:
241: kod_db = emalloc(sizeof(kod_db[0]) * kod_db_cnt);
242:
243: /* Read contents of file */
244: for (b = 0;
245: !feof(db_s) && !ferror(db_s) && b < kod_db_cnt;
246: b++) {
247:
248: str_ptr = fgets(fbuf, sizeof(fbuf), db_s);
249: if (NULL == str_ptr) {
250: error = 1;
251: break;
252: }
253:
254: /* ignore blank lines */
255: if ('\n' == fbuf[0]) {
256: b--;
257: continue;
258: }
259:
260: kod_db[b] = emalloc(sizeof(*kod_db[b]));
261:
262: if (3 != sscanf(fbuf, "%llx %4s %254s", &ull,
263: kod_db[b]->type, kod_db[b]->hostname)) {
264:
265: free(kod_db[b]);
266: kod_db[b] = NULL;
267: error = 1;
268: break;
269: }
270:
271: kod_db[b]->timestamp = (time_t)ull;
272: }
273:
274: if (ferror(db_s) || error) {
275: kod_db_cnt = b;
276: msyslog(LOG_WARNING, "An error occured while parsing the KoD db file %s",
277: db_file);
278: fclose(db_s);
279:
280: return;
281: }
282:
283: fclose(db_s);
284: #ifdef DEBUG
285: for (a = 0; a < kod_db_cnt; a++)
286: printf("KoD entry %d: %s at %llx type %s\n", a,
287: kod_db[a]->hostname,
288: (unsigned long long)kod_db[a]->timestamp,
289: kod_db[a]->type);
290: #endif
291: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>