Annotation of 43BSDTahoe/etc/named/db_load.c, revision 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.