home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / n / bind / bind-4.001 / bind-4~ / bind-4.9.3-BETA9 / named / ns_init.c < prev    next >
C/C++ Source or Header  |  1994-07-12  |  21KB  |  809 lines

  1. #if !defined(lint) && !defined(SABER)
  2. static char sccsid[] = "@(#)ns_init.c    4.38 (Berkeley) 3/21/91";
  3. static char rcsid[] = "$Id:";
  4. #endif /* not lint */
  5.  
  6. /*
  7.  * ++Copyright++ 1986, 1990
  8.  * -
  9.  * Copyright (c) 1986, 1990
  10.  *    The Regents of the University of California.  All rights reserved.
  11.  * 
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, are permitted provided that the following conditions
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  * 3. All advertising materials mentioning features or use of this software
  21.  *    must display the following acknowledgement:
  22.  *     This product includes software developed by the University of
  23.  *     California, Berkeley and its contributors.
  24.  * 4. Neither the name of the University nor the names of its contributors
  25.  *    may be used to endorse or promote products derived from this software
  26.  *    without specific prior written permission.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  29.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  32.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  37.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  38.  * SUCH DAMAGE.
  39.  * -
  40.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  41.  * 
  42.  * Permission to use, copy, modify, and distribute this software for any
  43.  * purpose with or without fee is hereby granted, provided that the above
  44.  * copyright notice and this permission notice appear in all copies, and that
  45.  * the name of Digital Equipment Corporation not be used in advertising or
  46.  * publicity pertaining to distribution of the document or software without
  47.  * specific, written prior permission.
  48.  * 
  49.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  50.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  51.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  52.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  53.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  54.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  55.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  56.  * SOFTWARE.
  57.  * -
  58.  * --Copyright--
  59.  */
  60.  
  61. #include <sys/param.h>
  62. #include <sys/socket.h>
  63. #include <sys/stat.h>
  64. #include <netinet/in.h>
  65. #include <arpa/nameser.h>
  66. #include <arpa/inet.h>
  67. #include <syslog.h>
  68. #include <signal.h>
  69. #include <resolv.h>
  70. #include <stdio.h>
  71. #include <errno.h>
  72. #include <ctype.h>
  73.  
  74. #include "named.h"
  75.  
  76. #undef nsaddr
  77.  
  78. static void        zoneinit __P((struct zoneinfo *)),
  79.             get_forwarders __P((FILE *)),
  80.             boot_read __P((char *)),
  81. #ifdef DEBUG
  82.             content_zone __P((int)),
  83. #endif
  84.             free_forwarders __P((void));
  85.  
  86. static struct zoneinfo    *find_zone __P((char *, int, int));
  87.  
  88. /*
  89.  * Read boot file for configuration info.
  90.  */
  91. void
  92. ns_init(bootfile)
  93.     char *bootfile;
  94. {
  95.     register struct zoneinfo *zp;
  96.     static int loads = 0;            /* number of times loaded */
  97.  
  98.     dprintf(1, (ddt, "\nns_init(%s)\n", bootfile));
  99.     gettime(&tt);
  100.  
  101.         if (loads == 0) {
  102.         if ((zones =
  103.             (struct zoneinfo *)calloc(64, sizeof(struct zoneinfo)))
  104.                         == NULL) {
  105.             syslog(LOG_ERR,
  106.             "Not enough memory to allocate initial zones array");
  107.             exit(1);
  108.         }
  109.         nzones = 1;        /* zone zero is cache data */
  110.         /* allocate cache hash table, formerly the root hash table. */
  111.         hashtab = savehash((struct hashbuf *)NULL);
  112.  
  113.         /* allocate root-hints/file-cache hash table */
  114.         fcachetab = savehash((struct hashbuf *)NULL);
  115.         /* init zone data */
  116.         zones[0].z_type = Z_CACHE;
  117.         } else {
  118.         /* Mark previous zones as not yet found in boot file. */
  119.         for (zp = &zones[1]; zp < &zones[nzones]; zp++)
  120.             zp->z_flags &= ~Z_FOUND;
  121. #ifdef LOCALDOM
  122.         if (localdomain) {
  123.             free(localdomain);
  124.             localdomain = NULL;
  125.         }
  126. #endif
  127.         free_forwarders();
  128.         free_netlist(enettab);
  129. #ifdef XFRNETS
  130.         free_netlist(&xfrnets);
  131. #endif
  132. #ifdef BOGUSNS
  133.         free_netlist(&boglist);
  134. #endif
  135.         forward_only = 0;
  136.     }
  137.  
  138.     dprintf(3, (ddt, "\n content of zones before loading \n"));
  139. #ifdef DEBUG
  140.         if (debug >= 3) {
  141.             content_zone(nzones - 1);
  142.         }
  143. #endif
  144.     boot_read(bootfile);
  145.  
  146.         /* erase all old zones that were not found */
  147.         for (zp = &zones[1]; zp < &zones[nzones]; zp++) {
  148.             if (zp->z_type && (zp->z_flags & Z_FOUND) == 0) {
  149. #ifdef CLEANCACHE
  150.         remove_zone(hashtab, zp - zones, 1);
  151. #else
  152.         remove_zone(hashtab, zp - zones);
  153. #endif
  154. #ifdef SECURE_ZONES
  155.         free_netlist(&zp->secure_nets);
  156. #endif
  157.         syslog(LOG_NOTICE, "Zone \"%s\" was removed", zp->z_origin);
  158.         free(zp->z_origin);
  159.         free(zp->z_source);
  160.         bzero((char *) zp, sizeof(*zp));
  161.         }
  162.         }
  163.     dprintf(2, (ddt,"\n content of zones after loading\n"));
  164.  
  165. #ifdef DEBUG
  166.     if (debug >= 2) {
  167.             content_zone(nzones-1);
  168.         }
  169. #endif
  170.  
  171.     /*
  172.      * Schedule calls to ns_maint().
  173.      */
  174.     if (!needmaint)
  175.         sched_maint();
  176.     dprintf(1, (ddt, "exit ns_init()%s\n",
  177.             needmaint ? ", need maintenance immediately" : ""));
  178.     loads++;
  179. }
  180.  
  181. /*
  182.  * Read the actual boot file.
  183.  * Set up to recurse.
  184.  */
  185. static void
  186. boot_read(bootfile)
  187.     char *bootfile;
  188. {
  189.     register struct zoneinfo *zp;
  190.     char buf[BUFSIZ], obuf[BUFSIZ], *source;
  191.     FILE *fp;
  192.     int type;
  193.     int class;
  194. #ifdef GEN_AXFR
  195.     char *class_p;
  196. #endif
  197.     struct stat f_time;
  198.     static int tmpnum = 0;        /* unique number for tmp zone files */
  199. #ifdef ALLOW_UPDATES
  200.     char *cp, *flag;
  201. #endif
  202.     int slineno;            /* Saved global line number. */
  203.     int i;
  204.  
  205.     if ((fp = fopen(bootfile, "r")) == NULL) {
  206.         syslog(LOG_ERR, "%s: %m", bootfile);
  207.         exit(1);
  208.     }
  209.  
  210.     slineno = lineno;
  211.     lineno = 0;
  212.  
  213.     while (!feof(fp) && !ferror(fp)) {
  214.         if (!getword(buf, sizeof(buf), fp))
  215.             continue;
  216.         /* read named.boot keyword and process args */
  217.         if (strcasecmp(buf, "directory") == 0) {
  218.             (void) getword(buf, sizeof(buf), fp);
  219.             if (chdir(buf) < 0) {
  220.                 syslog(LOG_CRIT, "directory %s: %m\n",
  221.                     buf);
  222.                 exit(1);
  223.             }
  224.             continue;
  225.         } else if (strcasecmp(buf, "sortlist") == 0) {
  226.             get_netlist(fp, enettab, ALLOW_NETS, buf);
  227.             continue;
  228.         } else if (strcasecmp(buf, "max-fetch") == 0) {
  229.             max_xfers_running = getnum(fp, bootfile, 0);
  230.             continue;
  231.         } else if (strcasecmp(buf, "forwarders") == 0) {
  232.             get_forwarders(fp);
  233.             continue;
  234.         } else if (strcasecmp(buf, "slave") == 0) {
  235.             forward_only++;
  236.             endline(fp);
  237.             continue;
  238. #ifdef BOGUSNS
  239.         } else if (strcasecmp(buf, "bogusns") == 0) {
  240.             get_netlist(fp, &boglist, ALLOW_HOSTS, buf);
  241.             continue;
  242. #endif
  243. #ifdef XFRNETS
  244.         } else if ((strcasecmp(buf, "tcplist") == 0) ||
  245.                (strcasecmp(buf, "xfrnets") == 0)) {
  246.             get_netlist(fp, &xfrnets, ALLOW_NETS, buf);
  247.             continue;
  248. #endif
  249. #ifdef LOCALDOM
  250.         } else if (strcasecmp(buf, "domain") == 0) {
  251.             if (getword(buf, sizeof(buf), fp))
  252.                 localdomain = savestr(buf);
  253.             endline(fp);
  254.             continue;
  255. #endif
  256.         } else if (strcasecmp(buf, "include") == 0) {
  257.             if (getword(buf, sizeof(buf), fp))
  258.                 boot_read(buf);
  259.             endline(fp);
  260.             continue;
  261.         } else if (strncasecmp(buf, "cache", 5) == 0) {
  262.             type = Z_CACHE;
  263.             class = C_IN;
  264. #ifdef GEN_AXFR
  265.             if (class_p = strchr(buf, '/'))
  266.                 class = get_class(class_p+1);
  267. #endif
  268.         } else if (strncasecmp(buf, "primary", 7) == 0) {
  269.             type = Z_PRIMARY;
  270.             class = C_IN;
  271. #ifdef GEN_AXFR
  272.             if (class_p = strchr(buf, '/'))
  273.                 class = get_class(class_p+1);
  274. #endif
  275.         } else if (strncasecmp(buf, "secondary", 9) == 0) {
  276.             type = Z_SECONDARY;
  277.             class = C_IN;
  278. #ifdef GEN_AXFR
  279.             if (class_p = strchr(buf, '/'))
  280.                 class = get_class(class_p+1);
  281. #endif
  282. #ifdef STUBS
  283.         } else if (strncasecmp(buf, "stub", 4) == 0) {
  284.             type = Z_STUB;
  285.             class = C_IN;
  286. #ifdef GEN_AXFR
  287.             if (class_p = strchr(buf, '/'))
  288.                 class = get_class(class_p+1);
  289. #endif
  290. #endif
  291.         } else {
  292.             syslog(LOG_ERR, "%s: line %d: unknown field '%s'\n",
  293.                 bootfile, lineno+1, buf);
  294.             endline(fp);
  295.             continue;
  296.         }
  297.  
  298.         /*
  299.          * read zone origin
  300.          */
  301.         if (!getword(obuf, sizeof(obuf), fp)) {
  302.             syslog(LOG_ERR, "%s: line %d: missing origin\n",
  303.                 bootfile, lineno);
  304.             continue;
  305.         }
  306.         i = strlen(obuf);
  307.         if ((obuf[i-1] == '.') && (i != 1))
  308.             syslog(LOG_ERR, "%s: line %d: zone \"%s\" has trailing dot\n",
  309.                 bootfile, lineno, obuf);
  310.         while ((--i >= 0) && (obuf[i] == '.'))
  311.             obuf[i] = '\0';
  312.         dprintf(1, (ddt, "zone origin %s", obuf[0]?obuf:"."));
  313.         /*
  314.          * read source file or host address
  315.          */
  316.         if (!getword(buf, sizeof(buf), fp)) {
  317.             syslog(LOG_ERR, "%s: line %d: missing %s\n",
  318.                 bootfile, lineno, 
  319. #ifdef STUBS
  320.                (type == Z_SECONDARY || type == Z_STUB)
  321. #else
  322.                (type == Z_SECONDARY)
  323. #endif
  324.                    ?"host address"
  325.                    :"source file");
  326.             continue;
  327.         }
  328.  
  329.         /* check for previous instance of this zone (reload) */
  330.         if (!(zp = find_zone(obuf, type, class))) {
  331.             if (type == Z_CACHE) {
  332.                 zp = &zones[0];
  333.                 zp->z_origin = "";
  334.                 goto gotcache;
  335.             }
  336.             for (zp = &zones[1]; zp < &zones[nzones]; zp++)
  337.                 if (zp->z_type == Z_NIL)
  338.                     goto gotzone;
  339.             /*
  340.              * this code assumes that nzones never decreases
  341.              */
  342.             if (nzones % 64 == 0) {
  343.                 dprintf(1, (ddt,
  344.                     "Reallocating zones structure\n"));
  345.                 /*
  346.                  * Realloc() not used since it might damage zones
  347.                  * if an error occurs
  348.                  */
  349.                 zp = (struct zoneinfo *)
  350.                 malloc((64 + nzones)
  351.                        * sizeof(struct zoneinfo));
  352.                 if (zp == (struct zoneinfo *)0) {
  353.                     syslog(LOG_ERR,
  354.                        "no memory for more zones");
  355.                     dprintf(1, (ddt,
  356.                         "Out of memory for new zones\n"
  357.                         )
  358.                         );
  359.                     endline(fp);
  360.                     continue;
  361.                 }
  362.                 bcopy((char *)zones, (char *)zp,
  363.                   nzones * sizeof(struct zoneinfo));
  364.                 bzero((char *)&zp[nzones],
  365.                   64 * sizeof(struct zoneinfo));
  366.                 free(zones);
  367.                 zones = zp;
  368.             }
  369.             zp = &zones[nzones++];
  370.     gotzone:
  371.             zp->z_origin = savestr(obuf);
  372.     gotcache:
  373.             zp->z_type = type;
  374.             zp->z_class = class;
  375.         }
  376.         zp->z_addrcnt = 0;
  377.  
  378.         switch (type) {
  379.         case Z_CACHE:
  380.             source = savestr(buf);
  381.             dprintf(1, (ddt, ", source = %s\n", source));
  382.             zp->z_refresh = 0;    /* by default, no dumping */
  383.             if (getword(buf, sizeof(buf), fp)) {
  384. #ifdef notyet
  385.                 zp->z_refresh = atoi(buf);
  386.                 if (zp->z_refresh <= 0) {
  387.                     syslog(LOG_ERR,
  388.                 "%s: line %d: bad refresh time '%s', ignored\n",
  389.                         bootfile, lineno, buf);
  390.                     zp->z_refresh = 0;
  391.                 } else if (cache_file == NULL)
  392.                     cache_file = source;
  393. #else
  394.                 syslog(LOG_WARNING,
  395.                 "%s: line %d: cache refresh ignored\n",
  396.                     bootfile, lineno);
  397. #endif
  398.                 endline(fp);
  399.             }
  400.             /*
  401.              * If we've loaded this file, and the file has
  402.              * not been modified and contains no $include,
  403.              * then there's no need to reload.
  404.              */
  405.             if (zp->z_source &&
  406.                 !strcmp(source, zp->z_source) &&
  407.                 !(zp->z_flags & Z_INCLUDE) && 
  408.                 stat(zp->z_source, &f_time) != -1 &&
  409.                 zp->z_ftime == f_time.st_mtime) {
  410.                 dprintf(1, (ddt, "cache is up to date\n"));
  411.                 if (source != cache_file)
  412.                     free(source);
  413.                 break; /* zone is already up to date */
  414.             }
  415.  
  416.             /* file has changed, or hasn't been loaded yet */
  417.             if (zp->z_source) {
  418.                 free(zp->z_source);
  419. #ifdef CLEANCACHE
  420.                 remove_zone(fcachetab, 0, 1);
  421. #else
  422.                 remove_zone(fcachetab, 0);
  423. #endif
  424.             }
  425.             zp->z_source = source;
  426.             dprintf(1, (ddt, "reloading zone\n"));
  427.             (void) db_load(zp->z_source, zp->z_origin, zp, 0);
  428.             break;
  429.  
  430.         case Z_PRIMARY:
  431.             source = savestr(buf);
  432. #ifdef ALLOW_UPDATES
  433.             if (getword(buf, sizeof(buf), fp)) {
  434.                 endline(fp);
  435.                 flag = buf;
  436.                 while (flag) {
  437.                     cp = strchr(flag, ',');
  438.                     if (cp)
  439.                     *cp++ = 0;
  440.                     if (strcasecmp(flag, "dynamic") == 0)
  441.                     zp->z_flags |= Z_DYNAMIC;
  442.                     else if (strcasecmp(flag, "addonly") == 0)
  443.                     zp->z_flags |= Z_DYNADDONLY;
  444.                     else {
  445.                     syslog(LOG_ERR,
  446.                            "%s: line %d: bad flag '%s'\n",
  447.                            bootfile, lineno, flag);
  448.                     }
  449.                     flag = cp;
  450.                 }
  451.             }
  452. #else /*ALLOW_UPDATES*/
  453.                     endline(fp);
  454. #endif
  455.  
  456.             dprintf(1, (ddt, ", source = %s\n", source));
  457.             /*
  458.              * If we've loaded this file, and the file has
  459.              * not been modified and contains no $include,
  460.              * then there's no need to reload.
  461.              */
  462.             if (zp->z_source &&
  463.                 !strcmp(source, zp->z_source) &&
  464.                 !(zp->z_flags & Z_INCLUDE) && 
  465.                 stat(zp->z_source, &f_time) != -1 &&
  466.                 zp->z_ftime == f_time.st_mtime) {
  467.                 dprintf(1, (ddt, "zone is up to date\n"));
  468.                 free(source);
  469.                 break; /* zone is already up to date */
  470.             }
  471.             if (zp->z_source) {
  472.                 free(zp->z_source);
  473. #ifdef CLEANCACHE
  474.                 remove_zone(hashtab, zp - zones, 1);
  475. #else
  476.                 remove_zone(hashtab, zp - zones);
  477. #endif
  478.             }
  479.                         zp->z_source = source;
  480.             zp->z_flags &= ~Z_AUTH;
  481.             dprintf(1, (ddt, "reloading zone\n"));
  482.             if (db_load(zp->z_source, zp->z_origin, zp, 0) == 0)
  483.                 zp->z_flags |= Z_AUTH;
  484. #ifdef ALLOW_UPDATES
  485.             /* Guarantee calls to ns_maint() */
  486.             zp->z_refresh = maint_interval;
  487. #else
  488.             zp->z_refresh = 0;    /* no maintenance needed */
  489.             zp->z_time = 0;
  490. #endif
  491.             break;
  492.  
  493.         case Z_SECONDARY:
  494. #ifdef STUBS
  495.         case Z_STUB:
  496. #endif
  497.             source = NULL;
  498.             dprintf(1, (ddt, "\n\taddrs: "));
  499.             do {
  500.                 if (!inet_aton(buf,
  501.                            &zp->z_addr[zp->z_addrcnt])
  502.                     ) {
  503.                     source = savestr(buf);
  504.                                     endline(fp);
  505.                     break;
  506.                 }
  507.                 dprintf(1, (ddt, "%s, ", buf));
  508.                 if ((int)++zp->z_addrcnt > NSMAX - 1) {
  509.                     zp->z_addrcnt = NSMAX - 1;
  510.                     dprintf(1, (ddt,
  511.                             "\nns.h NSMAX reached\n"));
  512.                 }
  513.             } while (getword(buf, sizeof(buf), fp));
  514.             dprintf(1, (ddt, "addrcnt = %d\n", zp->z_addrcnt));
  515.             if (!source) {
  516.                 /*
  517.                  * We will always transfer this zone again
  518.                  * after a reload.
  519.                  */
  520.                 sprintf(buf, "/%s/NsTmp%d.%d", _PATH_TMPDIR,
  521.                     getpid(), tmpnum++);
  522.                 source = savestr(buf);
  523.                 zp->z_flags |= Z_TMP_FILE;
  524.             } else
  525.                 zp->z_flags &= ~Z_TMP_FILE;
  526.             /*
  527.              * If we had a backup file name, and it was changed,
  528.              * free old zone and start over.  If we don't have
  529.              * current zone contents, try again now in case
  530.              * we have a new server on the list.
  531.              */
  532.             if (zp->z_source &&
  533.                 (strcmp(source, zp->z_source) ||
  534.                  (stat(zp->z_source, &f_time) == -1 ||
  535.                  (zp->z_ftime != f_time.st_mtime)))) {
  536.                 dprintf(1, (ddt, "backup file changed\n"));
  537.                 free(zp->z_source);
  538.                 zp->z_source = NULL;
  539.                 zp->z_flags &= ~Z_AUTH;
  540.                 zp->z_serial = 0;    /* force xfer */
  541. #ifdef    CLEANCACHE
  542.                             remove_zone(hashtab, zp - zones, 1);
  543. #else
  544.                             remove_zone(hashtab, zp - zones);
  545. #endif
  546.             }
  547.             if (zp->z_source)
  548.                 free(source);
  549.             else
  550.                 zp->z_source = source;
  551.             if (!(zp->z_flags & Z_AUTH))
  552.                 zoneinit(zp);
  553. #ifdef FORCED_RELOAD
  554.             else {
  555.                 /* 
  556.                 ** Force secondary to try transfer right away 
  557.                 ** after SIGHUP.
  558.                 */
  559.                 if (reloading) {
  560.                     zp->z_time = tt.tv_sec;
  561.                     needmaint = 1;
  562.                 }
  563.             }
  564. #endif /* FORCED_RELOAD */
  565.             break;
  566.  
  567.         }
  568.                 zp->z_flags |= Z_FOUND;
  569.         dprintf(1, (ddt, "zone[%d] type %d: '%s'",
  570.                 zp-zones, type,
  571.                 *(zp->z_origin) == '\0' ? "." : zp->z_origin));
  572.         if (zp->z_refresh && zp->z_time == 0)
  573.             zp->z_time = zp->z_refresh + tt.tv_sec;
  574.         if (zp->z_time <= tt.tv_sec)
  575.             needmaint = 1;
  576.         dprintf(1, (ddt, " z_time %d, z_refresh %d\n",
  577.                 zp->z_time, zp->z_refresh));
  578.     }
  579.     (void) my_fclose(fp);
  580.     lineno = slineno;
  581. }
  582.  
  583. static void
  584. zoneinit(zp)
  585.     register struct zoneinfo *zp;
  586. {
  587.     struct stat sb;
  588.  
  589.     /*
  590.      * Try to load zone from backup file,
  591.      * if one was specified and it exists.
  592.      * If not, or if the data are out of date,
  593.      * we will refresh the zone from a primary
  594.      * immediately.
  595.      */
  596.     if (!zp->z_source)
  597.         return;
  598.     if (stat(zp->z_source, &sb) == -1 ||
  599.         db_load(zp->z_source, zp->z_origin, zp, 0) != 0) {
  600.         /*
  601.          * Set zone to be refreshed immediately.
  602.          */
  603.         zp->z_refresh = INIT_REFRESH;
  604.         zp->z_retry = INIT_REFRESH;
  605.         zp->z_time = tt.tv_sec;
  606.         needmaint = 1;
  607.     } else {
  608.         zp->z_flags |= Z_AUTH;
  609.     }
  610. }
  611.  
  612. #ifdef ALLOW_UPDATES
  613. /*
  614.  * Look for the authoritative zone with the longest matching RHS of dname
  615.  * and return its zone # or zero if not found.
  616.  */
  617. int
  618. findzone(dname, class)
  619.     char *dname;
  620.     int class;
  621. {
  622.     char *dZoneName, *zoneName;
  623.     int dZoneNameLen, zoneNameLen;
  624.     int maxMatchLen = 0;
  625.     int maxMatchZoneNum = 0;
  626.     int zoneNum;
  627.  
  628.     dprintf(4, (ddt, "findzone(dname=%s, class=%d)\n", dname, class));
  629. #ifdef DEBUG
  630.     if (debug >= 5) {
  631.         fprintf(ddt, "zone dump:\n");
  632.         for (zoneNum = 1; zoneNum < nzones; zoneNum++)
  633.             printzoneinfo(zoneNum);
  634.     }
  635. #endif
  636.  
  637.     dZoneName = strchr(dname, '.');
  638.     if (dZoneName == NULL)
  639.         dZoneName = "";    /* root */
  640.     else
  641.         dZoneName++;    /* There is a '.' in dname, so use remainder of
  642.                    string as the zone name */
  643.     dZoneNameLen = strlen(dZoneName);
  644.     for (zoneNum = 1; zoneNum < nzones; zoneNum++) {
  645.         zoneName = (zones[zoneNum]).z_origin;
  646.         zoneNameLen = strlen(zoneName);
  647.         /* The zone name may or may not end with a '.' */
  648.         if (zoneName[zoneNameLen - 1] == '.')
  649.             zoneNameLen--;
  650.         if (dZoneNameLen != zoneNameLen)
  651.             continue;
  652.         dprintf(5, (ddt, "about to strncasecmp('%s', '%s', %d)\n",
  653.                 dZoneName, zoneName, dZoneNameLen));
  654.         if (strncasecmp(dZoneName, zoneName, dZoneNameLen) == 0) {
  655.             dprintf(5, (ddt, "match\n"));
  656.             /*
  657.              * See if this is as long a match as any so far.
  658.              * Check if "<=" instead of just "<" so that if
  659.              * root domain (whose name length is 0) matches,
  660.              * we use it's zone number instead of just 0
  661.              */
  662.             if (maxMatchLen <= zoneNameLen) {
  663.                 maxMatchZoneNum = zoneNum;
  664.                 maxMatchLen = zoneNameLen;
  665.             }
  666.         } else {
  667.             dprintf(5, (ddt, "no match\n"));
  668.         }
  669.     }
  670.     dprintf(4, (ddt, "findzone: returning %d\n", maxMatchZoneNum));
  671.     return (maxMatchZoneNum);
  672. }
  673. #endif /* ALLOW_UPDATES */
  674.  
  675. static void
  676. get_forwarders(fp)
  677.     FILE *fp;
  678. {
  679.     char buf[BUFSIZ];
  680.     register struct fwdinfo *fip = NULL, *ftp = NULL;
  681.  
  682. #ifdef SLAVE_FORWARD
  683.     int forward_count = 0;
  684. #endif
  685.  
  686.     dprintf(1, (ddt, "forwarders "));
  687.  
  688.     /* on mulitple forwarder lines, move to end of the list */
  689. #ifdef SLAVE_FORWARD
  690.     if (fwdtab != NULL){
  691.         forward_count++;
  692.         for (fip = fwdtab; fip->next != NULL; fip = fip->next)
  693.             forward_count++;
  694.     }
  695. #else
  696.     if (fwdtab != NULL) {
  697.         for (fip = fwdtab; fip->next != NULL; fip = fip->next) {
  698.             ;
  699.         }
  700.     }
  701. #endif /* SLAVE_FORWARD */
  702.  
  703.     while (getword(buf, sizeof(buf), fp)) {
  704.         if (strlen(buf) == 0)
  705.             break;
  706.         dprintf(1, (ddt," %s",buf));
  707.         if (ftp == NULL)
  708.             ftp = (struct fwdinfo *)malloc(sizeof(struct fwdinfo));
  709.         if (inet_aton(buf, &ftp->fwdaddr.sin_addr)) {
  710.             ftp->fwdaddr.sin_port = ns_port;
  711.             ftp->fwdaddr.sin_family = AF_INET;
  712.         } else {
  713.             syslog(LOG_ERR, "'%s' (ignored, NOT dotted quad)",
  714.                    buf);
  715.             dprintf(1, (ddt, " (ignored, NOT dotted quad)"));
  716.             continue;    
  717.         }
  718. #ifdef FWD_LOOP
  719.         if (aIsUs(ftp->fwdaddr.sin_addr)) {
  720.             syslog(LOG_ERR,
  721.                    "Forwarder '%s' ignored, my address",
  722.                    buf);
  723.             dprintf(1, (ddt, " (ignored, my address)"));
  724.             continue;
  725.         }
  726. #endif /* FWD_LOOP */
  727.         ftp->next = NULL;
  728.         if (fwdtab == NULL)
  729.             fwdtab = ftp;    /* First time only */
  730.         else
  731.             fip->next = ftp;
  732.         fip = ftp;
  733.         ftp = NULL;
  734. #ifdef SLAVE_FORWARD
  735.         forward_count++;
  736. #endif /* SLAVE_FORWARD */
  737.     }
  738.     if (ftp)
  739.         free((char *)ftp);
  740.     
  741. #ifdef SLAVE_FORWARD
  742.     /*
  743.     ** Set the slave retry time to 60 seconds total divided
  744.     ** between each forwarder
  745.     */
  746.     if (forward_count != 0) {
  747.         slave_retry = (int) (60 / forward_count);
  748.         if(slave_retry <= 0)
  749.             slave_retry = 1;
  750.     }
  751. #endif
  752.  
  753.     dprintf(1, (ddt, "\n"));
  754. #ifdef DEBUG
  755.     if (debug > 2) {
  756.         for (ftp = fwdtab; ftp != NULL; ftp = ftp->next) {
  757.             fprintf(ddt,"ftp x%x [%s] next x%x\n",
  758.                 ftp,
  759.                 inet_ntoa(ftp->fwdaddr.sin_addr),
  760.                 ftp->next);
  761.         }
  762.     }
  763. #endif
  764. }
  765.  
  766. static void
  767. free_forwarders()
  768. {
  769.     register struct fwdinfo *ftp, *fnext;
  770.  
  771.     for (ftp = fwdtab; ftp != NULL; ftp = fnext) {
  772.         fnext = ftp->next;
  773.         free((char *)ftp);
  774.     }
  775.     fwdtab = NULL;
  776. }
  777.  
  778. static struct zoneinfo *
  779. find_zone(name, type, class) 
  780.     char *name;
  781.     int type, class;
  782. {
  783.     register struct zoneinfo *zp;
  784.  
  785.         for (zp = &zones[1]; zp < &zones[nzones]; zp++) {
  786.         if (zp->z_type == type && zp->z_class == class &&
  787.             strcasecmp(name, zp->z_origin) == 0) {
  788.             dprintf(2, (ddt, ", old zone (%d)", zp - zones));
  789.             return (zp);
  790.         }
  791.     }
  792.     dprintf(2, (ddt, ", new zone"));
  793.     return NULL;
  794. }
  795.  
  796. #ifdef DEBUG
  797. /* prints out the content of zones */
  798. static void
  799. content_zone(end) 
  800.     int end;
  801. {
  802.     int i;
  803.  
  804.     for (i = 1;  i <= end;  i++) {
  805.         printzoneinfo(i);
  806.     }
  807. }
  808. #endif
  809.