Annotation of 43BSD/etc/named/db_load.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)db_load.c  4.3 (Berkeley) 5/30/86";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1986 Regents of the University of California
                      7:  *     All Rights Reserved
                      8:  */
                      9: 
                     10: /*
                     11:  * Load data base from ascii backupfile.  Format similar to RFC 883.
                     12:  */
                     13: 
                     14: #include <sys/types.h>
                     15: #include <sys/time.h>
                     16: #include <netinet/in.h>
                     17: #include <stdio.h>
                     18: #include <syslog.h>
                     19: #include <ctype.h>
                     20: #include <netdb.h>
                     21: #include <arpa/nameser.h>
                     22: #include "ns.h"
                     23: #include "db.h"
                     24: 
                     25: extern char *index();
                     26: 
                     27: /*
                     28:  * Map class and type names to number
                     29:  */
                     30: struct map {
                     31:        char    token[8];
                     32:        int     val;
                     33: };
                     34: 
                     35: struct map m_class[] = {
                     36:        "in",           C_IN,
                     37:        "any",          C_ANY,
                     38: };
                     39: #define NCLASS (sizeof(m_class)/sizeof(struct map))
                     40: 
                     41: struct map m_type[] = {
                     42:        "a",            T_A,
                     43:        "ns",           T_NS,
                     44:        "cname",        T_CNAME,
                     45:        "soa",          T_SOA,
                     46:        "mb",           T_MB,
                     47:        "mg",           T_MG,
                     48:        "mr",           T_MR,
                     49:        "null",         T_NULL,
                     50:        "wks",          T_WKS,
                     51:        "ptr",          T_PTR,
                     52:        "hinfo",        T_HINFO,
                     53:        "minfo",        T_MINFO,
                     54:        "mx",           T_MX,
                     55:        "uinfo",        T_UINFO,
                     56:        "uid",          T_UID,
                     57:        "gid",          T_GID,
                     58:        "any",          T_ANY,
                     59: };
                     60: #define NTYPE (sizeof(m_type)/sizeof(struct map))
                     61: 
                     62: /*
                     63:  * Parser token values
                     64:  */
                     65: #define CURRENT        1
                     66: #define DOT    2
                     67: #define AT     3
                     68: #define DNAME  4
                     69: #define INCLUDE        5
                     70: #define ORIGIN 6
                     71: 
                     72: int    lineno = 1;             /* current line number */
                     73: 
                     74: /*
                     75:  * Load the database from 'filename'. Origin is appended to all domain
                     76:  * names in the file.
                     77:  */
                     78: db_load(filename, in_origin, zone)
                     79:        char *filename, *in_origin;
                     80:        int zone;
                     81: {
                     82:        register char *cp;
                     83:        register struct map *mp;
                     84:        char domain[MAXDNAME];
                     85:        char origin[MAXDNAME];
                     86:        char buf[BUFSIZ];
                     87:        char data[MAXDATA];
                     88:        char *op;
                     89:        int class, type, ttl;
                     90:        struct databuf *dp;
                     91:        FILE *fp;
                     92:        int slineno, i;
                     93:        long n;
                     94: 
                     95: #ifdef DEBUG
                     96:        if (debug)
                     97:                fprintf(ddt,"db_load(%s, %s, %d)\n", filename, in_origin, zone);
                     98: #endif
                     99: 
                    100:        (void) strcpy(origin, in_origin);
                    101:        if ((fp = fopen(filename, "r")) == NULL) {
                    102:                syslog(LOG_ERR, "%s: %m", filename);
                    103:                return (NODBFILE);
                    104:        }
                    105:        lineno = 1;
                    106:        domain[0] = '\0';
                    107:        class = C_IN;
                    108:        while ((n = gettoken(fp)) != EOF) {
                    109:                switch ((int)n) {
                    110:                case INCLUDE:
                    111:                        if (!getword(buf, sizeof(buf), fp)) /* file name */
                    112:                                break;
                    113:                        slineno = lineno;
                    114:                        (void) db_load(buf, origin, zone);
                    115:                        lineno = slineno;
                    116:                        continue;
                    117: 
                    118:                case ORIGIN:
                    119:                        (void) strcpy(buf, origin);
                    120:                        if (!getword(origin, sizeof(origin), fp))
                    121:                                break;
                    122:                        makename(origin, buf);
                    123:                        continue;
                    124: 
                    125:                case DNAME:
                    126:                        if (!getword(domain, sizeof(domain), fp))
                    127:                                break;
                    128:                        n = strlen(domain) - 1;
                    129:                        if (domain[n] == '.')
                    130:                                domain[n] = '\0';
                    131:                        else if (*origin) {
                    132:                                (void) strcat(domain, ".");
                    133:                                (void) strcat(domain, origin);
                    134:                        }
                    135:                        goto gotdomain;
                    136: 
                    137:                case AT:
                    138:                        (void) strcpy(domain, origin);
                    139:                        goto gotdomain;
                    140: 
                    141:                case DOT:
                    142:                        domain[0] = '\0';
                    143:                        /* fall thru ... */
                    144:                case CURRENT:
                    145:                gotdomain:
                    146:                        if (!getword(buf, sizeof(buf), fp))
                    147:                                break;
                    148:                        cp = buf;
                    149:                        if (isdigit(*cp)) {
                    150:                                n = 0;
                    151:                                do
                    152:                                        n = n * 10 + (*cp++ - '0');
                    153:                                while (isdigit(*cp));
                    154:                                if (zone == 0) {
                    155:                                    if (gettimeofday(&tt,
                    156:                                        (struct timezone *)0) < 0)
                    157:                                        syslog(LOG_ERR,
                    158:                                           "gettimeofday failed: %m");
                    159:                                        n += (long) tt.tv_sec;
                    160:                                }
                    161:                                ttl = n;
                    162:                                if (!getword(buf, sizeof(buf), fp))
                    163:                                        break;
                    164:                        } else
                    165:                                ttl = 0;
                    166:                        for (mp = m_class; mp < m_class+NCLASS; mp++)
                    167:                                if (!cistrcmp(buf, mp->token)) {
                    168:                                        class = mp->val;
                    169:                                        (void) getword(buf, sizeof(buf), fp);
                    170:                                        break;
                    171:                                }
                    172:                        for (mp = m_type; mp < m_type+NTYPE; mp++)
                    173:                                if (!cistrcmp(buf, mp->token)) {
                    174:                                        type = mp->val;
                    175:                                        goto fndtype;
                    176:                                }
                    177: #ifdef DEBUG
                    178:                        if (debug)
                    179:                                fprintf(ddt,"Unknown type: %s.\n", buf);
                    180: #endif
                    181:                        break;
                    182:                fndtype:
                    183:                        if (!getword(buf, sizeof(buf), fp))
                    184:                                break;
                    185: #ifdef DEBUG
                    186:                        if (debug >= 3)
                    187:                            fprintf(ddt,"d='%s',c=%d,t=%d, ttl=%d, data='%s'\n",
                    188:                                        domain, class, type, ttl, buf);
                    189: #endif
                    190:                        /*
                    191:                         * Convert the ascii data 'buf' to the proper format
                    192:                         * based on the type and pack into 'data'.
                    193:                         */
                    194:                        switch (type) {
                    195:                        case T_A:
                    196:                                n = ntohl((u_long)inet_addr((char *)buf));
                    197:                                putlong((u_long)n, data);
                    198:                                n = sizeof(u_long);
                    199:                                break;
                    200: 
                    201:                        case T_HINFO:
                    202:                                n = strlen(buf);
                    203:                                if (n > 255) {
                    204:                                    syslog(LOG_WARNING, "CPU too large (%d)",n);
                    205:                                    n = 255;
                    206:                                }
                    207:                                data[0] = n;
                    208:                                bcopy(buf, (char *)data + 1, (int)n);
                    209:                                n++;
                    210:                                if (!getword(buf, sizeof(buf), fp))
                    211:                                        break;
                    212:                                i = strlen(buf);
                    213:                                if (i > 255) {
                    214:                                    syslog(LOG_WARNING, "OS too large (%d)", i);
                    215:                                    i = 255;
                    216:                                }
                    217:                                data[n] = i;
                    218:                                bcopy(buf, data + n + 1, i);
                    219:                                n += i + 1;
                    220:                                break;
                    221: 
                    222:                        case T_SOA:
                    223:                        case T_MINFO:
                    224:                                (void) strcpy(data, buf);
                    225:                                makename(data, origin);
                    226:                                cp = data + strlen(data) + 1;
                    227:                                if (!getword(cp, sizeof(data) - (cp - data),fp))
                    228:                                        break;
                    229:                                makename(cp, origin);
                    230:                                cp += strlen(cp) + 1;
                    231:                                if (type == T_MINFO) {
                    232:                                        n = cp - data;
                    233:                                        break;
                    234:                                }
                    235:                                if (getnonblank(fp) != '(')
                    236:                                        goto err;
                    237:                                putlong((u_long)(zones[zone].z_serial =
                    238:                                    getnum(fp)), cp);
                    239:                                cp += sizeof(u_long);
                    240:                                putlong((u_long)(zones[zone].z_refresh =
                    241:                                    getnum(fp)), cp);
                    242:                                cp += sizeof(u_long);
                    243:                                putlong((u_long)(zones[zone].z_retry =
                    244:                                    getnum(fp)), cp);
                    245:                                cp += sizeof(u_long);
                    246:                                putlong ((u_long)(zones[zone].z_expire =
                    247:                                    getnum(fp)), cp);
                    248:                                cp += sizeof(u_long);
                    249:                                putlong ((u_long)(zones[zone].z_minimum =
                    250:                                    getnum(fp)), cp);
                    251:                                cp += sizeof(u_long);
                    252:                                n = cp - data;
                    253:                                if (getnonblank(fp) != ')')
                    254:                                        goto err;
                    255:                                endline(fp);
                    256:                                break;
                    257: 
                    258:                        case T_UID:
                    259:                        case T_GID:
                    260:                                n = 0;
                    261:                                cp = buf;
                    262:                                while (isdigit(*cp))
                    263:                                        n = n * 10 + (*cp++ - '0');
                    264:                                if (cp == buf)
                    265:                                        goto err;
                    266:                                putlong((u_long)n, data);
                    267:                                n = sizeof(long);
                    268:                                break;
                    269: 
                    270:                        case T_WKS:
                    271:                                /* Address */
                    272:                                n = ntohl((u_long)inet_addr((char *)buf));
                    273:                                putlong((u_long)n, data);
                    274:                                data[sizeof(u_long)] = getprotocol(fp);
                    275:                                /* Protocol */
                    276:                                n = sizeof(u_long) + sizeof(char);
                    277:                                /* Services */
                    278:                                n = getservices((int)n, data, fp);
                    279:                                break;
                    280: 
                    281:                        case T_NS:
                    282:                        case T_CNAME:
                    283:                        case T_MB:
                    284:                        case T_MG:
                    285:                        case T_MR:
                    286:                        case T_PTR:
                    287:                                (void) strcpy(data, buf);
                    288:                                makename(data, origin);
                    289:                                n = strlen(data) + 1;
                    290:                                break;
                    291: 
                    292:                        case T_UINFO:
                    293:                                cp = index(buf, '&');
                    294:                                bzero(data, sizeof(data));
                    295:                                if ( cp != NULL) {
                    296:                                        (void) strncpy(data, buf, cp - buf);
                    297:                                        op = index(domain, '.');
                    298:                                        if ( op != NULL)
                    299:                                            (void) strncat(data,
                    300:                                                domain,op-domain);
                    301:                                        else
                    302:                                                (void) strcat(data, domain);
                    303:                                        (void) strcat(data, ++cp);
                    304:                                } else
                    305:                                        (void) strcpy(data, buf);
                    306:                                n = strlen(data) + 1;
                    307:                                break;
                    308:                        case T_MX:
                    309:                                n = 0;
                    310:                                cp = buf;
                    311:                                while (isdigit(*cp))
                    312:                                        n = n * 10 + (*cp++ - '0');
                    313:                                /* catch bad values */
                    314:                                if ((cp == buf) || (n & ~0xffff))
                    315:                                        goto err;
                    316: 
                    317:                                putshort((u_short)n, data);
                    318:                                cp = data + sizeof(u_short);
                    319: 
                    320:                                if (!getword(buf, sizeof(buf), fp))
                    321:                                            break;
                    322:                                (void) strcpy(cp,buf);
                    323:                                makename(cp, origin);
                    324:                                /* get pointer to place in data */
                    325:                                cp += strlen(cp) +1;
                    326: 
                    327:                                /* now save length */
                    328:                                n = (cp - data);
                    329:                                break;
                    330: 
                    331:                        default:
                    332:                                goto err;
                    333:                        }
                    334:                        dp = savedata(class, type, (u_long)ttl, data, (int)n);
                    335:                        dp->d_zone = zone;
                    336:                        if ((n = db_update(domain, dp, dp, DB_NODATA)) < 0) {
                    337: #ifdef DEBUG
                    338:                                if (debug && (n != DATAEXISTS))
                    339:                                        fprintf(ddt,"update failed\n");
                    340: #endif
                    341:                        }
                    342:                        continue;
                    343:                }
                    344:        err:
                    345:                syslog(LOG_ERR, "%s: line %d: database format error (%s)",
                    346:                        filename, lineno, buf);
                    347:                (void) fclose(fp);
                    348:                return (-1);
                    349:        }
                    350:        (void) fclose(fp);
                    351:        return (OK);
                    352: }
                    353: 
                    354: int gettoken(fp)
                    355:        register FILE *fp;
                    356: {
                    357:        register int c;
                    358:        char op[32];
                    359: 
                    360:        for (;;) {
                    361:                c = getc(fp);
                    362:        top:
                    363:                switch (c) {
                    364:                case EOF:
                    365:                        return (EOF);
                    366: 
                    367:                case '$':
                    368:                        if (!getword(op, sizeof(op), fp))
                    369:                                return (EOF);
                    370:                        if (!cistrcmp("include", op))
                    371:                                return (INCLUDE);
                    372:                        if (!cistrcmp("origin", op))
                    373:                                return (ORIGIN);
                    374:                        printf("Unknown $ option: %s\n", op);
                    375:                        /* fall through... */
                    376: 
                    377:                case ';':
                    378:                        while ((c = getc(fp)) != EOF && c != '\n')
                    379:                                ;
                    380:                        goto top;
                    381: 
                    382:                case ' ':
                    383:                case '\t':
                    384:                        return (CURRENT);
                    385: 
                    386:                case '.':
                    387:                        return (DOT);
                    388: 
                    389:                case '@':
                    390:                        return (AT);
                    391: 
                    392:                case '\n':
                    393:                        lineno++;
                    394:                        continue;
                    395: 
                    396:                default:
                    397:                        (void) ungetc(c, fp);
                    398:                        return (DNAME);
                    399:                }
                    400:        }
                    401: }
                    402: 
                    403: /*
                    404:  * Get next word, skipping blanks & comments.
                    405:  */
                    406: getword(buf, size, fp)
                    407:        char *buf;
                    408:        int size;
                    409:        FILE *fp;
                    410: {
                    411:        register char *cp;
                    412:        register int c;
                    413: 
                    414:        for (cp = buf; (c = getc(fp)) != EOF; ) {
                    415:                if (isspace(c)) {
                    416:                        if (c == '\n')
                    417:                                lineno++;
                    418:                        if (cp != buf)
                    419:                                break;
                    420:                        continue;
                    421:                }
                    422:                if (c == ';') {
                    423:                        while ((c = getc(fp)) != EOF && c != '\n')
                    424:                                ;
                    425:                        if (c == '\n')
                    426:                                lineno++;
                    427:                        if (cp != buf)
                    428:                                break;
                    429:                        continue;
                    430:                }
                    431:                if (c == '"') {
                    432:                        while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
                    433:                                if (c == '\\') {
                    434:                                        if ((c = getc(fp)) == EOF)
                    435:                                                c = '\\';
                    436:                                        if (c == '\n')
                    437:                                                lineno++;
                    438:                                }
                    439:                                if (cp >= buf+size-1)
                    440:                                        break;
                    441:                                *cp++ = c;
                    442:                        }
                    443:                        if (c == '\n') {
                    444:                                lineno++;
                    445:                                break;
                    446:                        }
                    447:                        continue;
                    448:                }
                    449:                if (c == '\\') {
                    450:                        if ((c = getc(fp)) == EOF)
                    451:                                c = '\\';
                    452:                        if (c == '\n')
                    453:                                lineno++;
                    454:                }
                    455:                if (cp >= buf+size-1)
                    456:                        break;
                    457:                *cp++ = c;
                    458:        }
                    459:        *cp = '\0';
                    460:        return (cp != buf);
                    461: }
                    462: 
                    463: getw_b_nl(buf, size, fp)
                    464:        char *buf;
                    465:        int size;
                    466:        FILE *fp;
                    467: {
                    468:        register char *cp;
                    469:        register int c;
                    470: 
                    471:        for (cp = buf; (c = getc(fp)) != EOF; ) {
                    472:                if (isspace(c)) {
                    473:                        if (c == '\n') {
                    474:                                *cp = '\0';
                    475:                                return (0);
                    476:                        }
                    477:                        if (cp != buf)
                    478:                                break;
                    479:                        continue;
                    480:                }
                    481:                if (c == ';') {
                    482:                        while ((c = getc(fp)) != EOF && c != '\n')
                    483:                                ;
                    484:                        if (c == '\n')
                    485:                                lineno++;
                    486:                        if (cp != buf)
                    487:                                break;
                    488:                        continue;
                    489:                }
                    490:                if (cp >= buf+size-1)
                    491:                        break;
                    492:                *cp++ = c;
                    493:        }
                    494:        *cp = '\0';
                    495:        return (cp != buf);
                    496: }
                    497: 
                    498: getnum(fp)
                    499:        FILE *fp;
                    500: {
                    501:        register int c, n;
                    502:        int seendigit = 0;
                    503:        int seendecimal = 0;
                    504: 
                    505:        for (n = 0; (c = getc(fp)) != EOF; ) {
                    506:                if (isspace(c)) {
                    507:                        if (c == '\n')
                    508:                                lineno++;
                    509:                        if (seendigit)
                    510:                                break;
                    511:                        continue;
                    512:                }
                    513:                if (c == ';') {
                    514:                        while ((c = getc(fp)) != EOF && c != '\n')
                    515:                                ;
                    516:                        if (c == '\n')
                    517:                                lineno++;
                    518:                        if (seendigit)
                    519:                                break;
                    520:                        continue;
                    521:                }
                    522:                if (!isdigit(c)) {
                    523:                        if (c != '.') {
                    524:                                syslog(LOG_ERR, "line %d: expected a number",
                    525:                                lineno);
                    526:                                exit(1);
                    527:                        }
                    528:                        if (!seendigit)
                    529:                                n = 1;
                    530:                        if (seendecimal) {
                    531:                                syslog(LOG_ERR, "line %d: expected a number",
                    532:                                lineno);
                    533:                                exit(1);
                    534:                        } else {
                    535:                                n = n * 1000 ;
                    536:                                seendigit = 1;
                    537:                                seendecimal = 1;
                    538:                        }
                    539:                        continue;
                    540:                }
                    541:                n = n * 10 + (c - '0');
                    542:                seendigit = 1;
                    543:        }
                    544:        return (n);
                    545: }
                    546: 
                    547: getnonblank(fp)
                    548:        FILE *fp;
                    549: {
                    550:        register int c;
                    551: 
                    552:        while ( (c = getc(fp)) != EOF ) {
                    553:                if (isspace(c)) {
                    554:                        if (c == '\n')
                    555:                                lineno++;
                    556:                        continue;
                    557:                }
                    558:                if (c == ';') {
                    559:                        while ((c = getc(fp)) != EOF && c != '\n')
                    560:                                ;
                    561:                        if (c == '\n')
                    562:                                lineno++;
                    563:                        continue;
                    564:                }
                    565:                return(c);
                    566:        }
                    567:        syslog(LOG_ERR, "line %d: unexpected EOF", lineno);
                    568:        return (EOF);
                    569: }
                    570: 
                    571: /*
                    572:  * Take name and fix it according to following rules:
                    573:  * "." means root.
                    574:  * "@" means current origin.
                    575:  * "name." means no changes.
                    576:  * "name" means append origin.
                    577:  */
                    578: makename(name, origin)
                    579:        char *name, *origin;
                    580: {
                    581:        int n;
                    582: 
                    583:        if (origin[0] == '.')
                    584:                origin++;
                    585:        n = strlen(name);
                    586:        if (n == 1) {
                    587:                if (name[0] == '.') {
                    588:                        name[0] = '\0';
                    589:                        return;
                    590:                }
                    591:                if (name[0] == '@') {
                    592:                        (void) strcpy(name, origin);
                    593:                        return;
                    594:                }
                    595:        }
                    596:        if (n > 0) {
                    597:                if (name[n - 1] == '.')
                    598:                        name[n - 1] = '\0';
                    599:                else if (origin[0] != '\0') {
                    600:                        name[n] = '.';
                    601:                        (void) strcpy(name + n + 1, origin);
                    602:                }
                    603:        }
                    604: }
                    605: 
                    606: endline(fp)
                    607:      register FILE *fp;
                    608: {
                    609:      register int c;
                    610:      while (c = getc(fp))
                    611:        if ((c == EOF) || (c == '\n')) {
                    612:            (void) ungetc(c,fp);
                    613:            break;
                    614:        }
                    615: }
                    616: 
                    617: #define MAXPORT 256
                    618: #define MAXLEN 24
                    619: 
                    620: getprotocol(fp)
                    621:     FILE *fp;
                    622: {
                    623:        int  k;
                    624:        char b[MAXLEN];
                    625:        struct protoent *proto;
                    626: 
                    627:        (void) getword(b, sizeof(b), fp);
                    628:                
                    629:        proto = getprotobyname(b);      
                    630:        if(proto == NULL) {
                    631:                k = 0;
                    632:                (void) sscanf(b,"%d",&k);
                    633:        }
                    634:        else
                    635:                k = proto->p_proto;
                    636:        return(k);
                    637: }
                    638: 
                    639: int getservices(n, data, fp)
                    640:     int n;
                    641:     char *data;
                    642:     FILE *fp;
                    643: {
                    644:        int j, ch;
                    645:        u_short k;
                    646:        int maxl;
                    647:        int bracket, eol;
                    648:        char b[MAXLEN];
                    649:        char bm[MAXPORT/8];
                    650:        struct servent *service;
                    651: 
                    652:        for (j = 0; j < MAXPORT/8; j++)
                    653:                bm[j] = 0;
                    654:        maxl = 0;
                    655:        bracket = eol = 0;
                    656:        while (1) {
                    657:                if (!getw_b_nl(b, sizeof(b), fp) && (!bracket)) {
                    658:                        if (strlen(b) == 0)
                    659:                                break;
                    660:                        eol++;
                    661:                }       
                    662:                if ( b[0] == '(') {
                    663:                        bracket++;
                    664:                        continue;
                    665:                }
                    666:                if ( b[0] == ')') {
                    667:                        bracket = 0;
                    668:                        while ((ch = getc(fp)) != EOF && ch != '\n')
                    669:                                ;
                    670:                        break;
                    671:                }
                    672:                service = getservbyname(b, (char *)NULL);
                    673:                if (service == NULL) {
                    674:                        k=0;
                    675:                        (void) sscanf(b,"%d",&k);
                    676:                        if (k == 0)
                    677:                                continue;
                    678:                }
                    679:                else
                    680:                        k = ntohs((u_short)service->s_port);
                    681:                if ((k < MAXPORT) && (k)) {
                    682:                        bm[k/8] |= (0x80>>(k%8));
                    683:                        if (k > maxl)
                    684:                                maxl=k;
                    685:                }
                    686:                else
                    687:                        syslog(LOG_WARNING,"port no.(%d) too big\n",k);
                    688:                if(eol)
                    689:                        break;
                    690:        }
                    691:        maxl = maxl/8+1;
                    692:        bcopy(bm, data+n, maxl);
                    693:        return(maxl+n);
                    694: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.