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

1.1       root        1: /*
                      2:  * Copyright (c) 1986 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: static char sccsid[] = "@(#)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.