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

1.1       root        1: /*
                      2:  * Copyright (c) 1986 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: static char sccsid[] = "@(#)db_load.c  4.27 (Berkeley) 6/18/88";
                     20: #endif /* not lint */
                     21: 
                     22: /*
                     23:  * Load data base from ascii backupfile.  Format similar to RFC 883.
                     24:  */
                     25: 
                     26: #include <sys/param.h>
                     27: #include <sys/time.h>
                     28: #include <sys/stat.h>
                     29: #include <netinet/in.h>
                     30: #include <stdio.h>
                     31: #include <syslog.h>
                     32: #include <ctype.h>
                     33: #include <netdb.h>
                     34: #include <arpa/nameser.h>
                     35: #include "ns.h"
                     36: #include "db.h"
                     37: 
                     38: extern char *index();
                     39: extern int max_cache_ttl;
                     40: 
                     41: /*
                     42:  * Map class and type names to number
                     43:  */
                     44: struct map {
                     45:        char    token[8];
                     46:        int     val;
                     47: };
                     48: 
                     49: struct map m_class[] = {
                     50:        "in",           C_IN,
                     51: #ifdef notdef
                     52:        "any",          C_ANY,          /* any is a QCLASS, not CLASS */
                     53: #endif
                     54:        "chaos",        C_CHAOS,
                     55: };
                     56: #define NCLASS (sizeof(m_class)/sizeof(struct map))
                     57: 
                     58: struct map m_type[] = {
                     59:        "a",            T_A,
                     60:        "ns",           T_NS,
                     61:        "cname",        T_CNAME,
                     62:        "soa",          T_SOA,
                     63:        "mb",           T_MB,
                     64:        "mg",           T_MG,
                     65:        "mr",           T_MR,
                     66:        "null",         T_NULL,
                     67:        "wks",          T_WKS,
                     68:        "ptr",          T_PTR,
                     69:        "hinfo",        T_HINFO,
                     70:        "minfo",        T_MINFO,
                     71:        "mx",           T_MX,
                     72:        "uinfo",        T_UINFO,
                     73:        "uid",          T_UID,
                     74:        "gid",          T_GID,
                     75: #ifdef notdef
                     76:        "any",          T_ANY,          /* any is a QTYPE, not TYPE */
                     77: #endif
                     78: #ifdef ALLOW_T_UNSPEC
                     79:         "unspec",       T_UNSPEC,
                     80: #endif ALLOW_T_UNSPEC
                     81: };
                     82: #define NTYPE (sizeof(m_type)/sizeof(struct map))
                     83: 
                     84: /*
                     85:  * Parser token values
                     86:  */
                     87: #define CURRENT        1
                     88: #define DOT    2
                     89: #define AT     3
                     90: #define DNAME  4
                     91: #define INCLUDE        5
                     92: #define ORIGIN 6
                     93: #define ERROR  7
                     94: 
                     95: int    lineno;         /* current line number */
                     96: 
                     97: struct valuelist {
                     98:        struct valuelist *next, *prev;
                     99:        char    *name;
                    100:        char    *proto;
                    101:        short   port;
                    102: } *servicelist, *protolist;
                    103: 
                    104: /*
                    105:  * Load the database from 'filename'. Origin is appended to all domain
                    106:  * names in the file.
                    107:  */
                    108: db_load(filename, in_origin, zp)
                    109:        char *filename, *in_origin;
                    110:        struct zoneinfo *zp;
                    111: {
                    112:        register u_char *cp;
                    113:        register struct map *mp;
                    114:        char domain[MAXDNAME];
                    115:        char origin[MAXDNAME];
                    116:        char tmporigin[MAXDNAME];
                    117:        u_char buf[BUFSIZ];
                    118:        u_char data[MAXDATA];
                    119:        char *op;
                    120:        int c;
                    121:        int class, type, ttl, dbflags, dataflags;
                    122:        struct databuf *dp;
                    123:        FILE *fp;
                    124:        int slineno, i, errs = 0, didinclude = 0;
                    125:        register u_long n;
                    126:        struct stat sb;
                    127: 
                    128: #ifdef DEBUG
                    129:        if (debug)
                    130:                fprintf(ddt,"db_load(%s, %s, %d)\n",
                    131:                    filename, in_origin, zp - zones);
                    132: #endif
                    133: 
                    134:        (void) strcpy(origin, in_origin);
                    135:        if ((fp = fopen(filename, "r")) == NULL) {
                    136:                if (zp->z_type != Z_SECONDARY)
                    137:                        syslog(LOG_ERR, "%s: %m", filename);
                    138: #ifdef DEBUG
                    139:                if (debug)
                    140:                    fprintf(ddt,"db_load: error opening file %s\n", filename);
                    141: #endif
                    142:                return (-1);
                    143:        }
                    144:        if (zp->z_type == Z_CACHE) {
                    145:            dbflags = DB_NODATA | DB_NOHINTS;
                    146:            dataflags = DB_F_HINT;
                    147:        } else {
                    148:            dbflags = DB_NODATA;
                    149:            dataflags = 0;
                    150:        }
                    151:        gettime(&tt);
                    152:        if (fstat(fileno(fp), &sb) < 0) {
                    153:            syslog(LOG_ERR, "%s: %m", filename);
                    154:            sb.st_mtime = (int)tt.tv_sec;
                    155:        }
                    156:        slineno = lineno;
                    157:        lineno = 1;
                    158:        domain[0] = '\0';
                    159:        class = C_IN;
                    160:        while ((c = gettoken(fp)) != EOF) {
                    161:                switch (c) {
                    162:                case INCLUDE:
                    163:                        if (!getword(buf, sizeof(buf), fp)) /* file name */
                    164:                                break;
                    165:                        if (!getword(tmporigin, sizeof(tmporigin), fp))
                    166:                                strcpy(tmporigin, origin);
                    167:                        else {
                    168:                                makename(tmporigin, origin);
                    169:                                endline(fp);
                    170:                        }
                    171:                        didinclude = 1;
                    172:                        errs += db_load(buf, tmporigin, zp);
                    173:                        continue;
                    174: 
                    175:                case ORIGIN:
                    176:                        (void) strcpy(buf, origin);
                    177:                        if (!getword(origin, sizeof(origin), fp))
                    178:                                break;
                    179: #ifdef DEBUG
                    180:                        if (debug > 3)
                    181:                                fprintf(ddt,"db_load: origin %s, buf %s\n",
                    182:                                    origin, buf);
                    183: #endif
                    184:                        makename(origin, buf);
                    185: #ifdef DEBUG
                    186:                        if (debug > 3)
                    187:                                fprintf(ddt,"db_load: origin now %s\n", origin);
                    188: #endif
                    189:                        continue;
                    190: 
                    191:                case DNAME:
                    192:                        if (!getword(domain, sizeof(domain), fp))
                    193:                                break;
                    194:                        n = strlen(domain) - 1;
                    195:                        if (domain[n] == '.')
                    196:                                domain[n] = '\0';
                    197:                        else if (*origin) {
                    198:                                (void) strcat(domain, ".");
                    199:                                (void) strcat(domain, origin);
                    200:                        }
                    201:                        goto gotdomain;
                    202: 
                    203:                case AT:
                    204:                        (void) strcpy(domain, origin);
                    205:                        goto gotdomain;
                    206: 
                    207:                case DOT:
                    208:                        domain[0] = '\0';
                    209:                        /* fall thru ... */
                    210:                case CURRENT:
                    211:                gotdomain:
                    212:                        if (!getword(buf, sizeof(buf), fp)) {
                    213:                                if (c == CURRENT)
                    214:                                        continue;
                    215:                                break;
                    216:                        }
                    217:                        cp = buf;
                    218:                        ttl = 0;
                    219:                        if (isdigit(*cp)) {
                    220:                                n = 0;
                    221:                                do
                    222:                                        n = n * 10 + (*cp++ - '0');
                    223:                                while (isdigit(*cp));
                    224:                                if (zp->z_type == Z_CACHE) {
                    225:                                    /* this allows the cache entry to age */
                    226:                                    /* while sitting on disk (powered off) */
                    227:                                    if (n > max_cache_ttl)
                    228:                                        n = max_cache_ttl;
                    229:                                    n += sb.st_mtime;
                    230:                                }
                    231:                                ttl = n;
                    232:                                if (!getword(buf, sizeof(buf), fp))
                    233:                                        break;
                    234:                        }
                    235:                        for (mp = m_class; mp < m_class+NCLASS; mp++)
                    236:                                if (!strcasecmp(buf, mp->token)) {
                    237:                                        class = mp->val;
                    238:                                        (void) getword(buf, sizeof(buf), fp);
                    239:                                        break;
                    240:                                }
                    241:                        for (mp = m_type; mp < m_type+NTYPE; mp++)
                    242:                                if (!strcasecmp(buf, mp->token)) {
                    243:                                        type = mp->val;
                    244:                                        goto fndtype;
                    245:                                }
                    246: #ifdef DEBUG
                    247:                        if (debug)
                    248:                                fprintf(ddt,"Line %d: Unknown type: %s.\n",
                    249:                                        lineno, buf);
                    250: #endif
                    251:                        errs++;
                    252:                        syslog(LOG_ERR, "Line %d: Unknown type: %s.\n",
                    253:                                lineno, buf);
                    254:                        break;
                    255:                fndtype:
                    256: #ifdef ALLOW_T_UNSPEC
                    257:                        /* Don't do anything here for T_UNSPEC...
                    258:                         * read input separately later
                    259:                         */
                    260:                         if (type != T_UNSPEC) {
                    261: #endif ALLOW_T_UNSPEC
                    262:                            if (!getword(buf, sizeof(buf), fp))
                    263:                                break;
                    264: #ifdef DEBUG
                    265:                            if (debug >= 3)
                    266:                                fprintf(ddt,
                    267:                                    "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",
                    268:                                    domain, class, type, ttl, buf);
                    269: #endif
                    270: #ifdef ALLOW_T_UNSPEC
                    271:                         }
                    272: #endif ALLOW_T_UNSPEC
                    273:                        /*
                    274:                         * Convert the ascii data 'buf' to the proper format
                    275:                         * based on the type and pack into 'data'.
                    276:                         */
                    277:                        switch (type) {
                    278:                        case T_A:
                    279:                                n = ntohl((u_long)inet_addr((char *)buf));
                    280:                                cp = data;
                    281:                                PUTLONG(n, cp);
                    282:                                n = sizeof(u_long);
                    283:                                break;
                    284: 
                    285:                        case T_HINFO:
                    286:                                n = strlen(buf);
                    287:                                if (n > 255) {
                    288:                                    syslog(LOG_WARNING,
                    289:                                        "%s: line %d: CPU type too long",
                    290:                                        filename, lineno);
                    291:                                    n = 255;
                    292:                                }
                    293:                                data[0] = n;
                    294:                                bcopy(buf, (char *)data + 1, (int)n);
                    295:                                n++;
                    296:                                if (!getword(buf, sizeof(buf), fp))
                    297:                                        break;
                    298:                                i = strlen(buf);
                    299:                                if (i > 255) {
                    300:                                    syslog(LOG_WARNING,
                    301:                                        "%s: line %d: OS type too long",
                    302:                                        filename, lineno);
                    303:                                    i = 255;
                    304:                                }
                    305:                                data[n] = i;
                    306:                                bcopy(buf, data + n + 1, i);
                    307:                                n += i + 1;
                    308:                                endline(fp);
                    309:                                break;
                    310: 
                    311:                        case T_SOA:
                    312:                        case T_MINFO:
                    313:                                (void) strcpy(data, buf);
                    314:                                makename(data, origin);
                    315:                                cp = data + strlen(data) + 1;
                    316:                                if (!getword(cp, sizeof(data) - (cp - data),fp)) {
                    317:                                        n = cp - data;
                    318:                                        break;
                    319:                                }
                    320:                                makename(cp, origin);
                    321:                                cp += strlen(cp) + 1;
                    322:                                if (type == T_MINFO) {
                    323:                                        n = cp - data;
                    324:                                        break;
                    325:                                }
                    326:                                if (getnonblank(fp) != '(')
                    327:                                        goto err;
                    328:                                zp->z_serial = getnum(fp);
                    329:                                n = (u_long) zp->z_serial;
                    330:                                PUTLONG(n, cp);
                    331:                                zp->z_refresh = getnum(fp);
                    332:                                n = (u_long) zp->z_refresh;
                    333:                                PUTLONG(n, cp);
                    334:                                zp->z_time = sb.st_mtime + zp->z_refresh;
                    335:                                zp->z_retry = getnum(fp);
                    336:                                n = (u_long) zp->z_retry;
                    337:                                PUTLONG(n, cp);
                    338:                                zp->z_expire = getnum(fp);
                    339:                                n = (u_long) zp->z_expire;
                    340:                                PUTLONG (n, cp);
                    341:                                zp->z_minimum = getnum(fp);
                    342:                                n = (u_long) zp->z_minimum;
                    343:                                PUTLONG (n, cp);
                    344:                                n = cp - data;
                    345:                                if (getnonblank(fp) != ')')
                    346:                                        goto err;
                    347:                                endline(fp);
                    348:                                break;
                    349: 
                    350:                        case T_UID:
                    351:                        case T_GID:
                    352:                                n = 0;
                    353:                                cp = buf;
                    354:                                while (isdigit(*cp))
                    355:                                        n = n * 10 + (*cp++ - '0');
                    356:                                if (cp == buf)
                    357:                                        goto err;
                    358:                                cp = data;
                    359:                                PUTLONG(n, cp);
                    360:                                n = sizeof(long);
                    361:                                break;
                    362: 
                    363:                        case T_WKS:
                    364:                                /* Address */
                    365:                                n = ntohl((u_long)inet_addr((char *)buf));
                    366:                                cp = data;
                    367:                                PUTLONG(n, cp);
                    368:                                *cp = getprotocol(fp, filename);
                    369:                                /* Protocol */
                    370:                                n = sizeof(u_long) + sizeof(char);
                    371:                                /* Services */
                    372:                                n = getservices((int)n, data, fp, filename);
                    373:                                break;
                    374: 
                    375:                        case T_NS:
                    376:                        case T_CNAME:
                    377:                        case T_MB:
                    378:                        case T_MG:
                    379:                        case T_MR:
                    380:                        case T_PTR:
                    381:                                (void) strcpy(data, buf);
                    382:                                makename(data, origin);
                    383:                                n = strlen(data) + 1;
                    384:                                break;
                    385: 
                    386:                        case T_UINFO:
                    387:                                cp = (u_char *)index(buf, '&');
                    388:                                bzero(data, sizeof(data));
                    389:                                if ( cp != NULL) {
                    390:                                        (void) strncpy(data, buf, cp - buf);
                    391:                                        op = index(domain, '.');
                    392:                                        if ( op != NULL)
                    393:                                            (void) strncat(data,
                    394:                                                domain,op-domain);
                    395:                                        else
                    396:                                                (void) strcat(data, domain);
                    397:                                        (void) strcat(data, ++cp);
                    398:                                } else
                    399:                                        (void) strcpy(data, buf);
                    400:                                n = strlen(data) + 1;
                    401:                                break;
                    402:                        case T_MX:
                    403:                                n = 0;
                    404:                                cp = buf;
                    405:                                while (isdigit(*cp))
                    406:                                        n = n * 10 + (*cp++ - '0');
                    407:                                /* catch bad values */
                    408:                                if ((cp == buf) || (n > 64535))
                    409:                                        goto err;
                    410: 
                    411:                                cp = data;
                    412:                                PUTSHORT((u_short)n, cp);
                    413: 
                    414:                                if (!getword(buf, sizeof(buf), fp))
                    415:                                            break;
                    416:                                (void) strcpy(cp,buf);
                    417:                                makename(cp, origin);
                    418:                                /* get pointer to place in data */
                    419:                                cp += strlen(cp) +1;
                    420: 
                    421:                                /* now save length */
                    422:                                n = (cp - data);
                    423:                                break;
                    424: #ifdef ALLOW_T_UNSPEC
                    425:                         case T_UNSPEC:
                    426:                                 {
                    427:                                     int rcode;
                    428:                                     fgets(buf, sizeof(buf), fp);
                    429: #ifdef DEBUG
                    430:                                    if (debug)
                    431:                                        fprintf(ddt, "loading T_UNSPEC\n");
                    432: #endif DEBUG
                    433:                                     if (rcode = atob(buf, strlen(buf), data,                                                         MAXDATA, &n)) {
                    434:                                         if (rcode == CONV_OVERFLOW) {
                    435: #ifdef DEBUG
                    436:                                             if (debug)
                    437:                                                fprintf(ddt,
                    438:                                                   "Load T_UNSPEC: input buffer overflow\n");
                    439: #endif DEBUG
                    440:                                            errs++;
                    441:                                             syslog(LOG_ERR,
                    442:                                                 "Load T_UNSPEC: input buffer overflow");
                    443:                                          } else {
                    444: #ifdef DEBUG
                    445:                                             if (debug)
                    446:                                                 fprintf(ddt,
                    447:                                                   "Load T_UNSPEC: Data in bad atob format\n");
                    448: #endif DEBUG
                    449:                                            errs++;
                    450:                                             syslog(LOG_ERR,
                    451:                                                   "Load T_UNSPEC: Data in bad atob format");
                    452:                                          }
                    453:                                     }
                    454:                                 }
                    455:                                 break;
                    456: #endif ALLOW_T_UNSPEC
                    457: 
                    458:                        default:
                    459:                                goto err;
                    460:                        }
                    461:                        dp = savedata(class, type, (u_long)ttl, data, (int)n);
                    462:                        dp->d_zone = zp - zones;
                    463:                        dp->d_flags = dataflags;
                    464:                        if ((c = db_update(domain, dp, dp, dbflags,
                    465:                           (zp->z_type == Z_CACHE)? fcachetab : hashtab)) < 0) {
                    466: #ifdef DEBUG
                    467:                                if (debug && (c != DATAEXISTS))
                    468:                                        fprintf(ddt,"update failed\n");
                    469: #endif
                    470:                        }
                    471:                        continue;
                    472: 
                    473:                case ERROR:
                    474:                        break;
                    475:                }
                    476:        err:
                    477:                errs++;
                    478:                syslog(LOG_ERR, "%s: line %d: database format error (%s)",
                    479:                        filename, lineno, buf);
                    480: #ifdef DEBUG
                    481:                if (debug)
                    482:                        fprintf(ddt,"%s: line %d: database format error ('%s', %d)\n",
                    483:                                filename, lineno, buf, n);
                    484: #endif
                    485:                while ((c = getc(fp)) != EOF && c != '\n')
                    486:                        ;
                    487:                if (c == '\n')
                    488:                        lineno++;
                    489:        }
                    490:        (void) fclose(fp);
                    491:        if (didinclude)
                    492:                zp->z_ftime = 0;
                    493:        else
                    494:                zp->z_ftime = sb.st_mtime;
                    495:        zp->z_lastupdate = sb.st_mtime;
                    496:        lineno = slineno;
                    497:        return (errs);
                    498: }
                    499: 
                    500: int gettoken(fp)
                    501:        register FILE *fp;
                    502: {
                    503:        register int c;
                    504:        char op[32];
                    505: 
                    506:        for (;;) {
                    507:                c = getc(fp);
                    508:        top:
                    509:                switch (c) {
                    510:                case EOF:
                    511:                        return (EOF);
                    512: 
                    513:                case '$':
                    514:                        if (getword(op, sizeof(op), fp)) {
                    515:                                if (!strcasecmp("include", op))
                    516:                                        return (INCLUDE);
                    517:                                if (!strcasecmp("origin", op))
                    518:                                        return (ORIGIN);
                    519:                        }
                    520: #ifdef DEBUG
                    521:                        if (debug)
                    522:                                fprintf(ddt,"Line %d: Unknown $ option: $%s\n", 
                    523:                                    lineno, op);
                    524: #endif
                    525:                        syslog(LOG_ERR,"Line %d: Unknown $ option: $%s\n", 
                    526:                            lineno, op);
                    527:                        return (ERROR);
                    528: 
                    529:                case ';':
                    530:                        while ((c = getc(fp)) != EOF && c != '\n')
                    531:                                ;
                    532:                        goto top;
                    533: 
                    534:                case ' ':
                    535:                case '\t':
                    536:                        return (CURRENT);
                    537: 
                    538:                case '.':
                    539:                        return (DOT);
                    540: 
                    541:                case '@':
                    542:                        return (AT);
                    543: 
                    544:                case '\n':
                    545:                        lineno++;
                    546:                        continue;
                    547: 
                    548:                default:
                    549:                        (void) ungetc(c, fp);
                    550:                        return (DNAME);
                    551:                }
                    552:        }
                    553: }
                    554: 
                    555: /*
                    556:  * Get next word, skipping blanks & comments.
                    557:  */
                    558: getword(buf, size, fp)
                    559:        char *buf;
                    560:        int size;
                    561:        FILE *fp;
                    562: {
                    563:        register char *cp;
                    564:        register int c;
                    565: 
                    566:        for (cp = buf; (c = getc(fp)) != EOF; ) {
                    567:                if (c == ';') {
                    568:                        while ((c = getc(fp)) != EOF && c != '\n')
                    569:                                ;
                    570:                        c = '\n';
                    571:                }
                    572:                if (c == '\n') {
                    573:                        if (cp != buf)
                    574:                                ungetc(c, fp);
                    575:                        else
                    576:                                lineno++;
                    577:                        break;
                    578:                }
                    579:                if (isspace(c)) {
                    580:                        while (isspace(c = getc(fp)) && c != '\n')
                    581:                                ;
                    582:                        ungetc(c, fp);
                    583:                        if (cp != buf)          /* Trailing whitespace */
                    584:                                break;
                    585:                        continue;               /* Leading whitespace */
                    586:                }
                    587:                if (c == '"') {
                    588:                        while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
                    589:                                if (c == '\\') {
                    590:                                        if ((c = getc(fp)) == EOF)
                    591:                                                c = '\\';
                    592:                                        if (c == '\n')
                    593:                                                lineno++;
                    594:                                }
                    595:                                if (cp >= buf+size-1)
                    596:                                        break;
                    597:                                *cp++ = c;
                    598:                        }
                    599:                        if (c == '\n') {
                    600:                                lineno++;
                    601:                                break;
                    602:                        }
                    603:                        continue;
                    604:                }
                    605:                if (c == '\\') {
                    606:                        if ((c = getc(fp)) == EOF)
                    607:                                c = '\\';
                    608:                        if (c == '\n')
                    609:                                lineno++;
                    610:                }
                    611:                if (cp >= buf+size-1)
                    612:                        break;
                    613:                *cp++ = c;
                    614:        }
                    615:        *cp = '\0';
                    616:        return (cp != buf);
                    617: }
                    618: 
                    619: getnum(fp)
                    620:        FILE *fp;
                    621: {
                    622:        register int c, n;
                    623:        int seendigit = 0;
                    624:        int seendecimal = 0;
                    625: 
                    626:        for (n = 0; (c = getc(fp)) != EOF; ) {
                    627:                if (isspace(c)) {
                    628:                        if (c == '\n')
                    629:                                lineno++;
                    630:                        if (seendigit)
                    631:                                break;
                    632:                        continue;
                    633:                }
                    634:                if (c == ';') {
                    635:                        while ((c = getc(fp)) != EOF && c != '\n')
                    636:                                ;
                    637:                        if (c == '\n')
                    638:                                lineno++;
                    639:                        if (seendigit)
                    640:                                break;
                    641:                        continue;
                    642:                }
                    643:                if (!isdigit(c)) {
                    644:                        if (seendecimal || c != '.') {
                    645:                                syslog(LOG_ERR, "line %d: expected a number",
                    646:                                lineno);
                    647: #ifdef DEBUG
                    648:                                if (debug)
                    649:                                    fprintf(ddt,"line %d: expected a number",
                    650:                                        lineno);
                    651: #endif
                    652:                                exit(1);
                    653:                        } else {
                    654:                                if (!seendigit)
                    655:                                        n = 1;
                    656:                                n = n * 1000 ;
                    657:                                seendigit = 1;
                    658:                                seendecimal = 1;
                    659:                        }
                    660:                        continue;
                    661:                }
                    662:                n = n * 10 + (c - '0');
                    663:                seendigit = 1;
                    664:        }
                    665:        return (n);
                    666: }
                    667: 
                    668: getnonblank(fp)
                    669:        FILE *fp;
                    670: {
                    671:        register int c;
                    672: 
                    673:        while ( (c = getc(fp)) != EOF ) {
                    674:                if (isspace(c)) {
                    675:                        if (c == '\n')
                    676:                                lineno++;
                    677:                        continue;
                    678:                }
                    679:                if (c == ';') {
                    680:                        while ((c = getc(fp)) != EOF && c != '\n')
                    681:                                ;
                    682:                        if (c == '\n')
                    683:                                lineno++;
                    684:                        continue;
                    685:                }
                    686:                return(c);
                    687:        }
                    688:        syslog(LOG_ERR, "line %d: unexpected EOF", lineno);
                    689: #ifdef DEBUG
                    690:        if (debug)
                    691:                fprintf(ddt, "line %d: unexpected EOF", lineno);
                    692: #endif
                    693:        return (EOF);
                    694: }
                    695: 
                    696: /*
                    697:  * Take name and fix it according to following rules:
                    698:  * "." means root.
                    699:  * "@" means current origin.
                    700:  * "name." means no changes.
                    701:  * "name" means append origin.
                    702:  */
                    703: makename(name, origin)
                    704:        char *name, *origin;
                    705: {
                    706:        int n;
                    707: 
                    708:        if (origin[0] == '.')
                    709:                origin++;
                    710:        n = strlen(name);
                    711:        if (n == 1) {
                    712:                if (name[0] == '.') {
                    713:                        name[0] = '\0';
                    714:                        return;
                    715:                }
                    716:                if (name[0] == '@') {
                    717:                        (void) strcpy(name, origin);
                    718:                        return;
                    719:                }
                    720:        }
                    721:        if (n > 0) {
                    722:                if (name[n - 1] == '.')
                    723:                        name[n - 1] = '\0';
                    724:                else if (origin[0] != '\0') {
                    725:                        name[n] = '.';
                    726:                        (void) strcpy(name + n + 1, origin);
                    727:                }
                    728:        }
                    729: }
                    730: 
                    731: endline(fp)
                    732:        register FILE *fp;
                    733: {
                    734:      register int c;
                    735:      while (c = getc(fp))
                    736:        if (c == '\n') {
                    737:            (void) ungetc(c,fp);
                    738:            break;
                    739:        } else if (c == EOF)
                    740:            break;
                    741: }
                    742: 
                    743: #define MAXPORT 256
                    744: #define MAXLEN 24
                    745: 
                    746: getprotocol(fp, src)
                    747:        FILE *fp;
                    748:        char *src;
                    749: {
                    750:        int  k;
                    751:        char b[MAXLEN];
                    752: 
                    753:        (void) getword(b, sizeof(b), fp);
                    754:                
                    755:        k = findservice(b, &protolist);
                    756:        if(k == -1) {
                    757:                (void) sscanf(b,"%d",&k);
                    758:                if(k <= 0)
                    759:                        syslog(LOG_ERR, "%s: line %d: unknown protocol: %s.",
                    760:                                src, lineno, b);
                    761:        }
                    762:        return(k);
                    763: }
                    764: 
                    765: int
                    766: getservices(n, data, fp, src)
                    767:        int n;
                    768:        char *data, *src;
                    769:        FILE *fp;
                    770: {
                    771:        int j, ch;
                    772:        int k;
                    773:        int maxl;
                    774:        int bracket;
                    775:        char b[MAXLEN];
                    776:        char bm[MAXPORT/8];
                    777: 
                    778:        for (j = 0; j < MAXPORT/8; j++)
                    779:                bm[j] = 0;
                    780:        maxl = 0;
                    781:        bracket = 0;
                    782:        while (getword(b, sizeof(b), fp) || bracket) {
                    783:                if (feof(fp) || ferror(fp))
                    784:                        break;
                    785:                if (strlen(b) == 0)
                    786:                        continue;
                    787:                if ( b[0] == '(') {
                    788:                        bracket++;
                    789:                        continue;
                    790:                }
                    791:                if ( b[0] == ')') {
                    792:                        bracket = 0;
                    793:                        while ((ch = getc(fp)) != EOF && ch != '\n')
                    794:                                ;
                    795:                        if (ch == '\n')
                    796:                                lineno++;
                    797:                        break;
                    798:                }
                    799:                k = findservice(b, &servicelist);
                    800:                if (k == -1) {
                    801:                        (void) sscanf(b,"%d",&k);
                    802:                        if (k <= 0) {
                    803:                                syslog(LOG_WARNING,
                    804:                         "%s: line %d: Unknown service '%s'", src, lineno, b);
                    805:                                continue;
                    806:                         }
                    807:                }
                    808:                if ((k < MAXPORT) && (k)) {
                    809:                        bm[k/8] |= (0x80>>(k%8));
                    810:                        if (k > maxl)
                    811:                                maxl=k;
                    812:                }
                    813:                else {
                    814:                        syslog(LOG_WARNING,
                    815:                            "%s: line %d: port no. (%d) too big\n",
                    816:                                src, lineno, k);
                    817: #ifdef DEBUG
                    818:                        if (debug)
                    819:                                fprintf(ddt,
                    820:                                    "%s: line %d: port no. (%d) too big\n",
                    821:                                        src, lineno, k);
                    822: #endif
                    823:                }
                    824:        }
                    825:        if (bracket)
                    826:                syslog(LOG_WARNING, "%s: line %d: missing close paren\n",
                    827:                    src, lineno);
                    828:        maxl = maxl/8+1;
                    829:        bcopy(bm, data+n, maxl);
                    830:        return(maxl+n);
                    831: }
                    832: 
                    833: get_sort_list(fp)
                    834:        FILE *fp;
                    835: {
                    836:        struct netinfo *tp;
                    837:        struct netinfo *ntp = NULL;
                    838:        struct netinfo *ntip = NULL;
                    839:        char buf[BUFSIZ];
                    840: 
                    841:        extern struct   netinfo *fnettab;
                    842: 
                    843: #ifdef DEBUG
                    844:        if (debug)
                    845:                fprintf(ddt,"sortlist ");
                    846: #endif
                    847:        if (fnettab) {
                    848: #ifdef DEBUG
                    849:                /* We can only handle the sortlist at startup. see ns_main */
                    850:                if (debug)
                    851:                        fprintf(ddt," (reloading, therefore ignored)\n");
                    852: #endif
                    853:                (void) endline(fp);
                    854:                return;
                    855:        }
                    856: 
                    857:        while (getword(buf, sizeof(buf), fp)) {
                    858:                if (strlen(buf) == 0)
                    859:                        break;
                    860: #ifdef DEBUG
                    861:                if (debug)
                    862:                        fprintf(ddt," %s",buf);
                    863: #endif
                    864:                if (ntp == NULL)
                    865:                        ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
                    866:                ntp->my_addr.s_addr = inet_addr(buf);
                    867:                if ( ntp->my_addr.s_addr == (unsigned)-1) {
                    868:                        /* resolve name to address - XXX */
                    869:                        continue;       
                    870:                }
                    871:                ntp->next = NULL;
                    872:                ntp->mask = net_mask(ntp->my_addr);
                    873:                ntp->net = ntp->my_addr.s_addr & ntp->mask;
                    874: 
                    875:                /* Check for duplicates, then add to linked list */
                    876:                for (tp = fnettab; tp != NULL; tp = tp->next) {
                    877:                        if ((ntp->mask == tp->mask) && 
                    878:                            (ntp->net == tp->net))
                    879:                                continue;
                    880:                }
                    881:                if (fnettab == NULL)
                    882:                        fnettab = ntp;
                    883:                else
                    884:                        ntip->next = ntp;
                    885:                ntip = ntp;
                    886:                ntp = NULL;
                    887:        }
                    888:        if (ntp)
                    889:                free((char *)ntp);
                    890:        
                    891: #ifdef DEBUG
                    892:        if (debug) 
                    893:                fprintf(ddt,"\n");
                    894:        if (debug > 2)
                    895:                for (ntp = fnettab; ntp != NULL; ntp = ntp->next) {
                    896:                        fprintf(ddt,"ntp x%x net x%x mask x%x", ntp, 
                    897:                        ntp->net, ntp->mask);
                    898:                        fprintf(ddt," my_addr x%x", ntp->my_addr);
                    899:                        fprintf(ddt," %s",inet_ntoa(ntp->my_addr));
                    900:                        fprintf(ddt," next x%x\n", ntp->next);
                    901:                }
                    902: #endif
                    903: }
                    904: 
                    905: buildservicelist()
                    906: {
                    907:        struct servent *sp;
                    908:        struct valuelist *slp;
                    909: 
                    910:        setservent(1);
                    911:        while (sp = getservent()) {
                    912:                slp = (struct valuelist *)malloc(sizeof(struct valuelist));
                    913:                slp->name = savestr(sp->s_name);
                    914:                slp->proto = savestr(sp->s_proto);
                    915:                slp->port = ntohs((u_short)sp->s_port);
                    916:                slp->next = servicelist;
                    917:                slp->prev = NULL;
                    918:                if (servicelist) {
                    919:                        servicelist->prev = slp;
                    920:                }
                    921:                servicelist = slp;
                    922:        }
                    923:        endservent();
                    924: }
                    925: 
                    926: buildprotolist()
                    927: {
                    928:        struct protoent *pp;
                    929:        struct valuelist *slp;
                    930: 
                    931:        setprotoent(1);
                    932:        while (pp = getprotoent()) {
                    933:                slp = (struct valuelist *)malloc(sizeof(struct valuelist));
                    934:                slp->name = savestr(pp->p_name);
                    935:                slp->port = pp->p_proto;
                    936:                slp->next = protolist;
                    937:                slp->prev = NULL;
                    938:                if (protolist) {
                    939:                        protolist->prev = slp;
                    940:                }
                    941:                protolist = slp;
                    942:        }
                    943:        endprotoent();
                    944: }
                    945: 
                    946: findservice(s, list)
                    947: register char *s;
                    948: register struct valuelist **list;
                    949: {
                    950:        register struct valuelist *lp = *list;
                    951: 
                    952:        for (; lp != NULL; lp = lp->next)
                    953:                if (strcasecmp(lp->name, s) == 0) {
                    954:                        if (lp != *list) {
                    955:                                lp->prev->next = lp->next;
                    956:                                if (lp->next)
                    957:                                        lp->next->prev = lp->prev;
                    958:                                (*list)->prev = lp;
                    959:                                lp->next = *list;
                    960:                                *list = lp;
                    961:                        }
                    962:                        return(lp->port);
                    963:                }
                    964:        return(-1);
                    965: }
                    966: 
                    967: struct servent *
                    968: cgetservbyport(port, proto)
                    969: u_short port;
                    970: char *proto;
                    971: {
                    972:        register struct valuelist **list = &servicelist;
                    973:        register struct valuelist *lp = *list;
                    974:        static struct servent serv;
                    975: 
                    976:        port = htons(port);
                    977:        for (; lp != NULL; lp = lp->next) {
                    978:                if (port != lp->port)
                    979:                        continue;
                    980:                if (strcasecmp(lp->proto, proto) == 0) {
                    981:                        if (lp != *list) {
                    982:                                lp->prev->next = lp->next;
                    983:                                if (lp->next)
                    984:                                        lp->next->prev = lp->prev;
                    985:                                (*list)->prev = lp;
                    986:                                lp->next = *list;
                    987:                                *list = lp;
                    988:                        }
                    989:                        serv.s_name = lp->name;
                    990:                        serv.s_port = htons((u_short)lp->port);
                    991:                        serv.s_proto = lp->proto;
                    992:                        return(&serv);
                    993:                }
                    994:        }
                    995:        return(0);
                    996: }
                    997: 
                    998: struct protoent *
                    999: cgetprotobynumber(proto)
                   1000: register int proto;
                   1001: {
                   1002: 
                   1003:        register struct valuelist **list = &protolist;
                   1004:        register struct valuelist *lp = *list;
                   1005:        static struct protoent prot;
                   1006: 
                   1007:        for (; lp != NULL; lp = lp->next)
                   1008:                if (lp->port == proto) {
                   1009:                        if (lp != *list) {
                   1010:                                lp->prev->next = lp->next;
                   1011:                                if (lp->next)
                   1012:                                        lp->next->prev = lp->prev;
                   1013:                                (*list)->prev = lp;
                   1014:                                lp->next = *list;
                   1015:                                *list = lp;
                   1016:                        }
                   1017:                        prot.p_name = lp->name;
                   1018:                        prot.p_proto = lp->port;
                   1019:                        return(&prot);
                   1020:                }
                   1021:        return(0);
                   1022: }

unix.superglobalmegacorp.com

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