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 / db_load.c < prev    next >
C/C++ Source or Header  |  1994-07-23  |  28KB  |  1,215 lines

  1. #if !defined(lint) && !defined(SABER)
  2. static char sccsid[] = "@(#)db_load.c    4.38 (Berkeley) 3/2/91";
  3. static char rcsid[] = "$Id: db_load.c,v 4.9.1.18 1994/07/23 23:23:56 vixie Exp $";
  4. #endif /* not lint */
  5.  
  6. /*
  7.  * ++Copyright++ 1986, 1988, 1990
  8.  * -
  9.  * Copyright (c) 1986, 1988, 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. /*
  62.  * Load data base from ascii backupfile.  Format similar to RFC 883.
  63.  */
  64.  
  65. #include <sys/param.h>
  66. #include <sys/stat.h>
  67. #include <netinet/in.h>
  68. #include <arpa/nameser.h>
  69. #include <arpa/inet.h>
  70. #include <stdio.h>
  71. #include <syslog.h>
  72. #include <ctype.h>
  73. #include <netdb.h>
  74.  
  75. #include "named.h"
  76.  
  77. static int        gettoken __P((register FILE *, char *)),
  78.             getnonblank __P((FILE *, char *)),
  79.             getprotocol __P((FILE *, char *)),
  80.             getservices __P((int, char *, FILE *, char *));
  81. static void        makename __P((char *, char *));
  82. static int        empty_token = 0;
  83.  
  84. /*
  85.  * Map class and type names to number
  86.  */
  87. struct map {
  88.     char    token[8];
  89.     int    val;
  90. };
  91.  
  92. struct map m_class[] = {
  93.     "in",        C_IN,
  94. #ifdef notdef
  95.     "any",        C_ANY,        /* any is a QCLASS, not CLASS */
  96. #endif
  97.     "chaos",    C_CHAOS,
  98.     "hs",        C_HS,
  99. };
  100. #define NCLASS (sizeof(m_class) / sizeof(struct map))
  101.  
  102. struct map m_type[] = {
  103.     "a",        T_A,
  104.     "ns",        T_NS,
  105.     "cname",    T_CNAME,
  106.     "soa",        T_SOA,
  107.     "mb",        T_MB,
  108.     "mg",        T_MG,
  109.     "mr",        T_MR,
  110.     "null",        T_NULL,
  111.     "wks",        T_WKS,
  112.     "ptr",        T_PTR,
  113.     "hinfo",    T_HINFO,
  114.     "minfo",    T_MINFO,
  115.     "mx",        T_MX,
  116.     "uinfo",    T_UINFO,
  117.     "txt",        T_TXT,
  118.     "rp",        T_RP,
  119.     "afsdb",    T_AFSDB,
  120.     "x25",        T_X25,
  121.     "isdn",        T_ISDN,
  122.     "rt",        T_RT,
  123.     "nsap",        T_NSAP,
  124.     "uid",        T_UID,
  125.     "gid",        T_GID,
  126. #ifdef notdef
  127.     "any",        T_ANY,        /* any is a QTYPE, not TYPE */
  128. #endif
  129. #ifdef ALLOW_T_UNSPEC
  130.         "unspec",       T_UNSPEC,
  131. #endif /* ALLOW_T_UNSPEC */
  132. };
  133. #define NTYPE (sizeof(m_type) / sizeof(struct map))
  134.  
  135. /*
  136.  * Parser token values
  137.  */
  138. #define CURRENT    1
  139. #define DOT    2
  140. #define AT    3
  141. #define DNAME    4
  142. #define INCLUDE    5
  143. #define ORIGIN    6
  144. #define ERROR    7
  145.  
  146. static int clev;    /* a zone deeper in a heirachy has more credability */
  147.  
  148. /* int
  149.  * db_load(filename, in_origin, zp, doinginclude)
  150.  *    load a database from `filename' into zone `zp'.  append `origin'
  151.  *    to all nonterminal domain names in the file.  `doinginclude' is
  152.  *    true if this is a $INCLUDE file.
  153.  * returns:
  154.  *    -1 = can't open file
  155.  *    0 = success
  156.  *    >0 = number of errors encountered
  157.  */
  158. int
  159. db_load(filename, in_origin, zp, doinginclude)
  160.     char *filename, *in_origin;
  161.     struct zoneinfo *zp;
  162.     int doinginclude;
  163. {
  164.     register char *cp;
  165.     register struct map *mp;
  166.     char domain[MAXDNAME];
  167.     char origin[MAXDNAME];
  168.     char tmporigin[MAXDNAME];
  169.     char buf[MAXDATA];
  170.     char data[MAXDATA];
  171.     char *cp1;
  172.     char *op;
  173.     int c, class, type, ttl, dbflags, dataflags, multiline;
  174.     static int read_soa;    /* number of soa's read */
  175.     struct databuf *dp;
  176.     FILE *fp;
  177.     int slineno, i, errs = 0, didinclude = 0;
  178.     register u_int32_t n;
  179.     struct stat sb;
  180.     struct in_addr ina;
  181.  
  182.     if (!doinginclude) {
  183.         read_soa = 0;
  184.         clev = db_getclev(in_origin);
  185.     }
  186.  
  187.     dprintf(1, (ddt,"db_load(%s, %s, %d, %d)\n",
  188.             filename, in_origin, zp - zones, doinginclude));
  189.  
  190.     (void) strcpy(origin, in_origin);
  191.     if ((fp = fopen(filename, "r")) == NULL) {
  192.         syslog(LOG_ERR, "%s: %m", filename);
  193.         dprintf(1, (ddt, "db_load: error opening file %s\n",
  194.                 filename));
  195.         return (-1);
  196.     }
  197.     if (zp->z_type == Z_CACHE) {
  198.         dbflags = DB_NODATA | DB_NOHINTS;
  199.         dataflags = DB_F_HINT;
  200.     } else {
  201.         dbflags = DB_NODATA;
  202.         dataflags = 0;
  203.     }
  204.     gettime(&tt);
  205.     if (fstat(fileno(fp), &sb) < 0) {
  206.         syslog(LOG_ERR, "%s: %m", filename);
  207.         sb.st_mtime = (int)tt.tv_sec;
  208.     }
  209.     slineno = lineno;
  210.     lineno = 1;
  211.     domain[0] = '\0';
  212.     class = zp->z_class;
  213.     zp->z_flags &= ~(Z_INCLUDE|Z_DB_BAD);
  214.      while ((c = gettoken(fp, filename)) != EOF) {
  215.         switch (c) {
  216.         case INCLUDE:
  217.             if (!getword((char *)buf, sizeof(buf), fp))
  218.                 /* file name*/
  219.                 break;
  220.             if (!getword(tmporigin, sizeof(tmporigin), fp))
  221.                 strcpy(tmporigin, origin);
  222.             else {
  223.                 makename(tmporigin, origin);
  224.                 endline(fp);
  225.             }
  226.             didinclude = 1;
  227.             errs += db_load((char *)buf, tmporigin, zp, 1);
  228.             continue;
  229.  
  230.         case ORIGIN:
  231.             (void) strcpy((char *)buf, origin);
  232.             if (!getword(origin, sizeof(origin), fp))
  233.                 break;
  234.             dprintf(3, (ddt, "db_load: origin %s, buf %s\n",
  235.                     origin, buf));
  236.             makename(origin, buf);
  237.             dprintf(3, (ddt, "db_load: origin now %s\n", origin));
  238.             continue;
  239.  
  240.         case DNAME:
  241.             if (!getword(domain, sizeof(domain), fp))
  242.                 break;
  243.             n = strlen(domain) - 1;
  244.             if (domain[n] == '.')
  245.                 domain[n] = '\0';
  246.             else if (*origin) {
  247.                 (void) strcat(domain, ".");
  248.                 (void) strcat(domain, origin);
  249.             }
  250.             goto gotdomain;
  251.  
  252.         case AT:
  253.             (void) strcpy(domain, origin);
  254.             goto gotdomain;
  255.  
  256.         case DOT:
  257.             domain[0] = '\0';
  258.             /* fall thru ... */
  259.         case CURRENT:
  260.         gotdomain:
  261.             if (!getword((char *)buf, sizeof(buf), fp)) {
  262.                 if (c == CURRENT)
  263.                     continue;
  264.                 break;
  265.             }
  266.             cp = buf;
  267.             ttl = 0;
  268.             if (isdigit(*cp)) {
  269.                 n = 0;
  270.                 do {
  271.                     if (n > (INT_MAX - (*cp - '0')) / 10) {
  272.                     syslog(LOG_ERR, 
  273.                        "%s: line %d: number > %lu\n",
  274.                        filename, lineno, INT_MAX);
  275.                     dprintf(1, (ddt,
  276.                         "%s: line %d: number > %lu\n",
  277.                         filename, lineno, INT_MAX));
  278.                     n = INT_MAX;
  279.                     cp++;
  280.                     } else
  281.                       n = n * 10 + (*cp++ - '0');
  282.                 }
  283.                 while (isdigit(*cp));
  284.                 if (zp->z_type == Z_CACHE) {
  285.                     /* this allows the cache entry to age */
  286.                     /* while sitting on disk (powered off) */
  287.                     if (n > max_cache_ttl)
  288.                     n = max_cache_ttl;
  289.                     n += sb.st_mtime;
  290.                 }
  291.                 ttl = n;
  292.                 if (!getword((char *)buf, sizeof(buf), fp))
  293.                     break;
  294.             }
  295.             for (mp = m_class; mp < m_class+NCLASS; mp++)
  296.                 if (!strcasecmp((char *)buf, mp->token)) {
  297.                     class = mp->val;
  298.                     (void) getword((char *)buf,
  299.                                sizeof(buf), fp);
  300.                     break;
  301.                 }
  302.             for (mp = m_type; mp < m_type+NTYPE; mp++)
  303.                 if (!strcasecmp((char *)buf, mp->token)) {
  304.                     type = mp->val;
  305.                     goto fndtype;
  306.                 }
  307.             dprintf(1, (ddt, "%s: Line %d: Unknown type: %s.\n",
  308.                     filename, lineno, buf));
  309.             errs++;
  310.              syslog(LOG_ERR, "%s: Line %d: Unknown type: %s.\n",
  311.                 filename, lineno, buf);
  312.             break;
  313.         fndtype:
  314. #ifdef ALLOW_T_UNSPEC
  315.             /* Don't do anything here for T_UNSPEC...
  316.              * read input separately later
  317.              */
  318.                         if (type != T_UNSPEC) {
  319. #endif
  320.                 if (!getword((char *)buf, sizeof(buf), fp))
  321.                 break;
  322.                 dprintf(3,
  323.                     (ddt,
  324.                      "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",
  325.                      domain, class, type, ttl, buf));
  326. #ifdef ALLOW_T_UNSPEC
  327.                         }
  328. #endif
  329.             /*
  330.              * Convert the ascii data 'buf' to the proper format
  331.              * based on the type and pack into 'data'.
  332.              */
  333.             switch (type) {
  334.             case T_A:
  335.                 if (!inet_aton(buf, &ina))
  336.                     goto err;
  337.                 n = ntohl(ina.s_addr);
  338.                 cp = data;
  339.                 PUTLONG(n, cp);
  340.                 n = INT32SZ;
  341.                 break;
  342.  
  343.             case T_HINFO:
  344.             case T_ISDN:
  345.                 n = strlen((char *)buf);
  346.                 if (n > 255) {
  347.                     syslog(LOG_WARNING,
  348.                     "%s: line %d: CPU type too long",
  349.                     filename, lineno);
  350.                     n = 255;
  351.                 }
  352.                 data[0] = n;
  353.                 bcopy(buf, (char *)data + 1, (int)n);
  354.                 if (n == 0)
  355.                     goto err;
  356.                 n++;
  357.                 if (!getword((char *)buf, sizeof(buf), fp))
  358.                     i = 0;
  359.                 else {
  360.                     endline(fp);
  361.                     i = strlen((char *)buf);
  362.                 }
  363.                 if (i == 0) {
  364.                     /* goto err; */
  365.                         /* XXX tolerate for now */
  366.                     data[n++] = 1;
  367.                     data[n++] = '?';
  368.                     break;
  369.                 }
  370.                 if (i > 255) {
  371.                     syslog(LOG_WARNING,
  372.                        "%s:%d: OS type too long",
  373.                        filename, lineno);
  374.                     i = 255;
  375.                 }
  376.                 data[n] = i;
  377.                 bcopy(buf, data + n + 1, i);
  378.                 n += i + 1;
  379.                 break;
  380.  
  381.             case T_SOA:
  382.             case T_MINFO:
  383.             case T_RP:
  384.                 (void) strcpy((char *)data, (char *)buf);
  385.                 makename(data, origin);
  386.                 cp = data + strlen((char *)data) + 1;
  387.                 if (!getword((char *)cp,
  388.                          sizeof(data) - (cp - data), fp))
  389.                     goto err;
  390.                 makename(cp, origin);
  391.                 cp += strlen((char *)cp) + 1;
  392.                 if (type != T_SOA) {
  393.                     n = cp - data;
  394.                     break;
  395.                 }
  396.                 if (class != zp->z_class) {
  397.                     syslog(LOG_WARNING,
  398.                            "%s:%d: %s",
  399.                            filename, lineno,
  400.                            "SOA class not same as zone's");
  401.                 }
  402.                 c = getnonblank(fp, filename);
  403.                 if (c == '(') {
  404.                     multiline = 1;
  405.                 } else {
  406.                     multiline = 0;
  407.                     ungetc(c, fp);
  408.                 }
  409.                 zp->z_serial = getnum(fp, filename, 1);
  410.                 n = (u_int32_t) zp->z_serial;
  411.                 PUTLONG(n, cp);
  412.                 zp->z_refresh = getnum(fp, filename, 0);
  413.                 n = (u_int32_t) zp->z_refresh;
  414.                 PUTLONG(n, cp);
  415.                 if (zp->z_type == Z_SECONDARY
  416. #if defined(STUBS) 
  417.                     || zp->z_type == Z_STUB
  418. #endif
  419.                     ) {
  420.                     zp->z_time = sb.st_mtime
  421.                            + zp->z_refresh;
  422.                 }
  423.                 zp->z_retry = getnum(fp, filename, 0);
  424.                 n = (u_int32_t) zp->z_retry;
  425.                 PUTLONG(n, cp);
  426.                 zp->z_expire = getnum(fp, filename, 0);
  427.                 n = (u_int32_t) zp->z_expire;
  428.                 PUTLONG (n, cp);
  429.                 zp->z_minimum = getnum(fp, filename, 0);
  430.                 n = (u_int32_t) zp->z_minimum;
  431.                 PUTLONG (n, cp);
  432.                 n = cp - data;
  433.                 if (multiline) {
  434.                     if (getnonblank(fp, filename) != ')')
  435.                         goto err;
  436.                 }
  437.                                 read_soa++;
  438.                 endline(fp);
  439.                 break;
  440.  
  441.             case T_UID:
  442.             case T_GID:
  443.                 n = 0;
  444.                 cp = buf;
  445.                 while (isdigit(*cp))
  446.                     n = n * 10 + (*cp++ - '0');
  447.                 if (cp == buf)
  448.                     goto err;
  449.                 cp = data;
  450.                 PUTLONG(n, cp);
  451.                 n = INT32SZ;
  452.                 break;
  453.  
  454.             case T_WKS:
  455.                 /* Address */
  456.                 if (!inet_aton(buf, &ina))
  457.                     goto err;
  458.                 n = ntohl(ina.s_addr);
  459.                 cp = data;
  460.                 PUTLONG(n, cp);
  461.                 *cp = (char)getprotocol(fp, filename);
  462.                 /* Protocol */
  463.                 n = INT32SZ + sizeof(char);
  464.                 /* Services */
  465.                 n = getservices((int)n, data, fp, filename);
  466.                 break;
  467.  
  468.             case T_NS:
  469.             case T_CNAME:
  470.             case T_MB:
  471.             case T_MG:
  472.             case T_MR:
  473.             case T_PTR:
  474.                 (void) strcpy((char *)data, (char *)buf);
  475.                 makename(data, origin);
  476.                 n = strlen((char *)data) + 1;
  477.                 break;
  478.  
  479.             case T_UINFO:
  480.                 cp = strchr((char *)buf, '&');
  481.                 bzero(data, sizeof(data));
  482.                 if ( cp != NULL) {
  483.                     (void) strncpy((char *)data,
  484.                         (char *)buf, cp - buf);
  485.                     op = strchr(domain, '.');
  486.                     if ( op != NULL)
  487.                         (void) strncat((char *)data,
  488.                         domain,op-domain);
  489.                     else
  490.                         (void) strcat((char *)data,
  491.                             domain);
  492.                     (void) strcat((char *)data,
  493.                         (char *)++cp);
  494.                 } else
  495.                     (void) strcpy((char *)data,
  496.                         (char *)buf);
  497.                 n = strlen((char *)data) + 1;
  498.                 break;
  499.             case T_MX:
  500.             case T_AFSDB:
  501.             case T_RT:
  502.                 n = 0;
  503.                 cp = buf;
  504.                 while (isdigit(*cp))
  505.                     n = n * 10 + (*cp++ - '0');
  506.                 /* catch bad values */
  507.                 if ((cp == buf) || (n > 65535))
  508.                     goto err;
  509.  
  510.                 cp = data;
  511.                 PUTSHORT((u_int16_t)n, cp);
  512.  
  513.                 if (!getword((char *)buf, sizeof(buf), fp))
  514.                     goto err;
  515.                 (void) strcpy((char *)cp, (char *)buf);
  516.                 makename(cp, origin);
  517.                 /* advance pointer to end of data */
  518.                 cp += strlen((char *)cp) +1;
  519.  
  520.                 /* now save length */
  521.                 n = (cp - data);
  522.                 break;
  523.  
  524.             case T_TXT:
  525.             case T_X25:
  526.                                 cp = buf + (n = strlen(buf));
  527.                 while ((i = getc(fp), *cp = i, i != EOF)
  528.                                        && *cp != '\n'
  529.                                        && (n < MAXDATA)) {
  530.                                   cp++; n++;
  531.                                 }
  532.                                 if (*cp == '\n') /* leave \n for getword */
  533.                                     ungetc(*cp, fp);
  534.                                 *cp = '\0';
  535.                                 /* now do normal processing */
  536.  
  537.                 i = strlen((char *)buf);
  538.                 cp = data;
  539.                 cp1 = buf;
  540.                 /*
  541.                  * there is expansion here so make sure we
  542.                  * don't overflow data
  543.                  */
  544.                 if (i > sizeof(data) * 255 / 256) {
  545.                     syslog(LOG_WARNING,
  546.                     "%s: line %d: TXT record truncated",
  547.                     filename, lineno);
  548.                     i = sizeof(data) * 255 / 256;
  549.                 }
  550.                 while (i > 255) {
  551.                     *cp++ = 255;
  552.                     bcopy(cp1, cp, 255);
  553.                     cp += 255;
  554.                     cp1 += 255;
  555.                     i -= 255;
  556.                 }
  557.                 *cp++ = i;
  558.                 bcopy(cp1, cp, i);
  559.                 cp += i;
  560.                 n = cp - data;
  561.                 endline(fp);
  562.                 break;
  563.  
  564.             case T_NSAP:
  565.                 n = inet_nsap_addr(buf, data, MAXDATA);
  566.                 if (n == 0)
  567.                     goto err;
  568.                 endline(fp);
  569.                 break;
  570. #ifdef ALLOW_T_UNSPEC
  571.                         case T_UNSPEC:
  572.                                 {
  573.                                     int rcode;
  574.                                     fgets(buf, sizeof(buf), fp);
  575.                     dprintf(1, (ddt, "loading T_UNSPEC\n"));
  576.                     if (rcode = atob(buf,
  577.                              strlen((char*)buf),
  578.                              data, sizeof(data),
  579.                              &n)) {
  580.                     if (rcode == CONV_OVERFLOW) {
  581.                         dprintf(1,
  582.                             (ddt,
  583.                        "Load T_UNSPEC: input buffer overflow\n"
  584.                              )
  585.                             );
  586.                         errs++;
  587.                         syslog(LOG_ERR,
  588.                        "Load T_UNSPEC: input buffer overflow");
  589.                     } else {
  590.                         dprintf(1,
  591.                             (ddt,
  592.                      "Load T_UNSPEC: Data in bad atob format\n"
  593.                              )
  594.                             );
  595.                         errs++;
  596.                         syslog(LOG_ERR,
  597.                      "Load T_UNSPEC: Data in bad atob format");
  598.                     }
  599.                                     }
  600.                                 }
  601.                                 break;
  602. #endif /* ALLOW_T_UNSPEC */
  603.  
  604.             default:
  605.                 goto err;
  606.             }
  607. #ifdef STUBS
  608.             if (type == T_SOA && zp->z_type == Z_STUB)
  609.                 continue;
  610. #endif
  611. #ifdef NO_GLUE
  612.             /*
  613.              * Ignore data outside the zone.
  614.              */
  615.             if (zp->z_type != Z_CACHE &&
  616.                 !samedomain(domain, zp->z_origin))
  617.             {
  618.                 syslog(LOG_WARNING,
  619.                 "%s:%d: data \"%s\" outside zone \"%s\" (ignored)",
  620.                        filename, lineno, domain, zp->z_origin);
  621.                 continue;
  622.             }
  623. #endif /*NO_GLUE*/
  624.  
  625.             dp = savedata(class, type, (u_int32_t)ttl,
  626.                       (u_char *)data, (int)n);
  627.             dp->d_zone = zp - zones;
  628.             dp->d_flags = dataflags;
  629.             dp->d_cred = DB_C_ZONE;
  630.             dp->d_clev = clev;
  631.             if ((c = db_update(domain, dp, dp, dbflags,
  632.                        (zp->z_type == Z_CACHE)
  633.                        ? fcachetab
  634.                        : hashtab))
  635.                 != OK) {
  636. #ifdef DEBUG
  637.                 if (debug && (c != DATAEXISTS))
  638.                     fprintf(ddt, "update failed %s %d\n", 
  639.                         domain, type);
  640. #endif
  641.                 free((char*) dp);
  642.             }
  643.             continue;
  644.  
  645.         case ERROR:
  646.             break;
  647.         }
  648.     err:
  649.         errs++;
  650.         syslog(LOG_ERR, "%s: line %d: database format error (%s)",
  651.             filename, empty_token ? (lineno - 1) : lineno, buf);
  652.         dprintf(1, (ddt,
  653.                 "%s: line %d: database format error ('%s', %d)\n",
  654.                 filename, empty_token ? (lineno - 1) : lineno,
  655.                 buf, n));
  656.         while ((c = getc(fp)) != EOF && c != '\n')
  657.             ;
  658.         if (c == '\n')
  659.             lineno++;
  660.     }
  661.     (void) my_fclose(fp);
  662.     lineno = slineno;
  663.     if (doinginclude == 0) {
  664.         if (didinclude) {
  665.             zp->z_flags |= Z_INCLUDE;
  666.             zp->z_ftime = 0;
  667.         } else
  668.             zp->z_ftime = sb.st_mtime;
  669.         zp->z_lastupdate = sb.st_mtime;
  670.         if (zp->z_type != Z_CACHE && read_soa != 1) {
  671.             errs++;
  672.             if (read_soa == 0)
  673.                 syslog(LOG_ERR, "%s: no SOA record", filename);
  674.             else
  675.                 syslog(LOG_ERR, "%s: multiple SOA records",
  676.                     filename);
  677.         }
  678.     }
  679. #ifdef SECURE_ZONES
  680.     build_secure_netlist(zp);
  681. #endif
  682.     if (errs)
  683.         zp->z_flags |= Z_DB_BAD;
  684.     return (errs);
  685. }
  686.  
  687. static int
  688. gettoken(fp, src)
  689.     register FILE *fp;
  690.     char *src;
  691. {
  692.     register int c;
  693.     char op[32];
  694.  
  695.     for (;;) {
  696.         c = getc(fp);
  697.     top:
  698.         switch (c) {
  699.         case EOF:
  700.             return (EOF);
  701.  
  702.         case '$':
  703.             if (getword(op, sizeof(op), fp)) {
  704.                 if (!strcasecmp("include", op))
  705.                     return (INCLUDE);
  706.                 if (!strcasecmp("origin", op))
  707.                     return (ORIGIN);
  708.             }
  709.             dprintf(1, (ddt,
  710.                     "%s: line %d: Unknown $ option: $%s\n", 
  711.                     src, lineno, op));
  712.             syslog(LOG_ERR,"%s: line %d: Unknown $ option: $%s\n", 
  713.                    src, lineno, op);
  714.             return (ERROR);
  715.  
  716.         case ';':
  717.             while ((c = getc(fp)) != EOF && c != '\n')
  718.                 ;
  719.             goto top;
  720.  
  721.         case ' ':
  722.         case '\t':
  723.             return (CURRENT);
  724.  
  725.         case '.':
  726.             return (DOT);
  727.  
  728.         case '@':
  729.             return (AT);
  730.  
  731.         case '\n':
  732.             lineno++;
  733.             continue;
  734.  
  735.         default:
  736.             (void) ungetc(c, fp);
  737.             return (DNAME);
  738.         }
  739.     }
  740. }
  741.  
  742. /* int
  743.  * getword(buf, size, fp)
  744.  *    get next word, skipping blanks & comments.
  745.  * parameters:
  746.  *    buf - destination
  747.  *    size - of destination
  748.  *    fp - file to read from
  749.  * return value:
  750.  *    0 = no word; perhaps EOL or EOF
  751.  *    1 = word was read
  752.  */
  753. int
  754. getword(buf, size, fp)
  755.     char *buf;
  756.     int size;
  757.     FILE *fp;
  758. {
  759.     register char *cp;
  760.     register int c;
  761.  
  762.     empty_token = 0;
  763.     for (cp = buf; (c = getc(fp)) != EOF; ) {
  764.         if (c == ';') {
  765.             while ((c = getc(fp)) != EOF && c != '\n')
  766.                 ;
  767.             c = '\n';
  768.         }
  769.         if (c == '\n') {
  770.             if (cp != buf)
  771.                 ungetc(c, fp);
  772.             else
  773.                 lineno++;
  774.             break;
  775.         }
  776.         if (isspace(c)) {
  777.             while (isspace(c = getc(fp)) && c != '\n')
  778.                 ;
  779.             ungetc(c, fp);
  780.             if (cp != buf)        /* Trailing whitespace */
  781.                 break;
  782.             continue;        /* Leading whitespace */
  783.         }
  784.         if (c == '"') {
  785.             while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
  786.                 if (c == '\\') {
  787.                     if ((c = getc(fp)) == EOF)
  788.                         c = '\\';
  789.                     if (c == '\n')
  790.                         lineno++;
  791.                 }
  792.                 if (cp >= buf+size-1)
  793.                     break;
  794.                 *cp++ = c;
  795.             }
  796.             if (c == '\n') {
  797.                 lineno++;
  798.                 break;
  799.             }
  800.             if ((c = getc(fp)) != EOF)
  801.                 ungetc(c, fp);
  802.             if (c == EOF || isspace(c) || c == '\n') {
  803.                 *cp = '\0';
  804.                 return (1);
  805.             }
  806.             else
  807.                 continue;
  808.         }
  809.         if (c == '\\') {
  810.             if ((c = getc(fp)) == EOF)
  811.                 c = '\\';
  812.             if (c == '\n')
  813.                 lineno++;
  814.         }
  815.         if (cp >= buf+size-1)
  816.             break;
  817.         *cp++ = (char)c;
  818.     }
  819.     *cp = '\0';
  820.     if (cp == buf)
  821.         empty_token = 1;
  822.     return (cp != buf);
  823. }
  824.  
  825. /*
  826. From: kagotani@cs.titech.ac.jp
  827. Message-Id: <9007040716.AA26646@saeko.cs.titech.ac.jp>
  828. Subject: named bug report and fix
  829. Date: Wed, 04 Jul 90 16:16:52 JST
  830.  
  831. I found a bug in the BIND source code. Named with this bug parses
  832. the serial_no field of SOA records incorrectly. For example:
  833.         expression      internal
  834.         in files        expression      I expect
  835.         1.              1000            10000
  836.         1.2             10002           10002
  837.         1.23            100023          10023
  838.         2.3             20003           20003
  839. Especially I can not accept that "2.3" is treated as if it is
  840. smaller than "1.23" in their internal expressions.
  841.  
  842. [ if you define SENSIBLE_DOTS in ../conf/options.h, you get
  843.   m. kagotani's expected behaviour.  this is NOT compatible
  844.   with pre-4.9 versions of BIND.  --vix ]
  845. */
  846.  
  847. int
  848. getnum(fp, src, is_serial)
  849.     FILE *fp;
  850.     char *src;
  851.     int is_serial;
  852. {
  853.     register int c, n;
  854.     int seendigit = 0;
  855.     int seendecimal = 0;
  856.     int m = 0;
  857.     int allow_dots = 0;
  858.  
  859. #ifdef DOTTED_SERIAL
  860.     allow_dots += is_serial;
  861. #endif
  862.     for (n = 0; (c = getc(fp)) != EOF; ) {
  863.         if (isspace(c)) {
  864.             if (c == '\n')
  865.                 lineno++;
  866.             if (seendigit)
  867.                 break;
  868.             continue;
  869.         }
  870.         if (c == ';') {
  871.             while ((c = getc(fp)) != EOF && c != '\n')
  872.                 ;
  873.             if (c == '\n')
  874.                 lineno++;
  875.             if (seendigit)
  876.                 break;
  877.             continue;
  878.         }
  879.         if (!isdigit(c)) {
  880.             if (c == ')' && seendigit) {
  881.                 (void) ungetc(c, fp);
  882.                 break;
  883.             }
  884.             if (seendecimal || c != '.' || !allow_dots) {
  885.                 syslog(LOG_ERR, "%s:%d: expected a number",
  886.                        src, lineno);
  887.                 dprintf(1, (ddt, "%s:%d: expected a number",
  888.                         src, lineno));
  889.                 exit(1);    /* XXX why exit here?? */
  890.             } else {
  891.                 if (!seendigit)
  892.                     n = 1;
  893. #ifdef SENSIBLE_DOTS
  894.                 n = n * 10000;
  895. #else
  896.                 n = n * 1000;
  897. #endif
  898.                 seendigit = 1;
  899.                 seendecimal = 1;
  900.             }
  901.             continue;
  902.         }
  903. #ifdef SENSIBLE_DOTS
  904.         if (seendecimal)
  905.             m = m * 10 + (c - '0');
  906.         else
  907.             n = n * 10 + (c - '0');
  908. #else
  909.         n = n * 10 + (c - '0');
  910. #endif
  911.         seendigit = 1;
  912.     }
  913.     if (m > 9999) {
  914.         syslog(LOG_ERR, 
  915.                "%s:%d: number after the decimal point exceeds 9999", 
  916.                src, lineno);
  917.         dprintf(1, (ddt,
  918.             "%s:%d: number after the decimal point exceeds 9999", 
  919.                 src, lineno));
  920.         exit(1);    /* XXX why exit here?? */
  921.     }
  922.     if (seendecimal) {
  923.         syslog(LOG_INFO,
  924.                "%s:%d: decimal serial number interpreted as %d",
  925.                src, lineno, n+m);
  926.     }
  927.     return (n + m);
  928. }
  929.  
  930. static int
  931. getnonblank(fp, src)
  932.     FILE *fp;
  933.     char *src;
  934. {
  935.     register int c;
  936.  
  937.     while ( (c = getc(fp)) != EOF ) {
  938.         if (isspace(c)) {
  939.             if (c == '\n')
  940.                 lineno++;
  941.             continue;
  942.         }
  943.         if (c == ';') {
  944.             while ((c = getc(fp)) != EOF && c != '\n')
  945.                 ;
  946.             if (c == '\n')
  947.                 lineno++;
  948.             continue;
  949.         }
  950.         return(c);
  951.     }
  952.     syslog(LOG_ERR, "%s: line %d: unexpected EOF", src, lineno);
  953.     dprintf(1, (ddt, "%s: line %d: unexpected EOF", src, lineno));
  954.     return (EOF);
  955. }
  956.  
  957. /*
  958.  * Take name and fix it according to following rules:
  959.  * "." means root.
  960.  * "@" means current origin.
  961.  * "name." means no changes.
  962.  * "name" means append origin.
  963.  */
  964. static void
  965. makename(name, origin)
  966.     char *name, *origin;
  967. {
  968.     int n;
  969.  
  970.     if (origin[0] == '.')
  971.         origin++;
  972.     n = strlen(name);
  973.     if (n == 1) {
  974.         if (name[0] == '.') {
  975.             name[0] = '\0';
  976.             return;
  977.         }
  978.         if (name[0] == '@') {
  979.             (void) strcpy(name, origin);
  980.             return;
  981.         }
  982.     }
  983.     if (n > 0) {
  984.         if (name[n - 1] == '.')
  985.             name[n - 1] = '\0';
  986.         else if (origin[0] != '\0') {
  987.             name[n] = '.';
  988.             (void) strcpy(name + n + 1, origin);
  989.         }
  990.     }
  991. }
  992.  
  993. void
  994. endline(fp)
  995.     register FILE *fp;
  996. {
  997.     register int c;
  998.  
  999.     while (c = getc(fp)) {
  1000.         if (c == '\n') {
  1001.             (void) ungetc(c,fp);
  1002.             break;
  1003.         } else if (c == EOF) {
  1004.             break;
  1005.         }
  1006.     }
  1007. }
  1008.  
  1009. #define MAXPORT 256
  1010. #define MAXLEN 24
  1011.  
  1012. static int
  1013. getprotocol(fp, src)
  1014.     FILE *fp;
  1015.     char *src;
  1016. {
  1017.     int  k;
  1018.     char b[MAXLEN];
  1019.  
  1020.     (void) getword(b, sizeof(b), fp);
  1021.         
  1022.     k = protocolnumber(b);
  1023.     if(k == -1)
  1024.         syslog(LOG_ERR, "%s: line %d: unknown protocol: %s.",
  1025.             src, lineno, b);
  1026.     return(k);
  1027. }
  1028.  
  1029. static int
  1030. getservices(n, data, fp, src)
  1031.     int n;
  1032.     char *data, *src;
  1033.     FILE *fp;
  1034. {
  1035.     int j, ch;
  1036.     int k;
  1037.     int maxl;
  1038.     int bracket;
  1039.     char b[MAXLEN];
  1040.     char bm[MAXPORT/8];
  1041.  
  1042.     for (j = 0; j < MAXPORT/8; j++)
  1043.         bm[j] = 0;
  1044.     maxl = 0;
  1045.     bracket = 0;
  1046.     while (getword(b, sizeof(b), fp) || bracket) {
  1047.         if (feof(fp) || ferror(fp))
  1048.             break;
  1049.         if (strlen(b) == 0)
  1050.             continue;
  1051.         if ( b[0] == '(') {
  1052.             bracket++;
  1053.              continue;
  1054.         }
  1055.         if ( b[0] == ')') {
  1056.             bracket = 0;
  1057.             while ((ch = getc(fp)) != EOF && ch != '\n')
  1058.                 ;
  1059.             if (ch == '\n')
  1060.                 lineno++;
  1061.             break;
  1062.         }
  1063.         k = servicenumber(b);
  1064.         if (k == -1) {
  1065.             syslog(LOG_WARNING,
  1066.                    "%s: line %d: Unknown service '%s'",
  1067.                    src, lineno, b);
  1068.             continue;
  1069.         }
  1070.         if ((k < MAXPORT) && (k)) {
  1071.             bm[k/8] |= (0x80>>(k%8));
  1072.             if (k > maxl)
  1073.                 maxl=k;
  1074.         }
  1075.         else {
  1076.             syslog(LOG_WARNING,
  1077.                 "%s: line %d: port no. (%d) too big\n",
  1078.                 src, lineno, k);
  1079.             dprintf(1, (ddt,
  1080.                     "%s: line %d: port no. (%d) too big\n",
  1081.                     src, lineno, k));
  1082.         }
  1083.     }
  1084.     if (bracket)
  1085.         syslog(LOG_WARNING, "%s: line %d: missing close paren\n",
  1086.             src, lineno);
  1087.     maxl = maxl/8+1;
  1088.     bcopy(bm, data+n, maxl);
  1089.     return(maxl+n);
  1090. }
  1091.  
  1092. /* get_netlist(fp, netlistp, allow)
  1093.  *    get list of nets from 'fp', put on *netlistp, 'allow' controls
  1094.  *    whether hosts, nets, or both shall be accepted without warnings.
  1095.  *    (note that they are always accepted; 'allow' just controls the
  1096.  *    warnings.)
  1097.  */
  1098. void
  1099. get_netlist(fp, netlistp, allow, print_tag)
  1100.     FILE *fp;
  1101.     struct netinfo **netlistp;
  1102.     int allow;
  1103.     char *print_tag;
  1104. {
  1105.     struct netinfo *ntp = NULL, **end = netlistp;
  1106.     char buf[BUFSIZ], *maskp;
  1107.     struct in_addr ina;
  1108.  
  1109.     dprintf(1, (ddt, "get_netlist(%s)", print_tag));
  1110.     while (getword(buf, sizeof(buf), fp)) {
  1111.         if (strlen(buf) == 0)
  1112.             break;
  1113.         if ((maskp = strchr(buf, '&')) != NULL)
  1114.             *maskp++ = '\0';
  1115.         dprintf(1, (ddt," %s", buf));
  1116.         if (ntp == NULL) {
  1117.             ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
  1118.         }
  1119.         if (!inet_aton(buf, &ntp->my_addr)) {
  1120.             syslog(LOG_ERR, "%s contains bogus element (%s)",
  1121.                    print_tag, buf);
  1122.             continue;    
  1123.         }
  1124.         if (maskp) {
  1125.             if (!inet_aton(maskp, &ina)) {
  1126.                 syslog(LOG_ERR,
  1127.                        "%s element %s has bad mask (%s)",
  1128.                        print_tag, buf, maskp);
  1129.                 continue;
  1130.             }
  1131.         } else {
  1132.             if (allow & ALLOW_HOSTS)
  1133.                 ina.s_addr = 0xffffffff;    /* "exact" */
  1134.             else
  1135.                 ina.s_addr = net_mask(ntp->my_addr);
  1136.         }
  1137.         ntp->next = NULL;
  1138.         ntp->mask = ina.s_addr;
  1139.         ntp->addr = ntp->my_addr.s_addr & ntp->mask;
  1140.  
  1141.         /* Check for duplicates */
  1142.         if (addr_on_netlist(ntp->my_addr, *netlistp))
  1143.             continue;
  1144.  
  1145.         if (ntp->addr != ntp->my_addr.s_addr) {
  1146.             ina.s_addr = ntp->addr;
  1147.             syslog(LOG_WARNING,
  1148.                    "%s element (%s) mask problem (%s)",
  1149.                 print_tag, buf, inet_ntoa(ina));
  1150.         }
  1151.  
  1152.         *end = ntp;
  1153.         end = &ntp->next;
  1154.         ntp = NULL;
  1155.     }
  1156.     if (ntp)
  1157.         free((char *)ntp);
  1158.     
  1159.     dprintf(1, (ddt, "\n"));
  1160. #ifdef DEBUG
  1161.     if (debug > 2)
  1162.         for (ntp = *netlistp;  ntp != NULL;  ntp = ntp->next) {
  1163.             fprintf(ddt, "ntp x%x addr x%x mask x%x",
  1164.                 ntp, ntp->addr, ntp->mask);
  1165.             fprintf(ddt, " my_addr x%x", ntp->my_addr);
  1166.             fprintf(ddt, " %s", inet_ntoa(ntp->my_addr));
  1167.             fprintf(ddt, " next x%x\n", ntp->next);
  1168.         }
  1169. #endif
  1170. }
  1171.  
  1172. struct netinfo *
  1173. addr_on_netlist(addr, netlist)
  1174.     struct in_addr    addr;
  1175.     struct netinfo    *netlist;
  1176. {
  1177.     u_int32_t    a = addr.s_addr;
  1178.     struct netinfo    *t;
  1179.  
  1180.     for (t = netlist;  t != NULL;  t = t->next)
  1181.         if (t->addr == (a & t->mask))
  1182.             return t;
  1183.     return NULL;
  1184. }
  1185.  
  1186. int
  1187. position_on_netlist(addr, netlist)
  1188.     struct in_addr    addr;
  1189.     struct netinfo    *netlist;
  1190. {
  1191.     u_int32_t    a = addr.s_addr;
  1192.     struct netinfo    *t;
  1193.     int        position = 0;
  1194.  
  1195.     for (t = netlist;  t != NULL;  t = t->next)
  1196.         if (t->addr == (a & t->mask))
  1197.             break;
  1198.         else
  1199.             position++;
  1200.     return position;
  1201. }
  1202.  
  1203. void
  1204. free_netlist(netlistp)
  1205.     struct netinfo **netlistp;
  1206. {
  1207.     register struct netinfo *ntp, *next;
  1208.  
  1209.     for (ntp = *netlistp;  ntp != NULL;  ntp = next) {
  1210.         next = ntp->next;
  1211.         free((char *)ntp);
  1212.     }
  1213.     *netlistp = NULL;
  1214. }
  1215.