# 2.11BSD#431 - /usr/src/usr.sbin/named/named/ns_maint.c

##### Functions

    clean_zone        X
    mark_zone         X
    ns_maint          X
    printzoneinfo     X
    zoneref           X

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

#### Defined functions

DelDom defined in line 484; used 1 times

- in line 515

clean_zone defined in line 601; used 4 times

- in line 298, 446, 452, 623

mark_zone defined in line 573; used 3 times

- in line 293, 453, 589

ns_maint defined in line 42; used 1 times

- in /usr/src/usr.sbin/named/named/ns_main.c line 620

printzoneinfo defined in line 522; used 2 times

- in line 69
- in /usr/src/usr.sbin/named/named/ns_init.c line 345

zoneref defined in line 112; used 1 times

- in line 75

#### Defined variables

sccsid defined in line 14; never used

Last modified: 1988-09-05 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2678 |