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>