xref: /csrg-svn/lib/libc/net/res_init.c (revision 62540)
144329Sbloom /*-
2*62540Sbostic  * Copyright (c) 1985, 1989, 1993
3*62540Sbostic  *	The Regents of the University of California.  All rights reserved.
433679Sbostic  *
544329Sbloom  * %sccs.include.redist.c%
661023Skarels  * -
761023Skarels  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
861023Skarels  *
961023Skarels  * Permission to use, copy, modify, and distribute this software for any
1061023Skarels  * purpose with or without fee is hereby granted, provided that the above
1161023Skarels  * copyright notice and this permission notice appear in all copies, and that
1261023Skarels  * the name of Digital Equipment Corporation not be used in advertising or
1361023Skarels  * publicity pertaining to distribution of the document or software without
1461023Skarels  * specific, written prior permission.
1561023Skarels  *
1661023Skarels  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
1761023Skarels  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
1861023Skarels  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
1961023Skarels  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
2061023Skarels  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
2161023Skarels  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
2261023Skarels  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2361023Skarels  * SOFTWARE.
2461023Skarels  * -
2561023Skarels  * --Copyright--
2618548Sralph  */
2718548Sralph 
2826633Sdonn #if defined(LIBC_SCCS) && !defined(lint)
29*62540Sbostic static char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 06/07/93";
3061023Skarels static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel $";
3133679Sbostic #endif /* LIBC_SCCS and not lint */
3221386Sdist 
3346604Sbostic #include <sys/param.h>
3418142Sralph #include <sys/socket.h>
3518142Sralph #include <netinet/in.h>
3646604Sbostic #include <arpa/inet.h>
3724081Skjd #include <arpa/nameser.h>
3826902Skjd #include <resolv.h>
3946604Sbostic #include <unistd.h>
4046604Sbostic #include <stdio.h>
4146604Sbostic #include <stdlib.h>
4246604Sbostic #include <string.h>
4318142Sralph 
4418142Sralph /*
4518142Sralph  * Resolver state default settings
4618142Sralph  */
4725242Skjd 
4861023Skarels struct __res_state _res = {
4939708Skarels 	RES_TIMEOUT,               	/* retransmition time interval */
5039708Skarels 	4,                         	/* number of times to retransmit */
5139708Skarels 	RES_DEFAULT,			/* options flags */
5239708Skarels 	1,                         	/* number of name servers */
5318142Sralph };
5418142Sralph 
5518142Sralph /*
5624736Sbloom  * Set up default settings.  If the configuration file exist, the values
5724736Sbloom  * there will have precedence.  Otherwise, the server address is set to
5824736Sbloom  * INADDR_ANY and the default domain name comes from the gethostname().
5924736Sbloom  *
6024736Sbloom  * The configuration file should only be used if you want to redefine your
6124736Sbloom  * domain or run without a server on your machine.
6224736Sbloom  *
6324736Sbloom  * Return 0 if completes successfully, -1 on error
6418142Sralph  */
res_init()6518142Sralph res_init()
6618142Sralph {
6739708Skarels 	register FILE *fp;
6839708Skarels 	register char *cp, **pp;
6939708Skarels 	register int n;
7039708Skarels 	char buf[BUFSIZ];
7139708Skarels 	int nserv = 0;    /* number of nameserver records read from file */
7239717Skarels 	int haveenv = 0;
7339708Skarels 	int havesearch = 0;
7418142Sralph 
7561023Skarels #ifdef USELOOPBACK
7661023Skarels 	_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
7761023Skarels #else
7839708Skarels 	_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
7961023Skarels #endif
8039708Skarels 	_res.nsaddr.sin_family = AF_INET;
8139708Skarels 	_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
8239708Skarels 	_res.nscount = 1;
8361023Skarels 	_res.pfcode = 0;
8418142Sralph 
8539708Skarels 	/* Allow user to override the local domain definition */
8639717Skarels 	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
8739708Skarels 		(void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
8861023Skarels 		if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
8961023Skarels 			*cp = '\0';
9039717Skarels 		haveenv++;
9139717Skarels 	}
9218142Sralph 
9339708Skarels 	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
9439708Skarels 	    /* read the config file */
9539708Skarels 	    while (fgets(buf, sizeof(buf), fp) != NULL) {
9661023Skarels 		/* skip comments */
9761023Skarels 		if ((*buf == ';') || (*buf == '#'))
9861023Skarels 			continue;
9939708Skarels 		/* read default domain name */
10039708Skarels 		if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
10139717Skarels 		    if (haveenv)	/* skip if have from environ */
10239708Skarels 			    continue;
10339708Skarels 		    cp = buf + sizeof("domain") - 1;
10439708Skarels 		    while (*cp == ' ' || *cp == '\t')
10539708Skarels 			    cp++;
10639791Sbloom 		    if ((*cp == '\0') || (*cp == '\n'))
10739708Skarels 			    continue;
10861023Skarels 		    (void)strncpy(_res.defdname, cp,
10961023Skarels 				  sizeof(_res.defdname) - 1);
11061023Skarels 		    if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
11139708Skarels 			    *cp = '\0';
11239708Skarels 		    havesearch = 0;
11339708Skarels 		    continue;
11439708Skarels 		}
11539708Skarels 		/* set search list */
11639708Skarels 		if (!strncmp(buf, "search", sizeof("search") - 1)) {
11739717Skarels 		    if (haveenv)	/* skip if have from environ */
11839717Skarels 			    continue;
11939708Skarels 		    cp = buf + sizeof("search") - 1;
12039708Skarels 		    while (*cp == ' ' || *cp == '\t')
12139708Skarels 			    cp++;
12239791Sbloom 		    if ((*cp == '\0') || (*cp == '\n'))
12339708Skarels 			    continue;
12461023Skarels 		    (void)strncpy(_res.defdname, cp,
12561023Skarels 				  sizeof(_res.defdname) - 1);
12662539Sbostic 		    if ((cp = strchr(_res.defdname, '\n')) != NULL)
12739708Skarels 			    *cp = '\0';
12839708Skarels 		    /*
12939708Skarels 		     * Set search list to be blank-separated strings
13039708Skarels 		     * on rest of line.
13139708Skarels 		     */
13239708Skarels 		    cp = _res.defdname;
13339708Skarels 		    pp = _res.dnsrch;
13439708Skarels 		    *pp++ = cp;
13539708Skarels 		    for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
13639708Skarels 			    if (*cp == ' ' || *cp == '\t') {
13739708Skarels 				    *cp = 0;
13839708Skarels 				    n = 1;
13939708Skarels 			    } else if (n) {
14039708Skarels 				    *pp++ = cp;
14139708Skarels 				    n = 0;
14239708Skarels 			    }
14339708Skarels 		    }
14444329Sbloom 		    /* null terminate last domain if there are excess */
14544329Sbloom 		    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
14644329Sbloom 			    cp++;
14744329Sbloom 		    *cp = '\0';
14839717Skarels 		    *pp++ = 0;
14939708Skarels 		    havesearch = 1;
15039708Skarels 		    continue;
15139708Skarels 		}
15239708Skarels 		/* read nameservers to query */
15339708Skarels 		if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
15439708Skarels 		   nserv < MAXNS) {
15561023Skarels 		   struct in_addr a;
15661023Skarels 
15739708Skarels 		    cp = buf + sizeof("nameserver") - 1;
15839708Skarels 		    while (*cp == ' ' || *cp == '\t')
15961023Skarels 			cp++;
16061023Skarels 		    if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
16161023Skarels 			_res.nsaddr_list[nserv].sin_addr = a;
16261023Skarels 			_res.nsaddr_list[nserv].sin_family = AF_INET;
16361023Skarels 			_res.nsaddr_list[nserv].sin_port =
16461023Skarels 				htons(NAMESERVER_PORT);
16561023Skarels 			nserv++;
16642258Sbloom 		    }
16739708Skarels 		    continue;
16839708Skarels 		}
16939708Skarels 	    }
17039708Skarels 	    if (nserv > 1)
17139708Skarels 		_res.nscount = nserv;
17239708Skarels 	    (void) fclose(fp);
17339708Skarels 	}
17439708Skarels 	if (_res.defdname[0] == 0) {
17539708Skarels 		if (gethostname(buf, sizeof(_res.defdname)) == 0 &&
17662539Sbostic 		   (cp = strchr(buf, '.')))
17739708Skarels 			(void)strcpy(_res.defdname, cp + 1);
17839708Skarels 	}
17931112Skarels 
18039708Skarels 	/* find components of local domain that might be searched */
18139708Skarels 	if (havesearch == 0) {
18239708Skarels 		pp = _res.dnsrch;
18339708Skarels 		*pp++ = _res.defdname;
18439708Skarels 		for (cp = _res.defdname, n = 0; *cp; cp++)
18539708Skarels 			if (*cp == '.')
18639708Skarels 				n++;
18739708Skarels 		cp = _res.defdname;
18839717Skarels 		for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
18939708Skarels 		    n--) {
19062539Sbostic 			cp = strchr(cp, '.');
19139708Skarels 			*pp++ = ++cp;
19239708Skarels 		}
19339717Skarels 		*pp++ = 0;
19439708Skarels 	}
19539708Skarels 	_res.options |= RES_INIT;
19639708Skarels 	return (0);
19718142Sralph }
198