Annotation of 43BSDTahoe/etc/named/ns_maint.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[] = "@(#)ns_maint.c 4.24 (Berkeley) 6/18/88";
        !            20: #endif /* not lint */
        !            21: 
        !            22: #include <sys/param.h>
        !            23: #include <sys/socket.h>
        !            24: #include <sys/time.h>
        !            25: #if defined(SYSV)
        !            26: #include <unistd.h>
        !            27: #endif SYSV
        !            28: #include <netinet/in.h>
        !            29: #include <stdio.h>
        !            30: #include <syslog.h>
        !            31: #include <signal.h>
        !            32: #include <errno.h>
        !            33: #include <arpa/nameser.h>
        !            34: #include "ns.h"
        !            35: #include "db.h"
        !            36: 
        !            37: extern int errno;
        !            38: extern int maint_interval;
        !            39: 
        !            40: 
        !            41: /*
        !            42:  * Invoked at regular intervals by signal interrupt; refresh all secondary
        !            43:  * zones from primary name server and remove old cache entries.  Also,
        !            44:  * ifdef'd ALLOW_UPDATES, dump database if it has changed since last
        !            45:  * dump/bootup.
        !            46:  */
        !            47: ns_maint()
        !            48: {
        !            49:        register struct zoneinfo *zp;
        !            50:        struct itimerval ival;
        !            51:        time_t next_refresh = 0;
        !            52:        int zonenum;
        !            53: 
        !            54: #ifdef DEBUG
        !            55:        if (debug)
        !            56:                fprintf(ddt,"ns_maint()\n");
        !            57: #endif
        !            58: 
        !            59:        for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {
        !            60:                switch(zp->z_type) {
        !            61: #ifdef ALLOW_UPDATES
        !            62:                case Z_PRIMARY:
        !            63: #endif ALLOW_UPDATES
        !            64:                case Z_SECONDARY:
        !            65:                case Z_CACHE:
        !            66:                        break;
        !            67: 
        !            68:                default:
        !            69:                        continue;
        !            70:                }
        !            71:                gettime(&tt);
        !            72: #ifdef DEBUG
        !            73:                if (debug >= 2)
        !            74:                        printzoneinfo(zonenum);
        !            75: #endif
        !            76:                if (tt.tv_sec >= zp->z_time && zp->z_refresh > 0) {
        !            77:                        if (zp->z_type == Z_CACHE)
        !            78:                                doachkpt();
        !            79:                        if (zp->z_type == Z_SECONDARY)
        !            80:                                zoneref(zp);
        !            81: #ifdef ALLOW_UPDATES
        !            82:                        /*
        !            83:                         * Checkpoint the zone if it has changed
        !            84:                         * since we last checkpointed
        !            85:                         */
        !            86:                        if (zp->z_type == Z_PRIMARY && zp->hasChanged)
        !            87:                                zonedump(zp);
        !            88: #endif ALLOW_UPDATES
        !            89:                        zp->z_time = tt.tv_sec + zp->z_refresh;
        !            90:                }
        !            91: 
        !            92:                /*
        !            93:                 * Find when the next refresh needs to be and set
        !            94:                 * interrupt time accordingly.
        !            95:                 */
        !            96:                if (next_refresh == 0 ||
        !            97:                    (zp->z_time != 0 && next_refresh > zp->z_time))
        !            98:                        next_refresh = zp->z_time;
        !            99:        }
        !           100: 
        !           101:         /*
        !           102:         *  Schedule the next call to this function.
        !           103:         *  Don't visit any sooner than maint_interval.
        !           104:         */
        !           105:        bzero((char *)&ival, sizeof (ival));
        !           106:        ival.it_value.tv_sec = next_refresh - tt.tv_sec;
        !           107:        if (ival.it_value.tv_sec < maint_interval)
        !           108:                ival.it_value.tv_sec = maint_interval;
        !           109:        (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);
        !           110: #ifdef DEBUG
        !           111:        if (debug)
        !           112:                fprintf(ddt,"exit ns_maint() Next interrupt in %d sec\n",
        !           113:                        ival.it_value.tv_sec);
        !           114: #endif
        !           115: }
        !           116: 
        !           117: zoneref(zp)
        !           118:        struct zoneinfo *zp;
        !           119: {
        !           120:        HEADER *hp;
        !           121:        u_short len;
        !           122:        u_long serial;
        !           123:        int s, n, l, tries;
        !           124:        int cnt, soacnt, error = 0;
        !           125:        int zone = zp - zones;
        !           126:        u_char *cp, *nmp, *eom;
        !           127:        u_char *tmp;
        !           128:        u_char buf[PACKETSZ];
        !           129:        char name[MAXDNAME], name2[MAXDNAME];
        !           130:        struct sockaddr_in sin;
        !           131:        struct zoneinfo zp_start, zp_finish;
        !           132:        struct itimerval ival;
        !           133:        struct itimerval zeroival;
        !           134:        extern struct sockaddr_in nsaddr;
        !           135:        extern int errno;
        !           136:        extern int read_interrupted;
        !           137:        extern int read_alarm();
        !           138:        struct sigvec sv, osv;
        !           139: 
        !           140: #ifdef DEBUG
        !           141:        if (debug)
        !           142:                fprintf(ddt,"zoneref() %s\n", zp->z_origin);
        !           143: #endif
        !           144:        bzero((char *)&zeroival, sizeof(zeroival));
        !           145:        ival = zeroival;
        !           146:        ival.it_value.tv_sec = 30;
        !           147:        sv.sv_handler = read_alarm;
        !           148:        sv.sv_onstack = 0;
        !           149:        sv.sv_mask = ~0;
        !           150:        (void) sigvec(SIGALRM, &sv, &osv);
        !           151: 
        !           152:        for( cnt = 0; cnt < zp->z_addrcnt; cnt++) {
        !           153:                error = 0;
        !           154:                bzero((char *)&sin, sizeof(sin));
        !           155:                sin.sin_family = AF_INET;
        !           156:                sin.sin_port = nsaddr.sin_port;
        !           157:                sin.sin_addr = zp->z_addr[cnt];
        !           158:                if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        !           159:                        syslog(LOG_ERR, "zoneref: socket: %m");
        !           160:                        error++;
        !           161:                        break;
        !           162:                }       
        !           163: #ifdef DEBUG
        !           164:                if (debug >= 2) {
        !           165:                        fprintf(ddt,"connecting to server #%d %s, %d\n",
        !           166:                           cnt+1, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
        !           167:                }
        !           168: #endif
        !           169:                if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
        !           170:                        (void) close(s);
        !           171:                        error++;
        !           172: #ifdef DEBUG
        !           173:                        if (debug >= 2)
        !           174:                                fprintf(ddt,"connect failed, errno %d\n", errno);
        !           175: #endif
        !           176:                        continue;
        !           177:                }       
        !           178:                if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,
        !           179:                    T_SOA, (char *)NULL, 0, NULL, buf, sizeof(buf))) < 0) {
        !           180:                        syslog(LOG_ERR, "zoneref: res_mkquery failed");
        !           181:                        (void) close(s);
        !           182:                        (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
        !           183:                        return;
        !           184:                }
        !           185:                /*
        !           186:                 * Send length & message for zone transfer
        !           187:                 */
        !           188:                if (writemsg(s, buf, n) < 0) {
        !           189:                        (void) close(s);
        !           190:                        error++;
        !           191: #ifdef DEBUG
        !           192:                        if (debug >= 2)
        !           193:                                fprintf(ddt,"writemsg failed\n");
        !           194: #endif
        !           195:                        continue;       
        !           196:                }
        !           197:                /*
        !           198:                 * Get out your butterfly net and catch the SOA
        !           199:                 */
        !           200:                cp = buf;
        !           201:                l = sizeof(u_short);
        !           202:                read_interrupted = 0;
        !           203:                while (l > 0) {
        !           204:                        (void) setitimer(ITIMER_REAL, &ival,
        !           205:                            (struct itimerval *)NULL);
        !           206:                        if ((n = recv(s, cp, l, 0)) > 0) {
        !           207:                                cp += n;
        !           208:                                l -= n;
        !           209:                        } else {
        !           210:                                if (errno == EINTR && !read_interrupted)
        !           211:                                        continue;
        !           212:                                error++;
        !           213:                                break;
        !           214:                        }
        !           215:                }
        !           216:                (void) setitimer(ITIMER_REAL, &zeroival,
        !           217:                    (struct itimerval *)NULL);
        !           218:                if (error) {
        !           219:                        (void) close(s);
        !           220:                        continue;
        !           221:                }
        !           222:                if ((len = htons(*(u_short *)buf)) == 0) {
        !           223:                        (void) close(s);
        !           224:                        if (zp->z_sysloged == 0)
        !           225:                            syslog(LOG_ERR,
        !           226:                                "no SOA from server %s, zone %s (len 0)\n",
        !           227:                                inet_ntoa(sin.sin_addr), zp->z_origin);
        !           228:                        continue;
        !           229:                }
        !           230:                l = len;
        !           231:                cp = buf;
        !           232:                while (l > 0) {
        !           233:                        (void) setitimer(ITIMER_REAL, &ival,
        !           234:                            (struct itimerval *)NULL);
        !           235:                        if ((n = recv(s, cp, l, 0)) > 0) {
        !           236:                                cp += n;
        !           237:                                l -= n;
        !           238:                        } else {
        !           239:                                if (errno == EINTR && !read_interrupted)
        !           240:                                        continue;
        !           241:                                error++;
        !           242:                                break;
        !           243:                        }
        !           244:                }
        !           245:                (void) setitimer(ITIMER_REAL, &zeroival,
        !           246:                    (struct itimerval *)NULL);
        !           247:                if (error) {
        !           248:                        (void) close(s);
        !           249:                        continue;
        !           250:                }
        !           251: #ifdef DEBUG
        !           252:                if (debug >= 3) {
        !           253:                        fprintf(ddt,"len = %d\n", len);
        !           254:                        fp_query(buf, ddt);
        !           255:                }
        !           256: #endif DEBUG
        !           257:                zp_start = *zp;
        !           258:                tmp = buf + sizeof(HEADER);
        !           259:                eom = buf + len;
        !           260:                /* NEED TO CHECK MESSAGE LENGTH, ANCOUNT, AA */
        !           261:                tmp += dn_skipname(tmp, eom) + QFIXEDSZ;
        !           262:                tmp += dn_skipname(tmp, eom);
        !           263:                soa_zinfo(&zp_start, tmp, eom);
        !           264:                if (zp->z_serial >= zp_start.z_serial && zp->z_auth)  {
        !           265: #ifdef DEBUG
        !           266:                        if (debug)
        !           267:                                fprintf(ddt,"zoneref: up to date (%d >= %d)\n",
        !           268:                                        zp->z_serial, zp_start.z_serial);
        !           269: #endif DEBUG
        !           270:                        zp->z_lastupdate = tt.tv_sec;
        !           271:                        zp->z_refresh = zp_start.z_refresh;
        !           272:                        (void) close(s);
        !           273:                        (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
        !           274:                        if (zp->z_source) {
        !           275: #if defined(SYSV)
        !           276:                                struct utimbuf t;
        !           277: 
        !           278:                                t.actime = t.modtime = tt.tv_sec;
        !           279:                                (void) utime(zp->z_source, &t);
        !           280: #else
        !           281:                                struct timeval t[2];
        !           282: 
        !           283:                                t[0] = tt;
        !           284:                                t[1] = tt;
        !           285:                                (void) utimes(zp->z_source, t);
        !           286: #endif /* SYSV */
        !           287:                        }
        !           288:                        return;
        !           289:                }
        !           290: #ifdef DEBUG
        !           291:                if (debug)
        !           292:                        fprintf(ddt,"zoneref: need xfer (%d < %d)\n",
        !           293:                                zp->z_serial, zp_start.z_serial);
        !           294: #endif DEBUG
        !           295:                hp = (HEADER *) buf;
        !           296:                soacnt = 0;
        !           297:                /* mark all existing RR's for zone as "old" */
        !           298:                mark_zone (hashtab, zone, 1);
        !           299:                for (tries = 0; ; tries++) {
        !           300:                        if (soacnt == 0) {
        !           301:                            /* delete unmarked (new) RR's for zone */
        !           302:                            if (tries)
        !           303:                                clean_zone (hashtab, zone, 0);
        !           304:                            if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,
        !           305:                              T_AXFR, (char *)NULL, 0, NULL,
        !           306:                              buf, sizeof(buf))) < 0) {
        !           307:                                syslog(LOG_ERR, "zoneref: res_mkquery failed");
        !           308:                                (void) close(s);
        !           309:                                (void) sigvec(SIGALRM, &osv,
        !           310:                                    (struct sigvec *)0);
        !           311:                                return;
        !           312:                            }
        !           313:                            /*
        !           314:                             * Send length & message for zone transfer
        !           315:                             */
        !           316:                            if (writemsg(s, buf, n) < 0) {
        !           317:                                    (void) close(s);
        !           318:                                    error++;
        !           319: #ifdef DEBUG
        !           320:                                    if (debug >= 2)
        !           321:                                            fprintf(ddt,"writemsg failed\n");
        !           322: #endif
        !           323:                                    break;      
        !           324:                            }
        !           325:                        }
        !           326:                        /*
        !           327:                         * Receive length & response
        !           328:                         */
        !           329:                        cp = buf;
        !           330:                        l = sizeof(u_short);
        !           331:                        while (l > 0) {
        !           332:                                (void) setitimer(ITIMER_REAL, &ival,
        !           333:                                    (struct itimerval *)NULL);
        !           334:                                if ((n = recv(s, cp, l, 0)) > 0) {
        !           335:                                        cp += n;
        !           336:                                        l -= n;
        !           337:                                } else {
        !           338:                                        if (errno == EINTR && !read_interrupted)
        !           339:                                                continue;
        !           340:                                        error++;
        !           341:                                        break;
        !           342:                                }
        !           343:                        }
        !           344:                        (void) setitimer(ITIMER_REAL, &zeroival,
        !           345:                            (struct itimerval *)NULL);
        !           346:                        if (error)
        !           347:                                break;
        !           348:                        if ((len = htons(*(u_short *)buf)) == 0)
        !           349:                                break;
        !           350:                        l = len;
        !           351:                        cp = buf;
        !           352:                        eom = buf + len;
        !           353:                        while (l > 0) {
        !           354:                                (void) setitimer(ITIMER_REAL, &ival,
        !           355:                                    (struct itimerval *)NULL);
        !           356:                                if ((n = recv(s, cp, l, 0)) > 0) {
        !           357:                                        cp += n;
        !           358:                                        l -= n;
        !           359:                                } else {
        !           360:                                        if (errno == EINTR && !read_interrupted)
        !           361:                                                continue;
        !           362:                                        error++;
        !           363:                                        break;
        !           364:                                }
        !           365:                        }
        !           366:                        (void) setitimer(ITIMER_REAL, &zeroival,
        !           367:                            (struct itimerval *)NULL);
        !           368:                        if (error)
        !           369:                                break;
        !           370: #ifdef DEBUG
        !           371:                        if (debug >= 3) {
        !           372:                                fprintf(ddt,"len = %d\n", len);
        !           373:                                fp_query(buf, ddt);
        !           374:                        }
        !           375: #endif
        !           376:                        cp = buf + sizeof(HEADER);
        !           377:                        if (hp->qdcount)
        !           378:                                cp += dn_skipname(cp, eom) + QFIXEDSZ;
        !           379:                        nmp = cp;
        !           380:                        tmp = cp + dn_skipname(cp, eom);
        !           381:                        n = doupdate(buf, sizeof(buf), cp, zone,
        !           382:                                        (struct databuf **)0, DB_NODATA);
        !           383:                        if (cp + n != eom) {
        !           384: #ifdef DEBUG
        !           385:                           if (debug)
        !           386:                             fprintf(ddt,"zoneref: doupdate failed (%d, %d)\n",
        !           387:                                        cp - buf, n);
        !           388: #endif
        !           389:                                error++;
        !           390:                                break;
        !           391:                        }
        !           392:                        GETSHORT(n, tmp);
        !           393:                        if (n == T_SOA) {
        !           394:                                if (soacnt == 0) {
        !           395:                                        soacnt++;
        !           396:                                        dn_expand(buf, buf + 512, nmp, name,
        !           397:                                                sizeof(name));
        !           398:                                        tmp += 2 * sizeof(u_short)
        !           399:                                                + sizeof(u_long);
        !           400:                                        tmp += dn_skipname(tmp, eom);
        !           401:                                        tmp += dn_skipname(tmp, eom);
        !           402:                                        GETLONG(serial, tmp);
        !           403: #ifdef DEBUG
        !           404:                                        if (debug)
        !           405:                                            fprintf(ddt,
        !           406:                                                "first SOA for %s, serial %d\n",
        !           407:                                                name, serial);
        !           408: #endif DEBUG
        !           409:                                        continue;
        !           410:                                }
        !           411:                                dn_expand(buf, buf + 512, nmp, name2, 
        !           412:                                        sizeof(name2));
        !           413:                                if (strcasecmp(name, name2) !=0) {
        !           414: #ifdef DEBUG
        !           415:                                        if (debug)
        !           416:                                            fprintf(ddt,
        !           417:                                              "extraneous SOA for %s\n",
        !           418:                                              name2);
        !           419: #endif DEBUG
        !           420:                                        continue;
        !           421:                                }
        !           422:                                tmp -= sizeof(u_short);
        !           423:                                soa_zinfo(&zp_finish, tmp, eom);
        !           424: #ifdef DEBUG
        !           425:                                if (debug)
        !           426:                                    fprintf(ddt,
        !           427:                                      "SOA, serial %d\n", zp_finish.z_serial);
        !           428: #endif DEBUG
        !           429:                                if (serial != zp_finish.z_serial) {
        !           430:                                         soacnt = 0;
        !           431: #ifdef DEBUG
        !           432:                                        if (debug)
        !           433:                                            fprintf(ddt,
        !           434:                                                "serial changed, restart\n");
        !           435: #endif DEBUG
        !           436:                                } else
        !           437:                                        break;
        !           438:                        }
        !           439:                }
        !           440:                (void) close(s);
        !           441:                if ( error == 0) {
        !           442:                        zp->z_refresh = zp_finish.z_refresh;
        !           443:                        zp->z_retry   = zp_finish.z_retry;
        !           444:                        zp->z_expire  = zp_finish.z_expire;
        !           445:                        zp->z_minimum = zp_finish.z_minimum;
        !           446:                        zp->z_serial  = zp_finish.z_serial;
        !           447:                        zp->z_lastupdate = tt.tv_sec;
        !           448:                        zp->z_sysloged = 0;
        !           449:                        zp->z_auth = 1;
        !           450:                        /* delete previously marked RR's here, then dump */
        !           451:                        clean_zone (hashtab, zone, 1);
        !           452:                        zonedump(zp);
        !           453:                        (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
        !           454:                        return;
        !           455:                }
        !           456:                /* error: delete unmarked RR's here; remove old marks */
        !           457:                clean_zone (hashtab, zone, 0);
        !           458:                mark_zone (hashtab, zone, 0);
        !           459: #ifdef DEBUG
        !           460:                if (debug >= 2)
        !           461:                        fprintf(ddt,"error receiving zone transfer\n");
        !           462: #endif
        !           463:        }
        !           464:        (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
        !           465:        /*
        !           466:         *     Freedom at last!!
        !           467:         *
        !           468:         *  The land where all repressed slaves dream of.
        !           469:         *
        !           470:         *  Can't find a master to talk to.
        !           471:         *  syslog it and hope we can find a master during next maintenance.
        !           472:         */
        !           473:        if (error && (!zp->z_sysloged)) {
        !           474:            syslog(LOG_WARNING,
        !           475:                "zoneref: Masters for secondary zone %s unreachable",
        !           476:                zp->z_origin);
        !           477:            zp->z_sysloged++;
        !           478:        }
        !           479:        zp->z_refresh = zp->z_retry;
        !           480:        if (tt.tv_sec - zp->z_lastupdate > zp->z_expire)
        !           481:                zp->z_auth = 0;
        !           482: }
        !           483: 
        !           484: #ifdef unused
        !           485: /*
        !           486:  * Recursively delete all domains (except for root SOA records),
        !           487:  * starting from head of list pointed to by np.
        !           488:  */
        !           489: static DelDom(fnp, isroot)
        !           490:        struct namebuf *fnp;
        !           491:        int isroot;
        !           492: {
        !           493:        register struct databuf *dp, *pdp = NULL;
        !           494:        register struct namebuf *np = fnp;
        !           495:        struct namebuf **npp, **nppend;
        !           496: 
        !           497: #ifdef DEBUG
        !           498:        if (debug >= 3)
        !           499:                fprintf(ddt, "DelDom('%s', %d)\n", fnp->n_dname, isroot);
        !           500: #endif DEBUG
        !           501: 
        !           502:        /* first do data records */
        !           503:        for (dp = np->n_data; dp != NULL; ) {
        !           504:                /* skip the root SOA record (marks end of data) */
        !           505:                if (isroot && dp->d_type == T_SOA) {
        !           506:                        pdp = dp;
        !           507:                        dp = dp->d_next;
        !           508:                        continue;
        !           509:                 }
        !           510:                dp = rm_datum(dp, np, pdp);
        !           511:        }
        !           512: 
        !           513:        /* next do subdomains */
        !           514:         if (np->n_hash == NULL)
        !           515:                 return;
        !           516:        npp = np->n_hash->h_tab;
        !           517:        nppend = npp + np->n_hash->h_size;
        !           518:        while (npp < nppend) {
        !           519:                for (np = *npp++; np != NULL; np = np->n_next) {
        !           520:                        DelDom(np, 0);
        !           521:                }
        !           522:        }
        !           523: }
        !           524: #endif unused
        !           525: 
        !           526: #ifdef DEBUG
        !           527: printzoneinfo(zonenum)
        !           528: int zonenum;
        !           529: {
        !           530:        struct timeval  tt;
        !           531:        struct zoneinfo *zp = &zones[zonenum];
        !           532:        char *ZoneType;
        !           533: 
        !           534:        if (!debug)
        !           535:                return; /* Else fprintf to ddt will bomb */
        !           536:        fprintf(ddt, "printzoneinfo(%d):\n", zonenum);
        !           537: 
        !           538:        gettime(&tt);
        !           539:        switch (zp->z_type) {
        !           540:                case Z_PRIMARY: ZoneType = "Primary"; break;
        !           541:                case Z_SECONDARY: ZoneType = "Secondary"; break;
        !           542:                case Z_CACHE: ZoneType = "Cache"; break;
        !           543:                default: ZoneType = "Unknown";
        !           544:        }
        !           545:        if (zp->z_origin[0] == '\0')
        !           546:                fprintf(ddt,"origin ='.'");
        !           547:        else
        !           548:                fprintf(ddt,"origin ='%s'", zp->z_origin);
        !           549:        fprintf(ddt,", type = %s", ZoneType);
        !           550:        fprintf(ddt,", source = %s\n", zp->z_source);
        !           551:        fprintf(ddt,"z_refresh = %ld", zp->z_refresh);
        !           552:        fprintf(ddt,", retry = %ld", zp->z_retry);
        !           553:        fprintf(ddt,", expire = %ld", zp->z_expire);
        !           554:        fprintf(ddt,", minimum = %ld", zp->z_minimum);
        !           555:        fprintf(ddt,", serial = %ld\n", zp->z_serial);
        !           556:        fprintf(ddt,"z_time = %d", zp->z_time);
        !           557:        fprintf(ddt,", now time : %d sec", tt.tv_sec);
        !           558:        fprintf(ddt,", time left: %d sec\n", zp->z_time - tt.tv_sec);
        !           559: }
        !           560: #endif DEBUG
        !           561: 
        !           562: /*
        !           563:  * New code added by Rich Wales (UCLA), October 1986:
        !           564:  *
        !           565:  * The following routines manipulate the d_mark field.  When a zone
        !           566:  * is being refreshed, the old RR's are marked.  This allows old RR's to
        !           567:  * be cleaned up after the new copy of the zone has been completely read
        !           568:  * -- or new RR's to be cleaned up if an error prevents transfer of a
        !           569:  * new zone copy.
        !           570:  *
        !           571:  */
        !           572: 
        !           573: /*
        !           574:  *     Set the "d_mark" field to on each RR in the zone "zone".
        !           575:  *     Initially called with "htp" equal to "hashtab", this routine
        !           576:  *     calls itself recursively in order to traverse all subdomains.
        !           577:  */
        !           578: mark_zone (htp, zone, flag)
        !           579:     struct hashbuf *htp;
        !           580:     register int zone;
        !           581:     register int flag;
        !           582: {
        !           583:     register struct databuf *dp;
        !           584:     register struct namebuf *np;
        !           585:     register struct namebuf **npp, **nppend;
        !           586: 
        !           587:     nppend = htp->h_tab + htp->h_size;
        !           588:     for (npp = htp->h_tab; npp < nppend; npp++) {
        !           589:         for (np = *npp; np != NULL; np = np->n_next) {
        !           590:            for (dp = np->n_data; dp != NULL; dp = dp->d_next)
        !           591:                if (dp->d_zone == zone)
        !           592:                    dp->d_mark = flag;
        !           593:            if (np->n_hash != NULL)     /* mark subdomains */
        !           594:                mark_zone (np->n_hash, zone, flag);
        !           595:         }
        !           596:     }
        !           597: }
        !           598: 
        !           599: /*
        !           600:  * clean_zone (htp, zone, flag) --
        !           601:  *     Delete all RR's in the zone "zone" whose "d_mark" values are
        !           602:  *     equal to "flag".  Originally called with "htp" equal to
        !           603:  *     "hashtab", this routine calls itself recursively in order to
        !           604:  *     traverse all subdomains.
        !           605:  */
        !           606: clean_zone (htp, zone, flag)
        !           607:     register struct hashbuf *htp;
        !           608:     register int zone;
        !           609:     register int flag;
        !           610: {
        !           611:     register struct databuf *dp, *pdp;
        !           612:     register struct namebuf *np;
        !           613:     struct namebuf **npp, **nppend;
        !           614: 
        !           615:     nppend = htp->h_tab + htp->h_size;
        !           616:     for (npp = htp->h_tab; npp < nppend; npp++) {
        !           617:        for (np = *npp; np != NULL; np = np->n_next) {
        !           618:            for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
        !           619:                if (dp->d_zone == zone && dp->d_mark == flag)
        !           620:                    dp = rm_datum(dp, np, pdp);
        !           621:                else {
        !           622:                    pdp = dp;
        !           623:                    dp = dp->d_next;
        !           624:                }
        !           625:            }
        !           626:            /* Call recursively to clean up subdomains. */
        !           627:            if (np->n_hash != NULL)
        !           628:                clean_zone (np->n_hash, zone, flag);
        !           629:        }
        !           630:     }
        !           631: }
        !           632: 

unix.superglobalmegacorp.com

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