Annotation of embedaddon/ntp/sntp/kod_management.c, revision 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>