Annotation of 43BSDReno/usr.sbin/named/xfer/named-xfer.c, revision 1.1

1.1     ! root        1: /*-
        !             2:  * Copyright (c) 1988, 1990 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  *
        !            19:  * The original version of xfer by Kevin Dunlap.
        !            20:  * Completed and integrated with named by David Waitzman
        !            21:  *     ([email protected]) 3/14/88.
        !            22:  * Modified by M. Karels and O. Kure 10-88.
        !            23:  */
        !            24: 
        !            25: #ifndef lint
        !            26: char copyright[] =
        !            27: "@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\
        !            28:  All rights reserved.\n";
        !            29: #endif /* not lint */
        !            30: 
        !            31: #ifndef lint
        !            32: static char sccsid[] = "@(#)named-xfer.c       4.15 (Berkeley) 7/24/90";
        !            33: #endif /* not lint */
        !            34: 
        !            35: #include <sys/types.h>
        !            36: #include <sys/file.h>
        !            37: #include <sys/stat.h>
        !            38: #include <sys/socket.h>
        !            39: #include <sys/uio.h>
        !            40: #include <sys/signal.h>
        !            41: 
        !            42: #include <netinet/in.h>
        !            43: #include <net/if.h>
        !            44: #include <netdb.h>
        !            45: #include <arpa/inet.h>
        !            46: #include <arpa/nameser.h>
        !            47: 
        !            48: #include <errno.h>
        !            49: #include <resolv.h>
        !            50: #include <string.h>
        !            51: #include <stdio.h>
        !            52: #include <syslog.h>
        !            53: 
        !            54: #define XFER                   /* modifies the ns.h include file */
        !            55: #include "ns.h"
        !            56: #include "pathnames.h"
        !            57: 
        !            58: char   *savestr();
        !            59: 
        !            60: /* max length of data in RR data field */
        !            61: #define MAXDATA                2048    /* from db.h */
        !            62:  
        !            63: int    debug = 0; 
        !            64: int    quiet = 0;
        !            65: int    read_interrupted = 0;
        !            66: struct zoneinfo zones;         /* zone information */
        !            67: struct timeval tt;
        !            68: 
        !            69: static char *ddtfile = _PATH_TMPXFER;
        !            70: static char *tmpname;
        !            71: FILE   *fp = 0, *ddt, *dbfp;
        !            72: char   *domain;                        /* domain being xfered */
        !            73: int    domain_len;                     /* strlen(domain) */
        !            74: 
        !            75: main(argc, argv)
        !            76:        int argc;
        !            77:        char *argv[];
        !            78: {
        !            79:        register struct zoneinfo *zp;
        !            80:        register struct hostent *hp;
        !            81:        char *dbfile = NULL, *tracefile = NULL, *tm = NULL;
        !            82:        int dbfd, ddtd, result, c;
        !            83:        u_long serial_no = 0;
        !            84:        extern char *optarg;
        !            85:        extern int optind, getopt();
        !            86:        u_short port = htons(NAMESERVER_PORT);
        !            87: 
        !            88:        (void) umask(022);
        !            89: #ifdef LOG_DAEMON
        !            90:        openlog("named-xfer", LOG_PID|LOG_CONS, LOG_DAEMON);
        !            91: #else
        !            92:        openlog("named-xfer", LOG_PID);
        !            93: #endif
        !            94:        while ((c = getopt(argc, argv, "d:l:s:t:z:f:p:P:q")) != EOF)
        !            95:            switch (c) {
        !            96:                case 'd':
        !            97:                        debug = atoi(optarg);
        !            98:                        break;
        !            99:                case 'l':
        !           100:                        ddtfile = (char *)malloc(strlen(optarg) +
        !           101:                            sizeof(".XXXXXX") + 1);
        !           102:                        (void) strcpy(ddtfile, optarg);
        !           103:                        (void) strcat(ddtfile, ".XXXXXX");
        !           104:                        break;
        !           105:                case 's':
        !           106:                        serial_no = (u_long) atol(optarg);
        !           107:                        break;
        !           108:                case 't':
        !           109:                        tracefile = optarg;
        !           110:                        break;
        !           111:                case 'z':               /* zone == domain */
        !           112:                        domain = optarg;
        !           113:                        domain_len = strlen(domain);
        !           114:                        break;
        !           115:                case 'f':
        !           116:                        dbfile = optarg;
        !           117:                        tmpname = (char *)malloc((unsigned)strlen(optarg) +
        !           118:                            sizeof(".XXXXXX") + 1);
        !           119:                        (void) strcpy(tmpname, optarg);
        !           120:                        break;
        !           121:                case 'p':
        !           122:                        port = htons((u_short)atoi(optarg));
        !           123:                        break;
        !           124:                case 'P':
        !           125:                        port = (u_short)atoi(optarg);
        !           126:                        break;
        !           127:                case 'q':
        !           128:                        quiet++;
        !           129:                        break;
        !           130:                case '?':
        !           131:                default:
        !           132:                        usage();
        !           133:                        /* NOTREACHED */
        !           134:            }
        !           135: 
        !           136:        if (!domain || !dbfile || optind >= argc) {
        !           137:                usage();
        !           138:                /* NOTREACHED */
        !           139:        }           
        !           140:        if (tracefile && (fp = fopen(tracefile, "w")) == NULL)
        !           141:                perror(tracefile);
        !           142:        (void) strcat(tmpname, ".XXXXXX");
        !           143:        /* tmpname is now something like "/etc/named/named.bu.db.XXXXXX" */
        !           144:        if ((dbfd = mkstemp(tmpname)) == -1) {
        !           145:                perror(tmpname);
        !           146:                if (!quiet)
        !           147:                        syslog(LOG_ERR, "can't make tmpfile (%s): %m\n",
        !           148:                            tmpname);
        !           149:                exit(XFER_FAIL);
        !           150:        }
        !           151:        if (fchmod(dbfd, 0644) == -1) {
        !           152:                perror(tmpname);
        !           153:                if (!quiet)
        !           154:                        syslog(LOG_ERR, "can't fchmod tmpfile (%s): %m\n",
        !           155:                            tmpname);
        !           156:                exit(XFER_FAIL);
        !           157:        }
        !           158:        if ((dbfp = fdopen(dbfd, "r+")) == NULL) {
        !           159:                perror(tmpname);
        !           160:                if (!quiet)
        !           161:                        syslog(LOG_ERR, "can't fdopen tmpfile (%s)", tmpname);
        !           162:                exit(XFER_FAIL);
        !           163:        }
        !           164: #ifdef DEBUG
        !           165:        if (debug) {
        !           166:                /* ddtfile is now something like "/usr/tmp/xfer.ddt.XXXXXX" */
        !           167:                if ((ddtd = mkstemp(ddtfile)) == -1) {
        !           168:                        perror(ddtfile);
        !           169:                        debug = 0;
        !           170:                } else if (fchmod(ddtd, 0644) == -1) {
        !           171:                        perror(ddtfile);
        !           172:                        debug = 0;
        !           173:                } else if ((ddt = fdopen(ddtd, "w")) == NULL) {
        !           174:                        perror(ddtfile);
        !           175:                        debug = 0;
        !           176:                } else {
        !           177: #if defined(SYSV)
        !           178:                        setvbuf(ddt, NULL, _IOLBF, BUFSIZ);
        !           179: #else
        !           180:                        setlinebuf(ddt);
        !           181: #endif
        !           182:                }
        !           183:        }
        !           184: #endif
        !           185:        /*
        !           186:         * Ignore many types of signals that named (assumed to be our parent)
        !           187:         * considers important- if not, the user controlling named with
        !           188:         * signals usually kills us.
        !           189:         */
        !           190:        (void) signal(SIGHUP, SIG_IGN);
        !           191:        (void) signal(SIGSYS, SIG_IGN);
        !           192:        if (debug == 0) {
        !           193:                (void) signal(SIGINT, SIG_IGN);
        !           194:                (void) signal(SIGQUIT, SIG_IGN);
        !           195:        }
        !           196:        (void) signal(SIGIOT, SIG_IGN);
        !           197: 
        !           198: #if defined(SIGUSR1) && defined(SIGUSR2)
        !           199:        (void) signal(SIGUSR1, SIG_IGN);
        !           200:        (void) signal(SIGUSR2, SIG_IGN);
        !           201: #else  SIGUSR1&&SIGUSR2
        !           202:        (void) signal(SIGEMT, SIG_IGN);
        !           203:        (void) signal(SIGFPE, SIG_IGN);
        !           204: #endif SIGUSR1&&SIGUSR2
        !           205: 
        !           206: #ifdef DEBUG
        !           207:        if (debug) (void)fprintf(ddt, "domain `%s' file `%s' ser no %lu \n", 
        !           208:              domain, dbfile,serial_no);
        !           209: #endif
        !           210:        buildservicelist();
        !           211:        buildprotolist();
        !           212: 
        !           213:        /* init zone data */
        !           214:  
        !           215:        zp = &zones;
        !           216:        zp->z_type = Z_SECONDARY;
        !           217:        zp->z_origin = domain;
        !           218:        zp->z_source = dbfile;
        !           219:        zp->z_addrcnt = 0;
        !           220: #ifdef DEBUG
        !           221:        if (debug) {
        !           222:                (void)fprintf(ddt,"zone found (%d): ", zp->z_type);
        !           223:                if (zp->z_origin[0] == '\0')
        !           224:                        (void)fprintf(ddt,"'.'");
        !           225:                else
        !           226:                        (void)fprintf(ddt,"'%s'", zp->z_origin);
        !           227:                (void)fprintf(ddt,", source = %s\n", zp->z_source);
        !           228:        }
        !           229: #endif
        !           230:        for (; optind != argc; optind++,zp->z_addrcnt++) {
        !           231:                tm = argv[optind];
        !           232:                zp->z_addr[zp->z_addrcnt].s_addr = inet_addr(tm);
        !           233:  
        !           234:                if (zp->z_addr[zp->z_addrcnt].s_addr == (unsigned)-1) {
        !           235:                        hp = gethostbyname(tm);
        !           236:                        if (hp == NULL) {
        !           237:                                syslog(LOG_ERR, "uninterpretable server %s\n",
        !           238:                                        tm);
        !           239:                                continue;
        !           240:                        }
        !           241:                        bcopy(hp->h_addr,
        !           242:                            (char *)&zp->z_addr[zp->z_addrcnt].s_addr,
        !           243:                            sizeof(zp->z_addr[zp->z_addrcnt].s_addr));
        !           244: #ifdef DEBUG
        !           245:                        if (debug)
        !           246:                                (void)fprintf(ddt,", %s",tm);
        !           247: #endif
        !           248:                }
        !           249:                if (zp->z_addrcnt >= NSMAX) {
        !           250:                        zp->z_addrcnt = NSMAX;
        !           251: #ifdef DEBUG
        !           252:                        if (debug)
        !           253:                            (void)fprintf(ddt, "\nns.h NSMAX reached\n");
        !           254: #endif
        !           255:                        break;
        !           256:                }
        !           257:        }
        !           258: #ifdef DEBUG
        !           259:        if (debug) (void)fprintf(ddt," (addrcnt) = %d\n", zp->z_addrcnt);
        !           260: #endif
        !           261: 
        !           262:        _res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE);
        !           263:        result = getzone(zp, serial_no, port);
        !           264:        (void) fclose(dbfp);
        !           265:        switch (result) {
        !           266: 
        !           267:        case XFER_SUCCESS:                      /* ok exit */
        !           268:                if (rename(tmpname, dbfile) == -1) {
        !           269:                        perror("rename");
        !           270:                        if (!quiet)
        !           271:                            syslog(LOG_ERR, "rename %s to %s: %m",
        !           272:                                tmpname, dbfile);
        !           273:                        exit(XFER_FAIL);
        !           274:                }
        !           275:                exit(XFER_SUCCESS);
        !           276: 
        !           277:        case XFER_UPTODATE:             /* the zone was already uptodate */
        !           278:                (void) unlink(tmpname);
        !           279:                exit(XFER_UPTODATE);
        !           280: 
        !           281:        case XFER_TIMEOUT:
        !           282: #ifdef DEBUG
        !           283:                if (!debug)
        !           284: #endif
        !           285:                    (void) unlink(tmpname);
        !           286:                exit(XFER_TIMEOUT);             /* servers not reachable exit */
        !           287: 
        !           288:        case XFER_FAIL:
        !           289:        default:
        !           290: #ifdef DEBUG
        !           291:                if (!debug)
        !           292: #endif
        !           293:                    (void) unlink(tmpname);
        !           294:                exit(XFER_FAIL);                /* yuck exit */
        !           295:        }
        !           296: }
        !           297:  
        !           298: usage()
        !           299: {
        !           300:        (void)fprintf(stderr,
        !           301: "Usage: xfer\n\
        !           302: \t-z zone_to_transfer\n\
        !           303: \t-f db_file\n\
        !           304: \t-s serial_no\n\
        !           305: \t[-d debug_level]\n\
        !           306: \t[-l debug_log_file (default %s)]\n\
        !           307: \t[-t trace_file]\n\
        !           308: \t[-p port]\n\
        !           309: \tservers...\n", ddtfile);
        !           310:        exit(XFER_FAIL);
        !           311: }
        !           312: 
        !           313: int    minimum_ttl = 0, got_soa = 0;
        !           314: char   prev_origin[MAXDNAME];
        !           315: char   prev_dname[MAXDNAME];
        !           316: 
        !           317: getzone(zp, serial_no, port)
        !           318:        struct zoneinfo *zp;
        !           319:        u_long serial_no;
        !           320:        u_short port;
        !           321: {
        !           322:        HEADER *hp;
        !           323:        u_short len;
        !           324:        u_long serial;
        !           325:        int s, n, l, cnt, soacnt, error = 0;
        !           326:        u_char *cp, *nmp, *eom, *tmp ;
        !           327:        u_char *buf = NULL;
        !           328:        int bufsize;
        !           329:        u_char name[MAXDNAME], name2[MAXDNAME];
        !           330:        struct sockaddr_in sin;
        !           331:        struct zoneinfo zp_start, zp_finish;
        !           332:        struct itimerval ival, zeroival;
        !           333:        extern VOID read_alarm();
        !           334:        struct sigvec sv, osv;
        !           335:        int ancount, aucount;
        !           336: #ifdef DEBUG
        !           337:        if (debug)
        !           338:                (void)fprintf(ddt,"getzone() %s\n", zp->z_origin);
        !           339: #endif
        !           340:        bzero((char *)&zeroival, sizeof(zeroival));
        !           341:        ival = zeroival;
        !           342:        ival.it_value.tv_sec = 120;
        !           343:        sv.sv_handler = read_alarm;
        !           344:        sv.sv_onstack = 0;
        !           345:        sv.sv_mask = ~0;
        !           346:        (void) sigvec(SIGALRM, &sv, &osv);
        !           347: 
        !           348:        strcpy(prev_origin, zp->z_origin);
        !           349: 
        !           350:        for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {
        !           351:                error = 0;
        !           352:                if (buf == NULL) {
        !           353:                        if ((buf = (u_char *)malloc(2 * PACKETSZ)) == NULL) {
        !           354:                                syslog(LOG_ERR, "malloc(%u) failed",
        !           355:                                    2 * PACKETSZ);
        !           356:                                error++;
        !           357:                                break;
        !           358:                        }
        !           359:                        bufsize = 2 * PACKETSZ;
        !           360:                }
        !           361:                bzero((char *)&sin, sizeof(sin));
        !           362:                sin.sin_family = AF_INET;
        !           363:                sin.sin_port = port;
        !           364:                sin.sin_addr = zp->z_addr[cnt];
        !           365:                if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        !           366:                        syslog(LOG_ERR, "socket: %m");
        !           367:                        error++;
        !           368:                        break;
        !           369:                }       
        !           370: #ifdef DEBUG
        !           371:                if (debug >= 2) {
        !           372:                        (void)fprintf(ddt,"connecting to server #%d %s, %d\n",
        !           373:                           cnt+1, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
        !           374:                }
        !           375: #endif
        !           376:                if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
        !           377:                        (void) close(s);
        !           378:                        error++;
        !           379: #ifdef DEBUG
        !           380:                        if (debug >= 2)
        !           381:                                (void)fprintf(ddt, "connect failed, %s\n",
        !           382:                                        strerror(errno));
        !           383: #endif
        !           384:                        continue;
        !           385:                }       
        !           386:                if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,
        !           387:                    T_SOA, (char *)NULL, 0, NULL, buf, bufsize)) < 0) {
        !           388:                        if (!quiet)
        !           389:                            syslog(LOG_ERR, "zone %s: res_mkquery T_SOA failed",
        !           390:                                zp->z_origin);
        !           391:                        (void) close(s);
        !           392:                        (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
        !           393:                        return XFER_FAIL;
        !           394:                }
        !           395:                /*
        !           396:                 * Send length & message for zone transfer
        !           397:                 */
        !           398:                if (writemsg(s, buf, n) < 0) {
        !           399:                        (void) close(s);
        !           400:                        error++;
        !           401: #ifdef DEBUG
        !           402:                        if (debug >= 2)
        !           403:                                (void)fprintf(ddt,"writemsg failed\n");
        !           404: #endif
        !           405:                        continue;       
        !           406:                }
        !           407:                /*
        !           408:                 * Get out your butterfly net and catch the SOA
        !           409:                 */
        !           410:                cp = buf;
        !           411:                l = sizeof(u_short);
        !           412:                read_interrupted = 0;
        !           413:                while (l > 0) {
        !           414: #ifdef DEBUG
        !           415:                        if (debug > 10) (void)fprintf(ddt,"Before setitimer\n");
        !           416: #endif
        !           417:                        (void) setitimer(ITIMER_REAL, &ival,
        !           418:                            (struct itimerval *)NULL);
        !           419: #ifdef DEBUG
        !           420:                        if (debug > 10) (void)fprintf(ddt,"Before recv(l = %d)\n",n);
        !           421: #endif
        !           422:                        errno = 0;
        !           423:                        if ((n = recv(s, (char *)cp, l, 0)) > 0) {
        !           424:                                cp += n;
        !           425:                                l -= n;
        !           426:                        } else {
        !           427: #ifdef DEBUG
        !           428:                                if (debug > 10)
        !           429:                                (void)fprintf(ddt,
        !           430: "bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted);
        !           431: #endif
        !           432:                                if (n == -1 && errno == EINTR 
        !           433:                                    && !read_interrupted)
        !           434:                                        continue;
        !           435:                                error++;
        !           436:                                break;
        !           437:                        }
        !           438:                }
        !           439: 
        !           440:                (void) setitimer(ITIMER_REAL, &zeroival,
        !           441:                    (struct itimerval *)NULL);
        !           442:                if (error) {
        !           443:                        (void) close(s);
        !           444:                        continue;
        !           445:                }
        !           446:                if ((len = htons(*(u_short *)buf)) == 0) {
        !           447:                        (void) close(s);
        !           448:                        continue;
        !           449:                }
        !           450:                if (len > bufsize) {
        !           451:                        if ((buf = (u_char *)realloc(buf, len)) == NULL) {
        !           452:                                syslog(LOG_ERR,
        !           453:                          "malloc(%u) failed for SOA from server %s, zone %s\n",
        !           454:                                    len, inet_ntoa(sin.sin_addr), zp->z_origin);
        !           455:                                (void) close(s);
        !           456:                                continue;
        !           457:                        }
        !           458:                        bufsize = len;
        !           459:                }
        !           460:                l = len;
        !           461:                cp = buf;
        !           462:                while (l > 0) {
        !           463:                        (void) setitimer(ITIMER_REAL, &ival,
        !           464:                            (struct itimerval *)NULL);
        !           465:                        errno = 0;
        !           466:                        if ((n = recv(s, (char *)cp, l, 0)) > 0) {
        !           467:                                cp += n;
        !           468:                                l -= n;
        !           469:                        } else {
        !           470:                                if (errno == EINTR && !read_interrupted)
        !           471:                                        continue;
        !           472:                                error++;
        !           473: #ifdef DEBUG
        !           474:                                if (debug > 10)
        !           475:                                    (void)fprintf(ddt,
        !           476:                                            "recv failed: n= %d, errno = %d\n",
        !           477:                                            n, errno);
        !           478: #endif
        !           479:                                break;
        !           480:                        }
        !           481:                }
        !           482:                (void) setitimer(ITIMER_REAL, &zeroival,
        !           483:                    (struct itimerval *)NULL);
        !           484:                if (error) {
        !           485:                        (void) close(s);
        !           486:                        continue;
        !           487:                }
        !           488: #ifdef DEBUG
        !           489:                if (debug >= 3) {
        !           490:                        (void)fprintf(ddt,"len = %d\n", len);
        !           491:                        fp_query(buf, ddt);
        !           492:                }
        !           493: #endif DEBUG
        !           494:                hp = (HEADER *) buf;
        !           495:                ancount = ntohs(hp->ancount);
        !           496:                aucount = ntohs(hp->nscount);
        !           497: 
        !           498:                /*
        !           499:                 * close socket if:
        !           500:                 *  1) rcode != NOERROR
        !           501:                 *  2) not an authority response
        !           502:                 *  3) both the number of answers and authority count < 1)
        !           503:                 */
        !           504:                if (hp->rcode != NOERROR || !(hp->aa) || 
        !           505:                    (ancount < 1 && aucount < 1)) {
        !           506:                        if (!quiet)
        !           507:                                syslog(LOG_ERR,
        !           508:            "%s from %s, zone %s: rcode %d, aa %d, ancount %d, aucount %d\n",
        !           509:                                    "bad response to SOA query",
        !           510:                                    inet_ntoa(sin.sin_addr), zp->z_origin,
        !           511:                                    hp->rcode, hp->aa, ancount, aucount);
        !           512: #ifdef DEBUG
        !           513:                        if (debug)
        !           514:                                fprintf(ddt,
        !           515:            "%s from %s, zone %s: rcode %d, aa %d, ancount %d, aucount %d\n",
        !           516:                                    "bad response to SOA query",
        !           517:                                    inet_ntoa(sin.sin_addr), zp->z_origin,
        !           518:                                    hp->rcode, hp->aa, ancount, aucount);
        !           519: #endif DEBUG
        !           520:                        (void) close(s);
        !           521:                        error++;
        !           522:                        continue;
        !           523:                }
        !           524:                zp_start = *zp;
        !           525:                if (len < sizeof(HEADER) + QFIXEDSZ) {
        !           526:        badsoa:
        !           527:                        if (!quiet)
        !           528:                                syslog(LOG_ERR,
        !           529:                                  "malformed SOA from %s, zone %s: too short\n",
        !           530:                                    inet_ntoa(sin.sin_addr), zp->z_origin);
        !           531: #ifdef DEBUG
        !           532:                        if (debug)
        !           533:                                fprintf(ddt,
        !           534:                                    "malformed SOA from %s: too short\n",
        !           535:                                    inet_ntoa(sin.sin_addr));
        !           536: #endif DEBUG
        !           537:                        (void) close(s);
        !           538:                        error++;
        !           539:                        continue;
        !           540:                }
        !           541:                tmp = buf + sizeof(HEADER);
        !           542:                eom = buf + len;
        !           543:                if ((n = dn_skipname(tmp, eom)) == -1)
        !           544:                        goto badsoa;
        !           545:                tmp += n + QFIXEDSZ;
        !           546:                if ((n = dn_skipname(tmp, eom)) == -1)
        !           547:                        goto badsoa;
        !           548:                tmp += n;
        !           549:                if (soa_zinfo(&zp_start, tmp, eom) == -1)
        !           550:                        goto badsoa;
        !           551:                if (zp_start.z_serial > serial_no || serial_no == 0) {
        !           552: #ifdef DEBUG
        !           553:                    if (debug)
        !           554:                        (void)fprintf(ddt, "need update, serial %d\n",
        !           555:                            zp_start.z_serial);
        !           556: #endif DEBUG
        !           557:                    hp = (HEADER *) buf;
        !           558:                    soacnt = 0;
        !           559:                    for (;;) {
        !           560:                        if (soacnt == 0) {
        !           561:                            if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,
        !           562:                              T_AXFR, (char *)NULL, 0, NULL,
        !           563:                              buf, bufsize)) < 0) {
        !           564:                                if (!quiet)
        !           565:                                    syslog(LOG_ERR,
        !           566:                                        "zone %s: res_mkquery T_AXFR failed",
        !           567:                                        zp->z_origin);
        !           568:                                (void) close(s);
        !           569:                                (void) sigvec(SIGALRM, &osv,
        !           570:                                    (struct sigvec *)0);
        !           571:                                return XFER_FAIL;
        !           572:                            }
        !           573:                            /*
        !           574:                             * Send length & message for zone transfer
        !           575:                             */
        !           576:                            if (writemsg(s, buf, n) < 0) {
        !           577:                                    (void) close(s);
        !           578:                                    error++;
        !           579: #ifdef DEBUG
        !           580:                                    if (debug >= 2)
        !           581:                                            (void)fprintf(ddt,"writemsg failed\n");
        !           582: #endif
        !           583:                                    break;      
        !           584:                            }
        !           585:                        }
        !           586:                        /*
        !           587:                         * Receive length & response
        !           588:                         */
        !           589:                        cp = buf;
        !           590:                        l = sizeof(u_short);
        !           591:                        /* allow extra time for the fork on first read */
        !           592:                        if (soacnt == 0)
        !           593:                                ival.it_value.tv_sec = 300;
        !           594:                        while (l > 0) {
        !           595:                                (void) setitimer(ITIMER_REAL, &ival,
        !           596:                                    (struct itimerval *)NULL);
        !           597:                                errno = 0;
        !           598:                                if ((n = recv(s, (char *)cp, l, 0)) > 0) {
        !           599:                                        cp += n;
        !           600:                                        l -= n;
        !           601:                                } else {
        !           602:                                        if (errno == EINTR && !read_interrupted)
        !           603:                                                continue;
        !           604:                                        error++;
        !           605: #ifdef DEBUG
        !           606:                                        if (debug >= 2)
        !           607:                                          (void)fprintf(ddt,
        !           608:                                            "recv failed: n= %d, errno = %d\n",
        !           609:                                            n, errno);
        !           610: #endif
        !           611:                                        break;
        !           612:                                }
        !           613:                        }
        !           614:                        if (soacnt == 0)
        !           615:                                ival.it_value.tv_sec = 120;
        !           616:                        (void) setitimer(ITIMER_REAL, &zeroival,
        !           617:                            (struct itimerval *)NULL);
        !           618:                        if (error)
        !           619:                                break;
        !           620:                        if ((len = htons(*(u_short *)buf)) == 0)
        !           621:                                break;
        !           622:                        l = len;
        !           623:                        cp = buf;
        !           624:                        eom = buf + len;
        !           625:                        while (l > 0) {
        !           626:                                (void) setitimer(ITIMER_REAL, &ival,
        !           627:                                    (struct itimerval *)NULL);
        !           628:                                errno = 0;
        !           629:                                if ((n = recv(s, (char *)cp, l, 0)) > 0) {
        !           630:                                        cp += n;
        !           631:                                        l -= n;
        !           632:                                } else {
        !           633:                                        if (errno == EINTR && !read_interrupted)
        !           634:                                                continue;
        !           635:                                        error++;
        !           636: #ifdef DEBUG
        !           637:                                        if (debug >= 2)
        !           638:                                                (void)fprintf(ddt,"recv failed\n");
        !           639: #endif
        !           640:                                        break;
        !           641:                                }
        !           642:                        }
        !           643:                        (void) setitimer(ITIMER_REAL, &zeroival,
        !           644:                            (struct itimerval *)NULL);
        !           645:                        if (error)
        !           646:                                break;
        !           647: #ifdef DEBUG
        !           648:                        if (debug >= 3) {
        !           649:                                (void)fprintf(ddt,"len = %d\n", len);
        !           650:                                fp_query(buf, ddt);
        !           651:                        }
        !           652:                        if (fp) fp_query(buf,fp);
        !           653: #endif
        !           654:                        if (len < sizeof(HEADER)) {
        !           655:                badrec:
        !           656:                                error++;
        !           657:                                if (!quiet)
        !           658:                                        syslog(LOG_ERR,
        !           659:                                          "record too short from %s, zone %s\n",
        !           660:                                          inet_ntoa(sin.sin_addr),
        !           661:                                          zp->z_source);
        !           662: #ifdef DEBUG
        !           663:                                if (debug)
        !           664:                                        fprintf(ddt,
        !           665:                                            "record too short from %s\n",
        !           666:                                    inet_ntoa(sin.sin_addr));
        !           667: #endif DEBUG
        !           668:                                break;
        !           669:                        }
        !           670:                        cp = buf + sizeof(HEADER);
        !           671:                        if (hp->qdcount) {
        !           672:                                if ((n = dn_skipname(cp, eom)) == -1 ||
        !           673:                                    n + QFIXEDSZ >= eom - cp)
        !           674:                                        goto badrec;
        !           675:                                cp += n + QFIXEDSZ;
        !           676:                        }
        !           677:                        nmp = cp;
        !           678:                        if ((n = dn_skipname(cp, eom)) == -1)
        !           679:                                goto badrec;
        !           680:                        tmp = cp + n;
        !           681: 
        !           682:                        n = print_output(buf, bufsize, cp);
        !           683:                        if (cp + n != eom) {
        !           684: #ifdef DEBUG
        !           685:                           if (debug)
        !           686:                           (void)fprintf(ddt,
        !           687:                                     "getzone: print_update failed (%d, %d)\n",
        !           688:                                        cp - buf, n);
        !           689: #endif
        !           690:                                error++;
        !           691:                                break;
        !           692:                        }
        !           693:                        GETSHORT(n, tmp);
        !           694:                        if (n == T_SOA) {
        !           695:                                if (soacnt == 0) {
        !           696:                                        soacnt++;
        !           697:                                        if (dn_expand(buf, buf + 512, nmp,
        !           698:                                            name, sizeof(name)) == -1)
        !           699:                                                goto badsoa;
        !           700:                                        if (eom - tmp <= 2 * sizeof(u_short) +
        !           701:                                            sizeof(u_long))
        !           702:                                                goto badsoa;
        !           703:                                        tmp += 2 * sizeof(u_short)
        !           704:                                                + sizeof(u_long);
        !           705:                                        if ((n = dn_skipname(tmp, eom)) == -1)
        !           706:                                                goto badsoa;
        !           707:                                        tmp += n;
        !           708:                                        if ((n = dn_skipname(tmp, eom)) == -1)
        !           709:                                                goto badsoa;
        !           710:                                        tmp += n;
        !           711:                                        if (eom - tmp <= sizeof(u_long))
        !           712:                                                goto badsoa;
        !           713:                                        GETLONG(serial, tmp);
        !           714: #ifdef DEBUG
        !           715:                                        if (debug > 2)
        !           716:                                            (void)fprintf(ddt,
        !           717:                                                "first SOA for %s, serial %d\n",
        !           718:                                                name, serial);
        !           719: #endif DEBUG
        !           720:                                        continue;
        !           721:                                }
        !           722:                                if (dn_expand(buf, buf + 512, nmp, name2, 
        !           723:                                    sizeof(name2)) == -1)
        !           724:                                        goto badsoa;
        !           725:                                if (strcasecmp((char *)name, (char *)name2) != 0) {
        !           726: #ifdef DEBUG
        !           727:                                        if (debug > 1)
        !           728:                                            (void)fprintf(ddt,
        !           729:                                              "extraneous SOA for %s\n",
        !           730:                                              name2);
        !           731: #endif DEBUG
        !           732:                                        continue;
        !           733:                                }
        !           734:                                tmp -= sizeof(u_short);
        !           735:                                if (soa_zinfo(&zp_finish, tmp, eom) == -1)
        !           736:                                        goto badsoa;
        !           737: #ifdef DEBUG
        !           738:                                if (debug > 1)
        !           739:                                    (void)fprintf(ddt,
        !           740:                                      "SOA, serial %d\n", zp_finish.z_serial);
        !           741: #endif DEBUG
        !           742:                                if (serial != zp_finish.z_serial) {
        !           743:                                        soacnt = 0;
        !           744:                                        got_soa = 0;
        !           745:                                        minimum_ttl = 0;
        !           746:                                        strcpy(prev_origin, zp->z_origin);
        !           747:                                        prev_dname[0] = 0;
        !           748: #ifdef DEBUG
        !           749:                                        if (debug)
        !           750:                                            (void)fprintf(ddt,
        !           751:                                                "serial changed, restart\n");
        !           752: #endif DEBUG
        !           753:                                        /*
        !           754:                                         * Flush buffer, truncate file
        !           755:                                         * and seek to beginning to restart.
        !           756:                                         */
        !           757:                                        fflush(dbfp);
        !           758:                                        if (ftruncate(fileno(dbfp), 0) != 0) {
        !           759:                                                if (!quiet)
        !           760:                                                    syslog(LOG_ERR,
        !           761:                                                        "ftruncate %s: %m\n",
        !           762:                                                        tmpname);
        !           763:                                                return(XFER_FAIL);
        !           764:                                        }
        !           765:                                        fseek(dbfp, 0L, 0);
        !           766:                                } else
        !           767:                                        break;
        !           768:                        }
        !           769:                }
        !           770:                (void) close(s);
        !           771:                if (error == 0) {
        !           772:                        (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
        !           773:                        return XFER_SUCCESS;
        !           774:                }
        !           775: #ifdef DEBUG
        !           776:                if (debug >= 2)
        !           777:                  (void)fprintf(ddt,"error receiving zone transfer\n");
        !           778: #endif
        !           779:            } else {
        !           780:                (void) close(s);
        !           781: #ifdef DEBUG
        !           782:                if (debug)
        !           783:                    (void)fprintf(ddt,
        !           784:                      "zone up-to-date, serial %d\n", zp_start.z_serial);
        !           785: #endif DEBUG
        !           786:                return XFER_UPTODATE;
        !           787:            }
        !           788:        }
        !           789:        (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
        !           790:        if (error)
        !           791:                return XFER_TIMEOUT;
        !           792:        return XFER_FAIL;
        !           793: }
        !           794: 
        !           795: /*
        !           796:  * Set flag saying to read was interrupted
        !           797:  * used for a read timer
        !           798:  */
        !           799: VOID
        !           800: read_alarm()
        !           801: {
        !           802:        extern int read_interrupted;
        !           803:        read_interrupted = 1;
        !           804: }
        !           805:  
        !           806: writemsg(rfd, msg, msglen)
        !           807:        int rfd;
        !           808:        u_char *msg;
        !           809:        int msglen;
        !           810: {
        !           811:        struct iovec iov[2];
        !           812:        u_short len = htons((u_short)msglen);
        !           813:  
        !           814:        iov[0].iov_base = (caddr_t)&len;
        !           815:        iov[0].iov_len = sizeof(len);
        !           816:        iov[1].iov_base = (caddr_t)msg;
        !           817:        iov[1].iov_len = msglen;
        !           818:        if (writev(rfd, iov, 2) != sizeof(len) + msglen) {
        !           819: #ifdef DEBUG
        !           820:            if (debug)
        !           821:              (void)fprintf(ddt,"write failed %d\n", errno);
        !           822: #endif
        !           823:            return (-1);
        !           824:        }
        !           825:        return (0);
        !           826: }
        !           827: 
        !           828: 
        !           829: soa_zinfo(zp, cp, eom)
        !           830:        register struct zoneinfo *zp;
        !           831:        register u_char *cp;
        !           832:        u_char *eom;
        !           833: {
        !           834:        register int n;
        !           835: 
        !           836:        if (eom - cp < 3 * sizeof(u_short) + sizeof(u_long))
        !           837:                return (-1);
        !           838:        cp += 3 * sizeof(u_short) + sizeof(u_long);
        !           839:        if ((n = dn_skipname(cp, eom)) == -1)
        !           840:                return (-1);
        !           841:        cp += n;
        !           842:        if ((n = dn_skipname(cp, eom)) == -1)
        !           843:                return (-1);
        !           844:        cp += n;
        !           845:        if (eom - cp < 5 * sizeof(u_long))
        !           846:                return (-1);
        !           847:        GETLONG(zp->z_serial, cp);
        !           848:        GETLONG(zp->z_refresh, cp);
        !           849:        gettime(&tt);
        !           850:        zp->z_time = tt.tv_sec + zp->z_refresh;
        !           851:        GETLONG(zp->z_retry, cp);
        !           852:        GETLONG(zp->z_expire, cp);
        !           853:        GETLONG(zp->z_minimum, cp);
        !           854:        return (0);
        !           855: }
        !           856: 
        !           857: gettime(ttp)
        !           858: struct timeval *ttp;
        !           859: {
        !           860:        if (gettimeofday(ttp, (struct timezone *)0) < 0)
        !           861:                syslog(LOG_ERR, "gettimeofday failed: %m");
        !           862: }
        !           863: 
        !           864: /*
        !           865:  * Parse the message, determine if it should be printed, and if so, print it
        !           866:  * in .db file form.
        !           867:  * Does minimal error checking on the message content.
        !           868:  */
        !           869: print_output(msg, msglen, rrp)
        !           870:        u_char *msg;
        !           871:        int msglen;
        !           872:        u_char *rrp;
        !           873: {
        !           874:        register u_char *cp;
        !           875:        register HEADER *hp = (HEADER *) msg;
        !           876:        u_long addr, ttl;
        !           877:        int i, j, tab, result, class, type, dlen, n1;
        !           878:        long n;
        !           879:        u_char *cp1, data[BUFSIZ];
        !           880:        u_char *temp_ptr;       /* used to get ttl for RR */
        !           881:        char *cdata, *origin, *proto, dname[MAXDNAME];
        !           882:        extern char *inet_ntoa(), *protocolname(), *servicename();
        !           883: 
        !           884:        cp = rrp;
        !           885:        if ((n = dn_expand(msg, msg + msglen, cp, (u_char *) dname,
        !           886:                    sizeof(dname))) < 0) {
        !           887:                hp->rcode = FORMERR;
        !           888:                return (-1);
        !           889:        }
        !           890:        cp += n;
        !           891:        GETSHORT(type, cp);
        !           892:        GETSHORT(class, cp);
        !           893:        GETLONG(ttl, cp);
        !           894:        GETSHORT(dlen, cp);
        !           895: 
        !           896:        origin = index(dname, '.');
        !           897:        if (origin == NULL)
        !           898:                origin = "";
        !           899:        else
        !           900:                origin++;       /* move past the '.' */
        !           901: #ifdef DEBUG
        !           902:        if (debug > 2)
        !           903:                (void) fprintf(ddt, "print_output: dname %s type %d class %d ttl %d\n",
        !           904:                    dname, type, class, ttl);
        !           905: #endif
        !           906:        /*
        !           907:         * Convert the resource record data into the internal database format.
        !           908:         */
        !           909:        switch (type) {
        !           910:        case T_A:
        !           911:        case T_WKS:
        !           912:        case T_HINFO:
        !           913:        case T_UINFO:
        !           914:        case T_TXT:
        !           915:        case T_UID:
        !           916:        case T_GID:
        !           917:                cp1 = cp;
        !           918:                n = dlen;
        !           919:                cp += n;
        !           920:                break;
        !           921: 
        !           922:        case T_CNAME:
        !           923:        case T_MB:
        !           924:        case T_MG:
        !           925:        case T_MR:
        !           926:        case T_NS:
        !           927:        case T_PTR:
        !           928:                if ((n = dn_expand(msg, msg + msglen, cp, data,
        !           929:                            sizeof(data))) < 0) {
        !           930:                        hp->rcode = FORMERR;
        !           931:                        return (-1);
        !           932:                }
        !           933:                cp += n;
        !           934:                cp1 = data;
        !           935:                n = strlen((char *) data) + 1;
        !           936:                break;
        !           937: 
        !           938:        case T_MINFO:
        !           939:        case T_SOA:
        !           940:                if ((n = dn_expand(msg, msg + msglen, cp, data,
        !           941:                            sizeof(data))) < 0) {
        !           942:                        hp->rcode = FORMERR;
        !           943:                        return (-1);
        !           944:                }
        !           945:                cp += n;
        !           946:                cp1 = data + (n = strlen((char *) data) + 1);
        !           947:                n1 = sizeof(data) - n;
        !           948:                if (type == T_SOA)
        !           949:                        n1 -= 5 * sizeof(u_long);
        !           950:                if ((n = dn_expand(msg, msg + msglen, cp, cp1, n1)) < 0) {
        !           951:                        hp->rcode = FORMERR;
        !           952:                        return (-1);
        !           953:                }
        !           954:                cp += n;
        !           955:                cp1 += strlen((char *) cp1) + 1;
        !           956:                if (type == T_SOA) {
        !           957:                        temp_ptr = cp + 4 * sizeof(u_long);
        !           958:                        GETLONG(minimum_ttl, temp_ptr);
        !           959:                        bcopy((char *) cp, (char *) cp1,
        !           960:                            n = 5 * sizeof(u_long));
        !           961:                        cp += n;
        !           962:                        cp1 += n;
        !           963:                }
        !           964:                n = cp1 - data;
        !           965:                cp1 = data;
        !           966:                break;
        !           967: 
        !           968:        case T_MX:
        !           969:                /* grab preference */
        !           970:                bcopy((char *) cp, (char *) data, sizeof(u_short));
        !           971:                cp1 = data + sizeof(u_short);
        !           972:                cp += sizeof(u_short);
        !           973: 
        !           974:                /* get name */
        !           975:                if ((n = dn_expand(msg, msg + msglen, cp, cp1,
        !           976:                            sizeof(data) - sizeof(u_short))) < 0)
        !           977:                        return (-1);
        !           978:                cp += n;
        !           979: 
        !           980:                /* compute end of data */
        !           981:                cp1 += strlen((char *) cp1) + 1;
        !           982:                /* compute size of data */
        !           983:                n = cp1 - data;
        !           984:                cp1 = data;
        !           985:                break;
        !           986: 
        !           987:        default:
        !           988: #ifdef DEBUG
        !           989:                if (debug >= 3)
        !           990:                        (void) fprintf(ddt, "unknown type %d\n", type);
        !           991: #endif
        !           992:                return ((cp - rrp) + dlen);
        !           993:        }
        !           994:        if (n > MAXDATA) {
        !           995: #ifdef DEBUG
        !           996:                if (debug)
        !           997:                        (void) fprintf(ddt,
        !           998:                            "update type %d: %d bytes is too much data\n",
        !           999:                            type, n);
        !          1000: #endif
        !          1001:                hp->rcode = NOCHANGE;   /* XXX - FORMERR ??? */
        !          1002:                return (-1);
        !          1003:        }
        !          1004:        cdata = (char *) cp1;
        !          1005:        result = cp - rrp;
        !          1006: 
        !          1007:        /*
        !          1008:         * Only print one SOA per db file
        !          1009:         */
        !          1010:        if (type == T_SOA) {
        !          1011:                if (got_soa)
        !          1012:                        return result;
        !          1013:                else
        !          1014:                        got_soa++;
        !          1015:        }
        !          1016:        /*
        !          1017:         * If the origin has changed, print the new origin
        !          1018:         */
        !          1019:        if (strcasecmp(prev_origin, origin)) {
        !          1020:                (void) strcpy(prev_origin, origin);
        !          1021:                (void) fprintf(dbfp, "$ORIGIN %s.\n", origin);
        !          1022:        }
        !          1023:        tab = 0;
        !          1024: 
        !          1025:        if (strcasecmp(prev_dname, dname)) {
        !          1026:                /*
        !          1027:                 * set the prev_dname to be the current dname, then cut off all
        !          1028:                 * characters of dname after (and including) the first '.'
        !          1029:                 */
        !          1030:                char *cutp = index(dname, '.');
        !          1031: 
        !          1032:                (void) strcpy(prev_dname, dname);
        !          1033:                if (cutp)
        !          1034:                        *cutp = NULL;
        !          1035: 
        !          1036:                if (dname[0] == 0) {
        !          1037:                        if (origin[0] == 0)
        !          1038:                                (void) fprintf(dbfp, ".\t");
        !          1039:                        else
        !          1040:                                (void) fprintf(dbfp, ".%s.\t", origin); /* ??? */
        !          1041:                } else
        !          1042:                        (void) fprintf(dbfp, "%s\t", dname);
        !          1043:                if (strlen(dname) < 8)
        !          1044:                        tab = 1;
        !          1045:        } else {
        !          1046:                (void) putc('\t', dbfp);
        !          1047:                tab = 1;
        !          1048:        }
        !          1049: 
        !          1050:        if (ttl != 0 && ttl != minimum_ttl)
        !          1051:                (void) fprintf(dbfp, "%d\t", (int) ttl);
        !          1052:        else if (tab)
        !          1053:                (void) putc('\t', dbfp);
        !          1054: 
        !          1055:        (void) fprintf(dbfp, "%s\t%s\t", p_class(class), p_type(type));
        !          1056:        cp = (u_char *) cdata;
        !          1057: 
        !          1058:        /*
        !          1059:         * Print type specific data
        !          1060:         */
        !          1061:        switch (type) {
        !          1062: 
        !          1063:        case T_A:
        !          1064:                switch (class) {
        !          1065:                case C_IN:
        !          1066:                case C_HS:
        !          1067:                        GETLONG(n, cp);
        !          1068:                        n = htonl(n);
        !          1069:                        (void) fprintf(dbfp, "%s",
        !          1070:                            inet_ntoa(*(struct in_addr *) & n));
        !          1071:                        break;
        !          1072:                }
        !          1073:                (void) fprintf(dbfp, "\n");
        !          1074:                break;
        !          1075: 
        !          1076:        case T_CNAME:
        !          1077:        case T_MB:
        !          1078:        case T_MG:
        !          1079:        case T_MR:
        !          1080:        case T_PTR:
        !          1081:                if (cp[0] == '\0')
        !          1082:                        (void) fprintf(dbfp, ".\n");
        !          1083:                else
        !          1084:                        (void) fprintf(dbfp, "%s.\n", cp);
        !          1085:                break;
        !          1086: 
        !          1087:        case T_NS:
        !          1088:                cp = (u_char *) cdata;
        !          1089:                if (cp[0] == '\0')
        !          1090:                        (void) fprintf(dbfp, ".\t");
        !          1091:                else
        !          1092:                        (void) fprintf(dbfp, "%s.", cp);
        !          1093:                (void) fprintf(dbfp, "\n");
        !          1094:                break;
        !          1095: 
        !          1096:        case T_HINFO:
        !          1097:                if (n = *cp++) {
        !          1098:                        (void) fprintf(dbfp, "\"%.*s\"", (int) n, cp);
        !          1099:                        cp += n;
        !          1100:                } else
        !          1101:                        (void) fprintf(dbfp, "\"\"");
        !          1102:                if (n = *cp++)
        !          1103:                        (void) fprintf(dbfp, " \"%.*s\"", (int) n, cp);
        !          1104:                else
        !          1105:                        (void) fprintf(dbfp, "\"\"");
        !          1106:                (void) putc('\n', dbfp);
        !          1107:                break;
        !          1108: 
        !          1109:        case T_SOA:
        !          1110:                (void) fprintf(dbfp, "%s.", cp);
        !          1111:                cp += strlen((char *) cp) + 1;
        !          1112:                (void) fprintf(dbfp, " %s. (\n", cp);
        !          1113:                cp += strlen((char *) cp) + 1;
        !          1114:                GETLONG(n, cp);
        !          1115:                (void) fprintf(dbfp, "\t\t%lu", n);
        !          1116:                GETLONG(n, cp);
        !          1117:                (void) fprintf(dbfp, " %lu", n);
        !          1118:                GETLONG(n, cp);
        !          1119:                (void) fprintf(dbfp, " %lu", n);
        !          1120:                GETLONG(n, cp);
        !          1121:                (void) fprintf(dbfp, " %lu", n);
        !          1122:                GETLONG(n, cp);
        !          1123:                (void) fprintf(dbfp, " %lu )\n", n);
        !          1124:                break;
        !          1125: 
        !          1126:        case T_MX:
        !          1127:                GETSHORT(n, cp);
        !          1128:                (void) fprintf(dbfp, "%lu", n);
        !          1129:                (void) fprintf(dbfp, " %s.\n", cp);
        !          1130:                break;
        !          1131: 
        !          1132:        case T_TXT:
        !          1133:                cp1 = cp + n;
        !          1134:                (void) putc('"', dbfp);
        !          1135:                while (cp < cp1) {
        !          1136:                        if (i = *cp++) {
        !          1137:                                for (j = i ; j > 0 && cp < cp1 ; j--)
        !          1138:                                        if (*cp == '\n') {
        !          1139:                                                (void) putc('\\', dbfp);
        !          1140:                                                (void) putc(*cp++, dbfp);
        !          1141:                                        } else
        !          1142:                                                (void) putc(*cp++, dbfp);
        !          1143:                        }
        !          1144:                }
        !          1145:                (void) fputs("\"\n", dbfp);
        !          1146:                break;
        !          1147: 
        !          1148:        case T_UINFO:
        !          1149:                (void) fprintf(dbfp, "\"%s\"\n", cp);
        !          1150:                break;
        !          1151: 
        !          1152:        case T_UID:
        !          1153:        case T_GID:
        !          1154:                if (n == sizeof(u_long)) {
        !          1155:                        GETLONG(n, cp);
        !          1156:                        (void) fprintf(dbfp, "%lu\n", n);
        !          1157:                }
        !          1158:                break;
        !          1159: 
        !          1160:        case T_WKS:
        !          1161:                GETLONG(addr, cp);
        !          1162:                addr = htonl(addr);
        !          1163:                (void) fprintf(dbfp, "%s ",
        !          1164:                    inet_ntoa(*(struct in_addr *) & addr));
        !          1165:                proto = protocolname(*cp);
        !          1166:                cp += sizeof(char);
        !          1167:                (void) fprintf(dbfp, "%s ", proto);
        !          1168:                i = 0;
        !          1169:                while (cp < (u_char *) cdata + n) {
        !          1170:                        j = *cp++;
        !          1171:                        do {
        !          1172:                                if (j & 0200)
        !          1173:                                        (void) fprintf(dbfp, " %s",
        !          1174:                                            servicename(i, proto));
        !          1175:                                j <<= 1;
        !          1176:                        } while (++i & 07);
        !          1177:                }
        !          1178:                (void) fprintf(dbfp, "\n");
        !          1179:                break;
        !          1180: 
        !          1181:        case T_MINFO:
        !          1182:                (void) fprintf(dbfp, "%s.", cp);
        !          1183:                cp += strlen((char *) cp) + 1;
        !          1184:                (void) fprintf(dbfp, " %s.\n", cp);
        !          1185:                break;
        !          1186: 
        !          1187:        default:
        !          1188:                (void) fprintf(dbfp, "???\n");
        !          1189:        }
        !          1190:        if (ferror(dbfp)) {
        !          1191:                syslog(LOG_ERR, "%s: %m", tmpname);
        !          1192:                exit(XFER_FAIL);
        !          1193:        }
        !          1194:        return result;
        !          1195: }
        !          1196: 
        !          1197: /*
        !          1198:  * Make a copy of a string and return a pointer to it.
        !          1199:  */
        !          1200: char *
        !          1201: savestr(str)
        !          1202:        char *str;
        !          1203: {
        !          1204:        char *cp;
        !          1205: 
        !          1206:        cp = (char *)malloc((unsigned)strlen(str) + 1);
        !          1207:        if (cp == NULL) {
        !          1208:                syslog(LOG_ERR, "savestr: %m");
        !          1209:                exit(XFER_FAIL);
        !          1210:        }
        !          1211:        (void) strcpy(cp, str);
        !          1212:        return (cp);
        !          1213: }

unix.superglobalmegacorp.com

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