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>