summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/res_init.c
diff options
context:
space:
mode:
authorderaadt <>1995-10-18 08:42:23 +0000
committerderaadt <>1995-10-18 08:42:23 +0000
commit0527d29da443886d92e9a418180c5b25a5f8d270 (patch)
tree86b3a64928451a669cefa27900e5884036b4e349 /src/lib/libc/net/res_init.c
downloadopenbsd-0527d29da443886d92e9a418180c5b25a5f8d270.tar.gz
openbsd-0527d29da443886d92e9a418180c5b25a5f8d270.tar.bz2
openbsd-0527d29da443886d92e9a418180c5b25a5f8d270.zip
initial import of NetBSD tree
Diffstat (limited to 'src/lib/libc/net/res_init.c')
-rw-r--r--src/lib/libc/net/res_init.c394
1 files changed, 394 insertions, 0 deletions
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c
new file mode 100644
index 0000000000..33cc8d39f1
--- /dev/null
+++ b/src/lib/libc/net/res_init.c
@@ -0,0 +1,394 @@
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
58static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
59static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
60#else
61static 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
76static void res_setoptions __P((char *, char *));
77static u_int32_t net_mask __P((struct in_addr));
78
79/*
80 * Resolver state default settings
81 */
82
83struct __res_state _res = {
84 RES_TIMEOUT, /* retransmition time interval */
85 4, /* number of times to retransmit */
86 RES_DEFAULT, /* options flags */
87 1, /* number of name servers */
88};
89
90/*
91 * Set up default settings. If the configuration file exist, the values
92 * there will have precedence. Otherwise, the server address is set to
93 * INADDR_ANY and the default domain name comes from the gethostname().
94 *
95 * The configuration file should only be used if you want to redefine your
96 * domain or run without a server on your machine.
97 *
98 * Return 0 if completes successfully, -1 on error
99 */
100res_init()
101{
102 register FILE *fp;
103 register char *cp, **pp, *net;
104 register int n;
105 char buf[BUFSIZ], buf2[BUFSIZ];
106 int nserv = 0; /* number of nameserver records read from file */
107 int haveenv = 0;
108 int havesearch = 0;
109 int nsort = 0;
110 u_long mask;
111
112 _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
113 _res.nsaddr.sin_family = AF_INET;
114 _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
115#ifdef USELOOPBACK
116 _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
117#else
118 _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
119#endif
120 _res.nscount = 1;
121 _res.ndots = 1;
122 _res.pfcode = 0;
123 strncpy(_res.lookups, "f", sizeof _res.lookups);
124
125 /* Allow user to override the local domain definition */
126 if ((cp = getenv("LOCALDOMAIN")) != NULL) {
127 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
128 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
129 *cp = '\0';
130 haveenv++;
131
132 /*
133 * Set search list to be blank-separated strings
134 * from rest of env value. Permits users of LOCALDOMAIN
135 * to still have a search list, and anyone to set the
136 * one that they want to use as an individual (even more
137 * important now that the rfc1535 stuff restricts searches)
138 */
139 cp = _res.defdname;
140 pp = _res.dnsrch;
141 *pp++ = cp;
142 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
143 if (*cp == '\n') /* silly backwards compat */
144 break;
145 else if (*cp == ' ' || *cp == '\t') {
146 *cp = 0;
147 n = 1;
148 } else if (n) {
149 *pp++ = cp;
150 n = 0;
151 havesearch = 1;
152 }
153 }
154 /* null terminate last domain if there are excess */
155 while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
156 cp++;
157 *cp = '\0';
158 *pp++ = 0;
159 }
160
161 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
162 strncpy(_res.lookups, "bf", sizeof _res.lookups);
163
164 /* read the config file */
165 while (fgets(buf, sizeof(buf), fp) != NULL) {
166 /* skip comments */
167 if ((*buf == ';') || (*buf == '#'))
168 continue;
169 /* read default domain name */
170 if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
171 if (haveenv) /* skip if have from environ */
172 continue;
173 cp = buf + sizeof("domain") - 1;
174 while (*cp == ' ' || *cp == '\t')
175 cp++;
176 if ((*cp == '\0') || (*cp == '\n'))
177 continue;
178 (void)strncpy(_res.defdname, cp,
179 sizeof(_res.defdname) - 1);
180 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
181 *cp = '\0';
182 havesearch = 0;
183 continue;
184 }
185 /* lookup types */
186 if (!strncmp(buf, "lookup", sizeof("lookup") -1)) {
187 char *sp = NULL;
188
189 bzero(_res.lookups, sizeof _res.lookups);
190 cp = buf + sizeof("lookup") - 1;
191 for (n = 0;; cp++) {
192 if (n == MAXDNSLUS)
193 break;
194 if ((*cp == '\0') || (*cp == '\n')) {
195 if (sp) {
196 if (*sp=='y' || *sp=='b' || *sp=='f')
197 _res.lookups[n++] = *sp;
198 sp = NULL;
199 }
200 break;
201 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
202 if (sp) {
203 if (*sp=='y' || *sp=='b' || *sp=='f')
204 _res.lookups[n++] = *sp;
205 sp = NULL;
206 }
207 } else if (sp == NULL)
208 sp = cp;
209 }
210 continue;
211 }
212 /* set search list */
213 if (!strncmp(buf, "search", sizeof("search") - 1)) {
214 if (haveenv) /* skip if have from environ */
215 continue;
216 cp = buf + sizeof("search") - 1;
217 while (*cp == ' ' || *cp == '\t')
218 cp++;
219 if ((*cp == '\0') || (*cp == '\n'))
220 continue;
221 (void)strncpy(_res.defdname, cp,
222 sizeof(_res.defdname) - 1);
223 if ((cp = strchr(_res.defdname, '\n')) != NULL)
224 *cp = '\0';
225 /*
226 * Set search list to be blank-separated strings
227 * on rest of line.
228 */
229 cp = _res.defdname;
230 pp = _res.dnsrch;
231 *pp++ = cp;
232 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
233 if (*cp == ' ' || *cp == '\t') {
234 *cp = 0;
235 n = 1;
236 } else if (n) {
237 *pp++ = cp;
238 n = 0;
239 }
240 }
241 /* null terminate last domain if there are excess */
242 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
243 cp++;
244 *cp = '\0';
245 *pp++ = 0;
246 havesearch = 1;
247 continue;
248 }
249 /* read nameservers to query */
250 if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
251 nserv < MAXNS) {
252 struct in_addr a;
253
254 cp = buf + sizeof("nameserver") - 1;
255 while (*cp == ' ' || *cp == '\t')
256 cp++;
257 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
258 _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in);
259 _res.nsaddr_list[nserv].sin_family = AF_INET;
260 _res.nsaddr_list[nserv].sin_port =
261 htons(NAMESERVER_PORT);
262 _res.nsaddr_list[nserv].sin_addr = a;
263 nserv++;
264 }
265 continue;
266 }
267 if (!strncmp(buf, "sortlist", sizeof("sortlist") - 1)) {
268 struct in_addr a;
269
270 cp = buf + sizeof("sortlist") - 1;
271 while (*cp == ' ' || *cp == '\t')
272 cp++;
273 while (sscanf(cp,"%[0-9./]s", buf2) && nsort < MAXRESOLVSORT) {
274 if (net = strchr(buf2, '/'))
275 *net = '\0';
276 if (inet_aton(buf2, &a)) {
277 _res.sort_list[nsort].addr = a;
278 if (net && inet_aton(net+1, &a)) {
279 _res.sort_list[nsort].mask = a.s_addr;
280 } else {
281 _res.sort_list[nsort].mask =
282 net_mask(_res.sort_list[nsort].addr);
283 }
284 nsort++;
285 }
286 if (net)
287 *net = '/';
288 cp += strlen(buf2);
289 while (*cp == ' ' || *cp == '\t')
290 cp++;
291 }
292 continue;
293 }
294 if (!strncmp(buf, "options", sizeof("options") -1)) {
295 res_setoptions(buf + sizeof("options") - 1, "conf");
296 continue;
297 }
298 }
299 if (nserv > 1)
300 _res.nscount = nserv;
301 _res.nsort = nsort;
302 (void) fclose(fp);
303 }
304 if (_res.defdname[0] == 0) {
305 if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
306 (cp = strchr(buf, '.')))
307 (void)strcpy(_res.defdname, cp + 1);
308 }
309
310 /* find components of local domain that might be searched */
311 if (havesearch == 0) {
312 pp = _res.dnsrch;
313 *pp++ = _res.defdname;
314#ifndef SEARCH_LOCAL_DOMAINS
315 *pp = NULL;
316#else
317 for (cp = _res.defdname, n = 0; *cp; cp++)
318 if (*cp == '.')
319 n++;
320 cp = _res.defdname;
321 for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
322 n--) {
323 cp = strchr(cp, '.');
324 *pp++ = ++cp;
325 }
326 *pp++ = 0;
327#endif
328 }
329
330 if ((cp = getenv("RES_OPTIONS")) != NULL)
331 res_setoptions(cp, "env");
332 _res.options |= RES_INIT;
333 return (0);
334}
335
336static void
337res_setoptions(options, source)
338 char *options, *source;
339{
340 char *cp = options;
341 int i;
342
343#ifdef DEBUG
344 if (_res.options & RES_DEBUG) {
345 printf(";; res_setoptions(\"%s\", \"%s\")...\n",
346 options, source);
347 }
348#endif
349 while (*cp) {
350 /* skip leading and inner runs of spaces */
351 while (*cp == ' ' || *cp == '\t')
352 cp++;
353 /* search for and process individual options */
354 if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) {
355 i = atoi(cp + sizeof("ndots:") - 1);
356 if (i <= RES_MAXNDOTS)
357 _res.ndots = i;
358 else
359 _res.ndots = RES_MAXNDOTS;
360#ifdef DEBUG
361 if (_res.options & RES_DEBUG) {
362 printf(";;\tndots=%d\n", _res.ndots);
363 }
364#endif
365 } else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
366#ifdef DEBUG
367 if (!(_res.options & RES_DEBUG)) {
368 printf(";; res_setoptions(\"%s\", \"%s\")..\n",
369 options, source);
370 _res.options |= RES_DEBUG;
371 }
372 printf(";;\tdebug\n");
373#endif
374 } else {
375 /* XXX - print a warning here? */
376 }
377 /* skip to next run of spaces */
378 while (*cp && *cp != ' ' && *cp != '\t')
379 cp++;
380 }
381}
382
383static u_int32_t
384net_mask(in) /* XXX - should really use system's version of this */
385 struct in_addr in;
386{
387 register u_int32_t i = ntohl(in.s_addr);
388
389 if (IN_CLASSA(i))
390 return (htonl(IN_CLASSA_NET));
391 if (IN_CLASSB(i))
392 return (htonl(IN_CLASSB_NET));
393 return (htonl(IN_CLASSC_NET));
394}