home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / net / res_init.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  12KB  |  384 lines

  1. /*    $NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $    */
  2.  
  3. /*-
  4.  * Copyright (c) 1985, 1989, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *    This product includes software developed by the University of
  18.  *    California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. #if 0
  58. static char sccsid[] = "@(#)res_init.c    8.1 (Berkeley) 6/7/93";
  59. static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
  60. #else
  61. static char rcsid[] = "$NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $";
  62. #endif
  63. #endif /* LIBC_SCCS and not lint */
  64.  
  65. #include <sys/param.h>
  66. #include <sys/socket.h>
  67. #include <netinet/in.h>
  68. #include <arpa/inet.h>
  69. #include <arpa/nameser.h>
  70. #include <resolv.h>
  71. #include <unistd.h>
  72. #include <stdio.h>
  73. #include <stdlib.h>
  74. #include <string.h>
  75.  
  76. static void res_setoptions __P((char *, char *));
  77. static u_int32_t net_mask __P((struct in_addr));
  78.  
  79.  
  80. /*
  81.  * Set up default settings.  If the configuration file exist, the values
  82.  * there will have precedence.  Otherwise, the server address is set to
  83.  * INADDR_ANY and the default domain name comes from the gethostname().
  84.  *
  85.  * The configuration file should only be used if you want to redefine your
  86.  * domain or run without a server on your machine.
  87.  *
  88.  * Return 0 if completes successfully, -1 on error
  89.  */
  90. int res_init()
  91. {
  92.     register FILE *fp;
  93.     register char *cp, **pp, *net;
  94.     register int n;
  95.     char buf[BUFSIZ], buf2[BUFSIZ];
  96.     int nserv = 0;    /* number of nameserver records read from file */
  97.     int haveenv = 0;
  98.     int havesearch = 0;
  99.     int nsort = 0;
  100.  
  101.     _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
  102.     _res.nsaddr.sin_family = AF_INET;
  103.     _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
  104. #ifdef USELOOPBACK
  105.     _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
  106. #else
  107.     _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
  108. #endif
  109.     _res.nscount = 1;
  110.     _res.ndots = 1;
  111.     _res.pfcode = 0;
  112.     strncpy(_res.lookups, "f", sizeof _res.lookups);
  113.  
  114.     /* Allow user to override the local domain definition */
  115.     if ((cp = getenv("LOCALDOMAIN")) != NULL) {
  116.         (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
  117.         if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
  118.             *cp = '\0';
  119.         haveenv++;
  120.  
  121.         /*
  122.          * Set search list to be blank-separated strings
  123.          * from rest of env value.  Permits users of LOCALDOMAIN
  124.          * to still have a search list, and anyone to set the
  125.          * one that they want to use as an individual (even more
  126.          * important now that the rfc1535 stuff restricts searches)
  127.          */
  128.         cp = _res.defdname;
  129.         pp = _res.dnsrch;
  130.         *pp++ = cp;
  131.         for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
  132.             if (*cp == '\n')        /* silly backwards compat */
  133.                 break;
  134.             else if (*cp == ' ' || *cp == '\t') {
  135.                 *cp = 0;
  136.                 n = 1;
  137.             } else if (n) {
  138.                 *pp++ = cp;
  139.                 n = 0;
  140.                 havesearch = 1;
  141.             }
  142.         }
  143.         /* null terminate last domain if there are excess */
  144.         while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
  145.             cp++;
  146.         *cp = '\0';
  147.         *pp++ = 0;
  148.     }
  149.  
  150.     if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
  151.         strncpy(_res.lookups, "bf", sizeof _res.lookups);
  152.  
  153.         /* read the config file */
  154.         while (fgets(buf, sizeof(buf), fp) != NULL) {
  155.         /* skip comments */
  156.         if ((*buf == ';') || (*buf == '#'))
  157.             continue;
  158.         /* read default domain name */
  159.         if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
  160.             if (haveenv)    /* skip if have from environ */
  161.                 continue;
  162.             cp = buf + sizeof("domain") - 1;
  163.             while (*cp == ' ' || *cp == '\t')
  164.                 cp++;
  165.             if ((*cp == '\0') || (*cp == '\n'))
  166.                 continue;
  167.             (void)strncpy(_res.defdname, cp,
  168.                   sizeof(_res.defdname) - 1);
  169.             if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
  170.                 *cp = '\0';
  171.             havesearch = 0;
  172.             continue;
  173.         }
  174.         /* lookup types */
  175.         if (!strncmp(buf, "lookup", sizeof("lookup") -1)) {
  176.             char *sp = NULL;
  177.  
  178.             bzero(_res.lookups, sizeof _res.lookups);
  179.             cp = buf + sizeof("lookup") - 1;
  180.             for (n = 0;; cp++) {
  181.                     if (n == MAXDNSLUS)
  182.                     break;
  183.                 if ((*cp == '\0') || (*cp == '\n')) {
  184.                     if (sp) {
  185.                         if (*sp=='y' || *sp=='b' || *sp=='f')
  186.                             _res.lookups[n++] = *sp;
  187.                         sp = NULL;
  188.                     }
  189.                     break;
  190.                 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
  191.                     if (sp) {
  192.                         if (*sp=='y' || *sp=='b' || *sp=='f')
  193.                             _res.lookups[n++] = *sp;
  194.                         sp = NULL;
  195.                     }
  196.                 } else if (sp == NULL)
  197.                     sp = cp;
  198.             }
  199.             continue;
  200.         }
  201.         /* set search list */
  202.         if (!strncmp(buf, "search", sizeof("search") - 1)) {
  203.             if (haveenv)    /* skip if have from environ */
  204.                 continue;
  205.             cp = buf + sizeof("search") - 1;
  206.             while (*cp == ' ' || *cp == '\t')
  207.                 cp++;
  208.             if ((*cp == '\0') || (*cp == '\n'))
  209.                 continue;
  210.             (void)strncpy(_res.defdname, cp,
  211.                   sizeof(_res.defdname) - 1);
  212.             if ((cp = strchr(_res.defdname, '\n')) != NULL)
  213.                 *cp = '\0';
  214.             /*
  215.              * Set search list to be blank-separated strings
  216.              * on rest of line.
  217.              */
  218.             cp = _res.defdname;
  219.             pp = _res.dnsrch;
  220.             *pp++ = cp;
  221.             for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
  222.                 if (*cp == ' ' || *cp == '\t') {
  223.                     *cp = 0;
  224.                     n = 1;
  225.                 } else if (n) {
  226.                     *pp++ = cp;
  227.                     n = 0;
  228.                 }
  229.             }
  230.             /* null terminate last domain if there are excess */
  231.             while (*cp != '\0' && *cp != ' ' && *cp != '\t')
  232.                 cp++;
  233.             *cp = '\0';
  234.             *pp++ = 0;
  235.             havesearch = 1;
  236.             continue;
  237.         }
  238.         /* read nameservers to query */
  239.         if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
  240.            nserv < MAXNS) {
  241.            struct in_addr a;
  242.  
  243.             cp = buf + sizeof("nameserver") - 1;
  244.             while (*cp == ' ' || *cp == '\t')
  245.             cp++;
  246.             if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
  247.             _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in);
  248.             _res.nsaddr_list[nserv].sin_family = AF_INET;
  249.             _res.nsaddr_list[nserv].sin_port =
  250.                 htons(NAMESERVER_PORT);
  251.             _res.nsaddr_list[nserv].sin_addr = a;
  252.             nserv++;
  253.             }
  254.             continue;
  255.         }
  256.         if (!strncmp(buf, "sortlist", sizeof("sortlist") - 1)) {
  257.             struct in_addr a;
  258.  
  259.             cp = buf + sizeof("sortlist") - 1;
  260.             while (*cp == ' ' || *cp == '\t')
  261.             cp++;
  262.             while (sscanf(cp,"%[0-9./]s", buf2) && nsort < MAXRESOLVSORT) {
  263.             if ((net = strchr(buf2, '/')))
  264.                 *net = '\0';
  265.             if (inet_aton(buf2, &a)) {
  266.                 _res.sort_list[nsort].addr = a;
  267.                 if (net && inet_aton(net+1, &a)) {
  268.                 _res.sort_list[nsort].mask = a.s_addr;
  269.                 } else {
  270.                 _res.sort_list[nsort].mask =
  271.                     net_mask(_res.sort_list[nsort].addr);
  272.                 }
  273.                 nsort++;
  274.             }
  275.             if (net)
  276.                 *net = '/';
  277.             cp += strlen(buf2);
  278.             while (*cp == ' ' || *cp == '\t')
  279.                 cp++;
  280.             }
  281.             continue;
  282.         }
  283.         if (!strncmp(buf, "options", sizeof("options") -1)) {
  284.             res_setoptions(buf + sizeof("options") - 1, "conf");
  285.             continue;
  286.         }
  287.         }
  288.         if (nserv > 1) 
  289.         _res.nscount = nserv;
  290.         _res.nsort = nsort;
  291.         (void) fclose(fp);
  292.     }
  293.     if (_res.defdname[0] == 0) {
  294.         if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
  295.            (cp = strchr(buf, '.')))
  296.             (void)strcpy(_res.defdname, cp + 1);
  297.     }
  298.  
  299.     /* find components of local domain that might be searched */
  300.     if (havesearch == 0) {
  301.         pp = _res.dnsrch;
  302.         *pp++ = _res.defdname;
  303. #ifndef SEARCH_LOCAL_DOMAINS
  304.         *pp = NULL;
  305. #else
  306.         for (cp = _res.defdname, n = 0; *cp; cp++)
  307.             if (*cp == '.')
  308.                 n++;
  309.         cp = _res.defdname;
  310.         for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
  311.             n--) {
  312.             cp = strchr(cp, '.');
  313.             *pp++ = ++cp;
  314.         }
  315.         *pp++ = 0;
  316. #endif
  317.     }
  318.  
  319.     if ((cp = getenv("RES_OPTIONS")) != NULL)
  320.         res_setoptions(cp, "env");
  321.     _res.options |= RES_INIT;
  322.     return (0);
  323. }
  324.  
  325. static void
  326. res_setoptions(options, source)
  327.     char *options, *source;
  328. {
  329.     char *cp = options;
  330.     int i;
  331.  
  332. #ifdef DEBUG
  333.     if (_res.options & RES_DEBUG) {
  334.         printf(";; res_setoptions(\"%s\", \"%s\")...\n",
  335.                options, source);
  336.     }
  337. #endif
  338.     while (*cp) {
  339.         /* skip leading and inner runs of spaces */
  340.         while (*cp == ' ' || *cp == '\t')
  341.             cp++;
  342.         /* search for and process individual options */
  343.         if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) {
  344.             i = atoi(cp + sizeof("ndots:") - 1);
  345.             if (i <= RES_MAXNDOTS)
  346.                 _res.ndots = i;
  347.             else
  348.                 _res.ndots = RES_MAXNDOTS;
  349. #ifdef DEBUG
  350.             if (_res.options & RES_DEBUG) {
  351.                 printf(";;\tndots=%d\n", _res.ndots);
  352.             }
  353. #endif
  354.         } else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
  355. #ifdef DEBUG
  356.             if (!(_res.options & RES_DEBUG)) {
  357.                 printf(";; res_setoptions(\"%s\", \"%s\")..\n",
  358.                        options, source);
  359.                 _res.options |= RES_DEBUG;
  360.             }
  361.             printf(";;\tdebug\n");
  362. #endif
  363.         } else {
  364.             /* XXX - print a warning here? */
  365.         }
  366.         /* skip to next run of spaces */
  367.         while (*cp && *cp != ' ' && *cp != '\t')
  368.             cp++;
  369.     }
  370. }
  371.  
  372. static u_int32_t
  373. net_mask(in)        /* XXX - should really use system's version of this */
  374.     struct in_addr in;
  375. {
  376.     register u_int32_t i = ntohl(in.s_addr);
  377.  
  378.     if (IN_CLASSA(i))
  379.         return (htonl(IN_CLASSA_NET));
  380.     if (IN_CLASSB(i))
  381.         return (htonl(IN_CLASSB_NET));
  382.     return (htonl(IN_CLASSC_NET));
  383. }
  384.