home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / NAMED / db_load.c < prev    next >
Text File  |  1993-08-24  |  20KB  |  949 lines

  1. /*
  2.  * Copyright (c) 1986, 1988, 1990 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:  ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. static char sccsid[] = "@(#)db_load.c    4.37 (Berkeley) 6/1/90";
  22. #endif /* not lint */
  23.  
  24. /*
  25.  * Load data base from ascii backupfile.  Format similar to RFC 883.
  26.  */
  27.  
  28. #include <sys/param.h>
  29. #include <sys/time.h>
  30. #include <sys/stat.h>
  31. #include <netinet/in.h>
  32. #include <stdio.h>
  33. #include <syslog.h>
  34. #include <ctype.h>
  35. #include <netdb.h>
  36. #include <arpa/nameser.h>
  37. #include "ns.h"
  38. #include "db.h"
  39.  
  40. extern char *index();
  41. extern int max_cache_ttl;
  42.  
  43. /*
  44.  * Map class and type names to number
  45.  */
  46. struct map {
  47.     char    token[8];
  48.     int    val;
  49. };
  50.  
  51. struct map m_class[] = {
  52.     "in",        C_IN,
  53. #ifdef notdef
  54.     "any",        C_ANY,        /* any is a QCLASS, not CLASS */
  55. #endif
  56.     "chaos",    C_CHAOS,
  57.     "hs",        C_HS,
  58. };
  59. #define NCLASS (sizeof(m_class)/sizeof(struct map))
  60.  
  61. struct map m_type[] = {
  62.     "a",        T_A,
  63.     "ns",        T_NS,
  64.     "cname",    T_CNAME,
  65.     "soa",        T_SOA,
  66.     "mb",        T_MB,
  67.     "mg",        T_MG,
  68.     "mr",        T_MR,
  69.     "null",        T_NULL,
  70.     "wks",        T_WKS,
  71.     "ptr",        T_PTR,
  72.     "hinfo",    T_HINFO,
  73.     "minfo",    T_MINFO,
  74.     "mx",        T_MX,
  75.     "uinfo",    T_UINFO,
  76.     "txt",        T_TXT,
  77.     "uid",        T_UID,
  78.     "gid",        T_GID,
  79. #ifdef notdef
  80.     "any",        T_ANY,        /* any is a QTYPE, not TYPE */
  81. #endif
  82. #ifdef ALLOW_T_UNSPEC
  83.         "unspec",       T_UNSPEC,
  84. #endif ALLOW_T_UNSPEC
  85. };
  86. #define NTYPE (sizeof(m_type)/sizeof(struct map))
  87.  
  88. /*
  89.  * Parser token values
  90.  */
  91. #define CURRENT    1
  92. #define DOT    2
  93. #define AT    3
  94. #define DNAME    4
  95. #define INCLUDE    5
  96. #define ORIGIN    6
  97. #define ERROR    7
  98.  
  99. int    lineno;        /* current line number */
  100.  
  101. /*
  102.  * Load the database from 'filename'. Origin is appended to all domain
  103.  * names in the file.
  104.  */
  105. db_load(filename, in_origin, zp, doinginclude)
  106.     char *filename, *in_origin;
  107.     struct zoneinfo *zp;
  108. {
  109.     register u_char *cp;
  110.     register struct map *mp;
  111.     char domain[MAXDNAME];
  112.     char origin[MAXDNAME];
  113.     char tmporigin[MAXDNAME];
  114.     u_char buf[MAXDATA];
  115.     u_char data[MAXDATA];
  116.     u_char *cp1;
  117.     char *op;
  118.     int c;
  119.     int class, type, ttl, dbflags, dataflags;
  120.         int read_soa = 0;    /* number of soa's read */
  121.     struct databuf *dp;
  122.     FILE *fp;
  123.     int slineno, i, errs = 0, didinclude = 0;
  124.     register u_long n;
  125.     struct stat sb;
  126.  
  127. #ifdef DEBUG
  128.     if (debug)
  129.         fprintf(ddt,"db_load(%s, %s, %d, %d)\n",
  130.             filename, in_origin, zp - zones, doinginclude);
  131. #endif
  132.  
  133.     (void) strcpy(origin, in_origin);
  134.     if ((fp = fopen(filename, "r")) == NULL) {
  135.         syslog(LOG_ERR, "%s: %m", filename);
  136. #ifdef DEBUG
  137.         if (debug)
  138.             fprintf(ddt,"db_load: error opening file %s\n", filename);
  139. #endif
  140.         return (-1);
  141.     }
  142.     if (zp->z_type == Z_CACHE) {
  143.         dbflags = DB_NODATA | DB_NOHINTS;
  144.         dataflags = DB_F_HINT;
  145.     } else {
  146.         dbflags = DB_NODATA;
  147.         dataflags = 0;
  148.     }
  149.     gettime(&tt);
  150.     if (fstat(fileno(fp), &sb) < 0) {
  151.         syslog(LOG_ERR, "%s: %m", filename);
  152.         sb.st_mtime = (int)tt.tv_sec;
  153.     }
  154.     slineno = lineno;
  155.     lineno = 1;
  156.     domain[0] = '\0';
  157.     class = C_IN;
  158.     zp->z_state &= ~(Z_INCLUDE|Z_DB_BAD);
  159.     while ((c = gettoken(fp)) != EOF) {
  160.         switch (c) {
  161.         case INCLUDE:
  162.             if (!getword(buf, sizeof(buf), fp)) /* file name */
  163.                 break;
  164.             if (!getword(tmporigin, sizeof(tmporigin), fp))
  165.                 strcpy(tmporigin, origin);
  166.             else {
  167.                 makename(tmporigin, origin);
  168.                 endline(fp);
  169.             }
  170.             didinclude = 1;
  171.             errs += db_load(buf, tmporigin, zp, 1);
  172.             continue;
  173.  
  174.         case ORIGIN:
  175.             (void) strcpy(buf, origin);
  176.             if (!getword(origin, sizeof(origin), fp))
  177.                 break;
  178. #ifdef DEBUG
  179.             if (debug > 3)
  180.                 fprintf(ddt,"db_load: origin %s, buf %s\n",
  181.                     origin, buf);
  182. #endif
  183.             makename(origin, buf);
  184. #ifdef DEBUG
  185.             if (debug > 3)
  186.                 fprintf(ddt,"db_load: origin now %s\n", origin);
  187. #endif
  188.             continue;
  189.  
  190.         case DNAME:
  191.             if (!getword(domain, sizeof(domain), fp))
  192.                 break;
  193.             n = strlen(domain) - 1;
  194.             if (domain[n] == '.')
  195.                 domain[n] = '\0';
  196.             else if (*origin) {
  197.                 (void) strcat(domain, ".");
  198.                 (void) strcat(domain, origin);
  199.             }
  200.             goto gotdomain;
  201.  
  202.         case AT:
  203.             (void) strcpy(domain, origin);
  204.             goto gotdomain;
  205.  
  206.         case DOT:
  207.             domain[0] = '\0';
  208.             /* fall thru ... */
  209.         case CURRENT:
  210.         gotdomain:
  211.             if (!getword(buf, sizeof(buf), fp)) {
  212.                 if (c == CURRENT)
  213.                     continue;
  214.                 break;
  215.             }
  216.             cp = buf;
  217.             ttl = 0;
  218.             if (isdigit(*cp)) {
  219.                 n = 0;
  220.                 do
  221.                     n = n * 10 + (*cp++ - '0');
  222.                 while (isdigit(*cp));
  223.                 if (zp->z_type == Z_CACHE) {
  224.                     /* this allows the cache entry to age */
  225.                     /* while sitting on disk (powered off) */
  226.                     if (n > max_cache_ttl)
  227.                     n = max_cache_ttl;
  228.                     n += sb.st_mtime;
  229.                 }
  230.                 ttl = n;
  231.                 if (!getword(buf, sizeof(buf), fp))
  232.                     break;
  233.             }
  234.             for (mp = m_class; mp < m_class+NCLASS; mp++)
  235.                 if (!strcasecmp(buf, mp->token)) {
  236.                     class = mp->val;
  237.                     (void) getword(buf, sizeof(buf), fp);
  238.                     break;
  239.                 }
  240.             for (mp = m_type; mp < m_type+NTYPE; mp++)
  241.                 if (!strcasecmp(buf, mp->token)) {
  242.                     type = mp->val;
  243.                     goto fndtype;
  244.                 }
  245. #ifdef DEBUG
  246.             if (debug)
  247.                 fprintf(ddt,"Line %d: Unknown type: %s.\n",
  248.                     lineno, buf);
  249. #endif
  250.             errs++;
  251.              syslog(LOG_ERR, "Line %d: Unknown type: %s.\n",
  252.                 lineno, buf);
  253.             break;
  254.         fndtype:
  255. #ifdef ALLOW_T_UNSPEC
  256.             /* Don't do anything here for T_UNSPEC...
  257.              * read input separately later
  258.              */
  259.                         if (type != T_UNSPEC) {
  260. #endif ALLOW_T_UNSPEC
  261.                 if (!getword(buf, sizeof(buf), fp))
  262.                 break;
  263. #ifdef DEBUG
  264.                 if (debug >= 3)
  265.                     fprintf(ddt,
  266.                     "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",
  267.                     domain, class, type, ttl, buf);
  268. #endif
  269. #ifdef ALLOW_T_UNSPEC
  270.                         }
  271. #endif ALLOW_T_UNSPEC
  272.             /*
  273.              * Convert the ascii data 'buf' to the proper format
  274.              * based on the type and pack into 'data'.
  275.              */
  276.             switch (type) {
  277.             case T_A:
  278.                 n = ntohl((u_long)inet_addr((char *)buf));
  279.                 cp = data;
  280.                 PUTLONG(n, cp);
  281.                 n = sizeof(u_long);
  282.                 break;
  283.  
  284.             case T_HINFO:
  285.                 n = strlen(buf);
  286.                 if (n > 255) {
  287.                     syslog(LOG_WARNING,
  288.                     "%s: line %d: CPU type too long",
  289.                     filename, lineno);
  290.                     n = 255;
  291.                 }
  292.                 data[0] = n;
  293.                 bcopy(buf, (char *)data + 1, (int)n);
  294.                 n++;
  295.                 if (!getword(buf, sizeof(buf), fp))
  296.                     break;
  297.                 i = strlen(buf);
  298.                 if (i > 255) {
  299.                     syslog(LOG_WARNING,
  300.                     "%s: line %d: OS type too long",
  301.                     filename, lineno);
  302.                     i = 255;
  303.                 }
  304.                 data[n] = i;
  305.                 bcopy(buf, data + n + 1, i);
  306.                 n += i + 1;
  307.                 endline(fp);
  308.                 break;
  309.  
  310.             case T_SOA:
  311.             case T_MINFO:
  312.                 (void) strcpy(data, buf);
  313.                 makename(data, origin);
  314.                 cp = data + strlen(data) + 1;
  315.                 if (!getword(cp, sizeof(data) - (cp - data),fp)) {
  316.                     n = cp - data;
  317.                     break;
  318.                 }
  319.                 makename(cp, origin);
  320.                 cp += strlen(cp) + 1;
  321.                 if (type == T_MINFO) {
  322.                     n = cp - data;
  323.                     break;
  324.                 }
  325.                 if (getnonblank(fp) != '(')
  326.                     goto err;
  327.                 zp->z_serial = getnum(fp);
  328.                 n = (u_long) zp->z_serial;
  329.                 PUTLONG(n, cp);
  330.                 zp->z_refresh = getnum(fp);
  331.                 n = (u_long) zp->z_refresh;
  332.                 PUTLONG(n, cp);
  333.                 if (zp->z_type == Z_SECONDARY)
  334.                     zp->z_time = sb.st_mtime + zp->z_refresh;
  335.                 zp->z_retry = getnum(fp);
  336.                 n = (u_long) zp->z_retry;
  337.                 PUTLONG(n, cp);
  338.                 zp->z_expire = getnum(fp);
  339.                 n = (u_long) zp->z_expire;
  340.                 PUTLONG (n, cp);
  341.                 zp->z_minimum = getnum(fp);
  342.                 n = (u_long) zp->z_minimum;
  343.                 PUTLONG (n, cp);
  344.                 n = cp - data;
  345.                 if (getnonblank(fp) != ')')
  346.                     goto err;
  347.                                 read_soa++;
  348.                 endline(fp);
  349.                 break;
  350.  
  351.             case T_UID:
  352.             case T_GID:
  353.                 n = 0;
  354.                 cp = buf;
  355.                 while (isdigit(*cp))
  356.                     n = n * 10 + (*cp++ - '0');
  357.                 if (cp == buf)
  358.                     goto err;
  359.                 cp = data;
  360.                 PUTLONG(n, cp);
  361.                 n = sizeof(long);
  362.                 break;
  363.  
  364.             case T_WKS:
  365.                 /* Address */
  366.                 n = ntohl((u_long)inet_addr((char *)buf));
  367.                 cp = data;
  368.                 PUTLONG(n, cp);
  369.                 *cp = getprotocol(fp, filename);
  370.                 /* Protocol */
  371.                 n = sizeof(u_long) + sizeof(char);
  372.                 /* Services */
  373.                 n = getservices((int)n, data, fp, filename);
  374.                 break;
  375.  
  376.             case T_NS:
  377.             case T_CNAME:
  378.             case T_MB:
  379.             case T_MG:
  380.             case T_MR:
  381.             case T_PTR:
  382.                 (void) strcpy(data, buf);
  383.                 makename(data, origin);
  384.                 n = strlen(data) + 1;
  385.                 break;
  386.  
  387.             case T_UINFO:
  388.                 cp = (u_char *)index(buf, '&');
  389.                 bzero(data, sizeof(data));
  390.                 if ( cp != NULL) {
  391.                     (void) strncpy(data, buf, cp - buf);
  392.                     op = index(domain, '.');
  393.                     if ( op != NULL)
  394.                         (void) strncat(data,
  395.                         domain,op-domain);
  396.                     else
  397.                         (void) strcat(data, domain);
  398.                     (void) strcat(data, ++cp);
  399.                 } else
  400.                     (void) strcpy(data, buf);
  401.                 n = strlen(data) + 1;
  402.                 break;
  403.             case T_MX:
  404.                 n = 0;
  405.                 cp = buf;
  406.                 while (isdigit(*cp))
  407.                     n = n * 10 + (*cp++ - '0');
  408.                 /* catch bad values */
  409.                 if ((cp == buf) || (n > 65535))
  410.                     goto err;
  411.  
  412.                 cp = data;
  413.                 PUTSHORT((u_short)n, cp);
  414.  
  415.                 if (!getword(buf, sizeof(buf), fp))
  416.                         break;
  417.                 (void) strcpy(cp,buf);
  418.                 makename(cp, origin);
  419.                 /* get pointer to place in data */
  420.                 cp += strlen(cp) +1;
  421.  
  422.                 /* now save length */
  423.                 n = (cp - data);
  424.                 break;
  425.  
  426.             case T_TXT:
  427.                 i = strlen(buf);
  428.                 cp = data;
  429.                 cp1 = buf;
  430.                 /*
  431.                  * there is expansion here so make sure we
  432.                  * don't overflow data
  433.                  */
  434.                 if (i > sizeof(data) * 255 / 256) {
  435.                     syslog(LOG_WARNING,
  436.                     "%s: line %d: TXT record truncated",
  437.                     filename, lineno);
  438.                     i = sizeof(data) * 255 / 256;
  439.                 }
  440.                 while (i > 255) {
  441.                     *cp++ = 255;
  442.                     bcopy(cp1, cp, 255);
  443.                     cp += 255;
  444.                     cp1 += 255;
  445.                     i -= 255;
  446.                 }
  447.                 *cp++ = i;
  448.                 bcopy(cp1, cp, i);
  449.                 cp += i;
  450.                 n = cp - data;
  451.                 endline(fp);
  452.                 break;
  453. #ifdef ALLOW_T_UNSPEC
  454.                         case T_UNSPEC:
  455.                                 {
  456.                                     int rcode;
  457.                                     fgets(buf, sizeof(buf), fp);
  458. #ifdef DEBUG
  459.                     if (debug)
  460.                                         fprintf(ddt, "loading T_UNSPEC\n");
  461. #endif DEBUG
  462.                                     if (rcode = atob(buf, strlen(buf), data,
  463.                             sizeof(data), &n)) {
  464.                                         if (rcode == CONV_OVERFLOW) {
  465. #ifdef DEBUG
  466.                                             if (debug)
  467.                                                fprintf(ddt,
  468.                                   "Load T_UNSPEC: input buffer overflow\n");
  469. #endif DEBUG
  470.                         errs++;
  471.                                             syslog(LOG_ERR,
  472.                          "Load T_UNSPEC: input buffer overflow");
  473.                                          } else {
  474. #ifdef DEBUG
  475.                                             if (debug)
  476.                                                 fprintf(ddt,
  477.                            "Load T_UNSPEC: Data in bad atob format\n");
  478. #endif DEBUG
  479.                         errs++;
  480.                                             syslog(LOG_ERR,
  481.                            "Load T_UNSPEC: Data in bad atob format");
  482.                                          }
  483.                                     }
  484.                                 }
  485.                                 break;
  486. #endif ALLOW_T_UNSPEC
  487.  
  488.             default:
  489.                 goto err;
  490.             }
  491.             dp = savedata(class, type, (u_long)ttl, data, (int)n);
  492.             dp->d_zone = zp - zones;
  493.             dp->d_flags = dataflags;
  494.             if ((c = db_update(domain, dp, dp, dbflags,
  495.                (zp->z_type == Z_CACHE)? fcachetab : hashtab)) < 0) {
  496. #ifdef DEBUG
  497.                 if (debug && (c != DATAEXISTS))
  498.                     fprintf(ddt,"update failed\n");
  499. #endif
  500.             }
  501.             continue;
  502.  
  503.         case ERROR:
  504.             break;
  505.         }
  506.     err:
  507.         errs++;
  508.         syslog(LOG_ERR, "%s: line %d: database format error (%s)",
  509.             filename, lineno, buf);
  510. #ifdef DEBUG
  511.         if (debug)
  512.             fprintf(ddt,"%s: line %d: database format error ('%s', %d)\n",
  513.                 filename, lineno, buf, n);
  514. #endif
  515.         while ((c = getc(fp)) != EOF && c != '\n')
  516.             ;
  517.         if (c == '\n')
  518.             lineno++;
  519.     }
  520.     (void) fclose(fp);
  521.     lineno = slineno;
  522.     if (doinginclude == 0) {
  523.         if (didinclude) {
  524.             zp->z_state |= Z_INCLUDE;
  525.             zp->z_ftime = 0;
  526.         } else
  527.             zp->z_ftime = sb.st_mtime;
  528.         zp->z_lastupdate = sb.st_mtime;
  529.         if (zp->z_type != Z_CACHE && read_soa != 1) {
  530.             errs++;
  531.             if (read_soa == 0)
  532.                 syslog(LOG_ERR, "%s: no SOA record", filename);
  533.             else
  534.                 syslog(LOG_ERR, "%s: multiple SOA records",
  535.                     filename);
  536.         }
  537.     }
  538.     if (errs)
  539.         zp->z_state |= Z_DB_BAD;
  540.     return (errs);
  541. }
  542.  
  543. int gettoken(fp)
  544.     register FILE *fp;
  545. {
  546.     register int c;
  547.     char op[32];
  548.  
  549.     for (;;) {
  550.         c = getc(fp);
  551.     top:
  552.         switch (c) {
  553.         case EOF:
  554.             return (EOF);
  555.  
  556.         case '$':
  557.             if (getword(op, sizeof(op), fp)) {
  558.                 if (!strcasecmp("include", op))
  559.                     return (INCLUDE);
  560.                 if (!strcasecmp("origin", op))
  561.                     return (ORIGIN);
  562.             }
  563. #ifdef DEBUG
  564.             if (debug)
  565.                 fprintf(ddt,"Line %d: Unknown $ option: $%s\n", 
  566.                     lineno, op);
  567. #endif
  568.             syslog(LOG_ERR,"Line %d: Unknown $ option: $%s\n", 
  569.                 lineno, op);
  570.             return (ERROR);
  571.  
  572.         case ';':
  573.             while ((c = getc(fp)) != EOF && c != '\n')
  574.                 ;
  575.             goto top;
  576.  
  577.         case ' ':
  578.         case '\t':
  579.             return (CURRENT);
  580.  
  581.         case '.':
  582.             return (DOT);
  583.  
  584.         case '@':
  585.             return (AT);
  586.  
  587.         case '\n':
  588.             lineno++;
  589.             continue;
  590.  
  591.         default:
  592.             (void) ungetc(c, fp);
  593.             return (DNAME);
  594.         }
  595.     }
  596. }
  597.  
  598. /*
  599.  * Get next word, skipping blanks & comments.
  600.  */
  601. getword(buf, size, fp)
  602.     char *buf;
  603.     int size;
  604.     FILE *fp;
  605. {
  606.     register char *cp;
  607.     register int c;
  608.  
  609.     for (cp = buf; (c = getc(fp)) != EOF; ) {
  610.         if (c == ';') {
  611.             while ((c = getc(fp)) != EOF && c != '\n')
  612.                 ;
  613.             c = '\n';
  614.         }
  615.         if (c == '\n') {
  616.             if (cp != buf)
  617.                 ungetc(c, fp);
  618.             else
  619.                 lineno++;
  620.             break;
  621.         }
  622.         if (isspace(c)) {
  623.             while (isspace(c = getc(fp)) && c != '\n')
  624.                 ;
  625.             ungetc(c, fp);
  626.             if (cp != buf)        /* Trailing whitespace */
  627.                 break;
  628.             continue;        /* Leading whitespace */
  629.         }
  630.         if (c == '"') {
  631.             while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
  632.                 if (c == '\\') {
  633.                     if ((c = getc(fp)) == EOF)
  634.                         c = '\\';
  635.                     if (c == '\n')
  636.                         lineno++;
  637.                 }
  638.                 if (cp >= buf+size-1)
  639.                     break;
  640.                 *cp++ = c;
  641.             }
  642.             if (c == '\n') {
  643.                 lineno++;
  644.                 break;
  645.             }
  646.             continue;
  647.         }
  648.         if (c == '\\') {
  649.             if ((c = getc(fp)) == EOF)
  650.                 c = '\\';
  651.             if (c == '\n')
  652.                 lineno++;
  653.         }
  654.         if (cp >= buf+size-1)
  655.             break;
  656.         *cp++ = c;
  657.     }
  658.     *cp = '\0';
  659.     return (cp != buf);
  660. }
  661.  
  662. getnum(fp)
  663.     FILE *fp;
  664. {
  665.     register int c, n;
  666.     int seendigit = 0;
  667.     int seendecimal = 0;
  668.  
  669.     for (n = 0; (c = getc(fp)) != EOF; ) {
  670.         if (isspace(c)) {
  671.             if (c == '\n')
  672.                 lineno++;
  673.             if (seendigit)
  674.                 break;
  675.             continue;
  676.         }
  677.         if (c == ';') {
  678.             while ((c = getc(fp)) != EOF && c != '\n')
  679.                 ;
  680.             if (c == '\n')
  681.                 lineno++;
  682.             if (seendigit)
  683.                 break;
  684.             continue;
  685.         }
  686.         if (!isdigit(c)) {
  687.             if (c == ')' && seendigit) {
  688.                 (void) ungetc(c, fp);
  689.                 break;
  690.             }
  691.             if (seendecimal || c != '.') {
  692.                 syslog(LOG_ERR, "line %d: expected a number",
  693.                 lineno);
  694. #ifdef DEBUG
  695.                 if (debug)
  696.                     fprintf(ddt,"line %d: expected a number",
  697.                         lineno);
  698. #endif
  699.                 exit(1);    /* XXX why exit */
  700.             } else {
  701.                 if (!seendigit)
  702.                     n = 1;
  703.                 n = n * 1000 ;
  704.                 seendigit = 1;
  705.                 seendecimal = 1;
  706.             }
  707.             continue;
  708.         }
  709.         n = n * 10 + (c - '0');
  710.         seendigit = 1;
  711.     }
  712.     return (n);
  713. }
  714.  
  715. getnonblank(fp)
  716.     FILE *fp;
  717. {
  718.     register int c;
  719.  
  720.     while ( (c = getc(fp)) != EOF ) {
  721.         if (isspace(c)) {
  722.             if (c == '\n')
  723.                 lineno++;
  724.             continue;
  725.         }
  726.         if (c == ';') {
  727.             while ((c = getc(fp)) != EOF && c != '\n')
  728.                 ;
  729.             if (c == '\n')
  730.                 lineno++;
  731.             continue;
  732.         }
  733.         return(c);
  734.     }
  735.     syslog(LOG_ERR, "line %d: unexpected EOF", lineno);
  736. #ifdef DEBUG
  737.     if (debug)
  738.         fprintf(ddt, "line %d: unexpected EOF", lineno);
  739. #endif
  740.     return (EOF);
  741. }
  742.  
  743. /*
  744.  * Take name and fix it according to following rules:
  745.  * "." means root.
  746.  * "@" means current origin.
  747.  * "name." means no changes.
  748.  * "name" means append origin.
  749.  */
  750. makename(name, origin)
  751.     char *name, *origin;
  752. {
  753.     int n;
  754.  
  755.     if (origin[0] == '.')
  756.         origin++;
  757.     n = strlen(name);
  758.     if (n == 1) {
  759.         if (name[0] == '.') {
  760.             name[0] = '\0';
  761.             return;
  762.         }
  763.         if (name[0] == '@') {
  764.             (void) strcpy(name, origin);
  765.             return;
  766.         }
  767.     }
  768.     if (n > 0) {
  769.         if (name[n - 1] == '.')
  770.             name[n - 1] = '\0';
  771.         else if (origin[0] != '\0') {
  772.             name[n] = '.';
  773.             (void) strcpy(name + n + 1, origin);
  774.         }
  775.     }
  776. }
  777.  
  778. endline(fp)
  779.     register FILE *fp;
  780. {
  781.      register int c;
  782.      while (c = getc(fp))
  783.     if (c == '\n') {
  784.         (void) ungetc(c,fp);
  785.         break;
  786.     } else if (c == EOF)
  787.         break;
  788. }
  789.  
  790. #define MAXPORT 256
  791. #define MAXLEN 24
  792.  
  793. getprotocol(fp, src)
  794.     FILE *fp;
  795.     char *src;
  796. {
  797.     int  k;
  798.     char b[MAXLEN];
  799.  
  800.     (void) getword(b, sizeof(b), fp);
  801.         
  802.     k = protocolnumber(b);
  803.     if(k == -1)
  804.         syslog(LOG_ERR, "%s: line %d: unknown protocol: %s.",
  805.             src, lineno, b);
  806.     return(k);
  807. }
  808.  
  809. int
  810. getservices(n, data, fp, src)
  811.     int n;
  812.     char *data, *src;
  813.     FILE *fp;
  814. {
  815.     int j, ch;
  816.     int k;
  817.     int maxl;
  818.     int bracket;
  819.     char b[MAXLEN];
  820.     char bm[MAXPORT/8];
  821.  
  822.     for (j = 0; j < MAXPORT/8; j++)
  823.         bm[j] = 0;
  824.     maxl = 0;
  825.     bracket = 0;
  826.     while (getword(b, sizeof(b), fp) || bracket) {
  827.         if (feof(fp) || ferror(fp))
  828.             break;
  829.         if (strlen(b) == 0)
  830.             continue;
  831.         if ( b[0] == '(') {
  832.             bracket++;
  833.              continue;
  834.         }
  835.         if ( b[0] == ')') {
  836.             bracket = 0;
  837.             while ((ch = getc(fp)) != EOF && ch != '\n')
  838.                 ;
  839.             if (ch == '\n')
  840.                 lineno++;
  841.             break;
  842.         }
  843.         k = servicenumber(b);
  844.         if (k == -1) {
  845.             syslog(LOG_WARNING, "%s: line %d: Unknown service '%s'",
  846.                 src, lineno, b);
  847.             continue;
  848.         }
  849.         if ((k < MAXPORT) && (k)) {
  850.             bm[k/8] |= (0x80>>(k%8));
  851.             if (k > maxl)
  852.                 maxl=k;
  853.         }
  854.         else {
  855.             syslog(LOG_WARNING,
  856.                 "%s: line %d: port no. (%d) too big\n",
  857.                 src, lineno, k);
  858. #ifdef DEBUG
  859.             if (debug)
  860.                 fprintf(ddt,
  861.                     "%s: line %d: port no. (%d) too big\n",
  862.                     src, lineno, k);
  863. #endif
  864.         }
  865.     }
  866.     if (bracket)
  867.         syslog(LOG_WARNING, "%s: line %d: missing close paren\n",
  868.             src, lineno);
  869.     maxl = maxl/8+1;
  870.     bcopy(bm, data+n, maxl);
  871.     return(maxl+n);
  872. }
  873.  
  874. get_sort_list(fp)
  875.     FILE *fp;
  876. {
  877.     extern struct netinfo **enettab;
  878.     register struct netinfo *ntp, **end = enettab;
  879.     extern struct netinfo *findnetinfo();
  880.     struct in_addr addr;
  881.     char buf[BUFSIZ];
  882.  
  883. #ifdef DEBUG
  884.     if (debug)
  885.         fprintf(ddt,"sortlist ");
  886. #endif
  887.     while (getword(buf, sizeof(buf), fp)) {
  888.         if (strlen(buf) == 0)
  889.             break;
  890. #ifdef DEBUG
  891.         if (debug)
  892.             fprintf(ddt," %s",buf);
  893. #endif
  894.         addr.s_addr = inet_addr(buf);
  895.         if (addr.s_addr == (unsigned)-1) {
  896.             /* resolve name to address - XXX */
  897.             continue;    
  898.         }
  899.         /* Check for duplicates, then add to linked list */
  900.         if (findnetinfo(addr))
  901.             continue;
  902.         ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
  903.         ntp->my_addr = addr;
  904.         ntp->next = NULL;
  905.         ntp->mask = net_mask(ntp->my_addr);
  906.         ntp->net = ntp->my_addr.s_addr & ntp->mask;
  907.         if (ntp->net != addr.s_addr) {
  908.             struct in_addr tmpaddr;
  909.  
  910.             tmpaddr.s_addr = ntp->net;
  911.             syslog(LOG_WARNING, "sortlist: addr %s != %s", buf,
  912.                 inet_ntoa(tmpaddr));
  913. #ifdef DEBUG
  914.             if (debug)
  915.                 fprintf(ddt, "\nsortlist: addr %s != %s\n", buf,
  916.                     inet_ntoa(tmpaddr));
  917. #endif
  918.         }
  919.  
  920.         *end = ntp;
  921.         end = &ntp->next;
  922.     }
  923.     
  924. #ifdef DEBUG
  925.     if (debug) 
  926.         fprintf(ddt,"\n");
  927.     if (debug > 2)
  928.         printnetinfo(*enettab);
  929.     if (debug > 4) {
  930.         extern struct netinfo *nettab;
  931.  
  932.         fprintf(ddt, "\nFull sort list:\n");
  933.         printnetinfo(nettab);
  934.     }
  935. #endif
  936. }
  937.  
  938. free_sort_list()
  939. {
  940.     extern struct netinfo **enettab;
  941.     register struct netinfo *ntp, *next;
  942.  
  943.     for (ntp = *enettab; ntp != NULL; ntp = next) {
  944.         next = ntp->next;
  945.         free((char *)ntp);
  946.     }
  947.     *enettab = NULL;
  948. }
  949.