File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / sntp / kod_management.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 2 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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>