]>
Commit | Line | Data |
---|---|---|
28f540f4 | 1 | /* |
28f540f4 RM |
2 | * Copyright (c) 1985, 1989, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
4aebaa6b | 4 | * |
28f540f4 RM |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
28f540f4 RM |
13 | * 4. Neither the name of the University nor the names of its contributors |
14 | * may be used to endorse or promote products derived from this software | |
15 | * without specific prior written permission. | |
4aebaa6b | 16 | * |
28f540f4 RM |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | |
b43b13ac UD |
28 | */ |
29 | ||
30 | /* | |
28f540f4 | 31 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. |
4aebaa6b | 32 | * |
28f540f4 RM |
33 | * Permission to use, copy, modify, and distribute this software for any |
34 | * purpose with or without fee is hereby granted, provided that the above | |
35 | * copyright notice and this permission notice appear in all copies, and that | |
36 | * the name of Digital Equipment Corporation not be used in advertising or | |
37 | * publicity pertaining to distribution of the document or software without | |
38 | * specific, written prior permission. | |
4aebaa6b | 39 | * |
28f540f4 RM |
40 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL |
41 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | |
42 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | |
43 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
44 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | |
45 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |
46 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
47 | * SOFTWARE. | |
b43b13ac UD |
48 | */ |
49 | ||
50 | /* | |
51 | * Portions Copyright (c) 1996-1999 by Internet Software Consortium. | |
52 | * | |
53 | * Permission to use, copy, modify, and distribute this software for any | |
54 | * purpose with or without fee is hereby granted, provided that the above | |
55 | * copyright notice and this permission notice appear in all copies. | |
56 | * | |
57 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | |
58 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | |
59 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | |
60 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
61 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | |
62 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |
63 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
64 | * SOFTWARE. | |
28f540f4 RM |
65 | */ |
66 | ||
67 | #if defined(LIBC_SCCS) && !defined(lint) | |
b43b13ac | 68 | static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; |
e685e07d | 69 | static const char rcsid[] = "$BINDId: res_init.c,v 8.16 2000/05/09 07:10:12 vixie Exp $"; |
28f540f4 RM |
70 | #endif /* LIBC_SCCS and not lint */ |
71 | ||
df21c858 | 72 | #include <sys/types.h> |
28f540f4 RM |
73 | #include <sys/param.h> |
74 | #include <sys/socket.h> | |
3d61b63c | 75 | #include <sys/time.h> |
b43b13ac | 76 | |
28f540f4 RM |
77 | #include <netinet/in.h> |
78 | #include <arpa/inet.h> | |
79 | #include <arpa/nameser.h> | |
80 | ||
28f540f4 RM |
81 | #include <ctype.h> |
82 | #include <resolv.h> | |
b43b13ac | 83 | #include <stdio.h> |
2706ee38 | 84 | #include <stdio_ext.h> |
b43b13ac UD |
85 | #include <stdlib.h> |
86 | #include <string.h> | |
87 | #include <unistd.h> | |
28f540f4 | 88 | |
ce42435c UD |
89 | #include <not-cancel.h> |
90 | ||
b43b13ac UD |
91 | /* Options. Should all be left alone. */ |
92 | #define RESOLVSORT | |
93 | #define RFC1535 | |
e685e07d | 94 | /* #undef DEBUG */ |
28f540f4 | 95 | |
e685e07d | 96 | static void res_setoptions (res_state, const char *, const char *) |
b43b13ac | 97 | internal_function; |
28f540f4 | 98 | |
28f540f4 | 99 | #ifdef RESOLVSORT |
0f283ffc RM |
100 | static const char sort_mask_chars[] = "/&"; |
101 | #define ISSORTMASK(ch) (strchr(sort_mask_chars, ch) != NULL) | |
28f540f4 RM |
102 | static u_int32_t net_mask __P((struct in_addr)); |
103 | #endif | |
104 | ||
105 | #if !defined(isascii) /* XXX - could be a function */ | |
106 | # define isascii(c) (!(c & 0200)) | |
107 | #endif | |
108 | ||
770d9b39 UD |
109 | #ifdef _LIBC |
110 | unsigned long long int __res_initstamp attribute_hidden; | |
111 | #endif | |
112 | ||
28f540f4 RM |
113 | /* |
114 | * Resolver state default settings. | |
115 | */ | |
116 | ||
28f540f4 RM |
117 | /* |
118 | * Set up default settings. If the configuration file exist, the values | |
119 | * there will have precedence. Otherwise, the server address is set to | |
120 | * INADDR_ANY and the default domain name comes from the gethostname(). | |
121 | * | |
122 | * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 | |
123 | * rather than INADDR_ANY ("0.0.0.0") as the default name server address | |
124 | * since it was noted that INADDR_ANY actually meant ``the first interface | |
125 | * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, | |
126 | * it had to be "up" in order for you to reach your own name server. It | |
4aebaa6b | 127 | * was later decided that since the recommended practice is to always |
28f540f4 RM |
128 | * install local static routes through 127.0.0.1 for all your network |
129 | * interfaces, that we could solve this problem without a code change. | |
130 | * | |
131 | * The configuration file should always be used, since it is the only way | |
132 | * to specify a default domain. If you are running a server on your local | |
133 | * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" | |
134 | * in the configuration file. | |
135 | * | |
136 | * Return 0 if completes successfully, -1 on error | |
137 | */ | |
3d61b63c | 138 | int |
b43b13ac UD |
139 | res_ninit(res_state statp) { |
140 | extern int __res_vinit(res_state, int); | |
141 | ||
142 | return (__res_vinit(statp, 0)); | |
143 | } | |
37ba7d66 UD |
144 | #ifdef _LIBC |
145 | libc_hidden_def (__res_ninit) | |
146 | #endif | |
b43b13ac UD |
147 | |
148 | /* This function has to be reachable by res_data.c but not publically. */ | |
149 | int | |
150 | __res_vinit(res_state statp, int preinit) { | |
28f540f4 RM |
151 | register FILE *fp; |
152 | register char *cp, **pp; | |
3d61b63c | 153 | register int n; |
b43b13ac | 154 | char buf[BUFSIZ]; |
28f540f4 | 155 | int nserv = 0; /* number of nameserver records read from file */ |
438e8239 UD |
156 | #ifdef _LIBC |
157 | int nservall = 0; /* number of NS records read, nserv IPv4 only */ | |
158 | #endif | |
28f540f4 RM |
159 | int haveenv = 0; |
160 | int havesearch = 0; | |
161 | #ifdef RESOLVSORT | |
162 | int nsort = 0; | |
163 | char *net; | |
164 | #endif | |
3d61b63c RM |
165 | #ifndef RFC1535 |
166 | int dots; | |
167 | #endif | |
87bb6b6c | 168 | #ifdef _LIBC |
87bb6b6c UD |
169 | statp->_u._ext.initstamp = __res_initstamp; |
170 | #endif | |
28f540f4 | 171 | |
b43b13ac UD |
172 | if (!preinit) { |
173 | statp->retrans = RES_TIMEOUT; | |
174 | statp->retry = RES_DFLRETRY; | |
175 | statp->options = RES_DEFAULT; | |
176 | statp->id = res_randomid(); | |
177 | } | |
28f540f4 RM |
178 | |
179 | #ifdef USELOOPBACK | |
b43b13ac | 180 | statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); |
28f540f4 | 181 | #else |
b43b13ac | 182 | statp->nsaddr.sin_addr.s_addr = INADDR_ANY; |
28f540f4 | 183 | #endif |
b43b13ac UD |
184 | statp->nsaddr.sin_family = AF_INET; |
185 | statp->nsaddr.sin_port = htons(NAMESERVER_PORT); | |
186 | statp->nscount = 1; | |
187 | statp->ndots = 1; | |
188 | statp->pfcode = 0; | |
e685e07d | 189 | statp->_vcsock = -1; |
b43b13ac UD |
190 | statp->_flags = 0; |
191 | statp->qhook = NULL; | |
192 | statp->rhook = NULL; | |
03fbfeb5 | 193 | statp->_u._ext.nsinit = 0; |
e685e07d | 194 | statp->_u._ext.nscount = 0; |
438e8239 UD |
195 | #ifdef _LIBC |
196 | statp->_u._ext.nscount6 = 0; | |
b64e1566 UD |
197 | for (n = 0; n < MAXNS; n++) { |
198 | statp->_u._ext.nsaddrs[n] = NULL; | |
199 | statp->_u._ext.nsmap[n] = MAXNS; | |
200 | } | |
438e8239 | 201 | #endif |
28f540f4 RM |
202 | |
203 | /* Allow user to override the local domain definition */ | |
74955460 | 204 | if ((cp = getenv("LOCALDOMAIN")) != NULL) { |
b43b13ac UD |
205 | (void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); |
206 | statp->defdname[sizeof(statp->defdname) - 1] = '\0'; | |
28f540f4 RM |
207 | haveenv++; |
208 | ||
209 | /* | |
210 | * Set search list to be blank-separated strings | |
211 | * from rest of env value. Permits users of LOCALDOMAIN | |
212 | * to still have a search list, and anyone to set the | |
213 | * one that they want to use as an individual (even more | |
214 | * important now that the rfc1535 stuff restricts searches) | |
215 | */ | |
b43b13ac UD |
216 | cp = statp->defdname; |
217 | pp = statp->dnsrch; | |
28f540f4 | 218 | *pp++ = cp; |
b43b13ac | 219 | for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) { |
28f540f4 RM |
220 | if (*cp == '\n') /* silly backwards compat */ |
221 | break; | |
222 | else if (*cp == ' ' || *cp == '\t') { | |
223 | *cp = 0; | |
224 | n = 1; | |
225 | } else if (n) { | |
226 | *pp++ = cp; | |
227 | n = 0; | |
228 | havesearch = 1; | |
229 | } | |
230 | } | |
231 | /* null terminate last domain if there are excess */ | |
232 | while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') | |
233 | cp++; | |
234 | *cp = '\0'; | |
235 | *pp++ = 0; | |
236 | } | |
237 | ||
238 | #define MATCH(line, name) \ | |
239 | (!strncmp(line, name, sizeof(name) - 1) && \ | |
240 | (line[sizeof(name) - 1] == ' ' || \ | |
241 | line[sizeof(name) - 1] == '\t')) | |
242 | ||
ee8449f7 | 243 | if ((fp = fopen(_PATH_RESCONF, "rc")) != NULL) { |
2706ee38 UD |
244 | /* No threads use this stream. */ |
245 | __fsetlocking (fp, FSETLOCKING_BYCALLER); | |
28f540f4 | 246 | /* read the config file */ |
71412a8c | 247 | while (fgets_unlocked(buf, sizeof(buf), fp) != NULL) { |
28f540f4 RM |
248 | /* skip comments */ |
249 | if (*buf == ';' || *buf == '#') | |
250 | continue; | |
251 | /* read default domain name */ | |
252 | if (MATCH(buf, "domain")) { | |
253 | if (haveenv) /* skip if have from environ */ | |
254 | continue; | |
255 | cp = buf + sizeof("domain") - 1; | |
256 | while (*cp == ' ' || *cp == '\t') | |
257 | cp++; | |
258 | if ((*cp == '\0') || (*cp == '\n')) | |
259 | continue; | |
b43b13ac UD |
260 | strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); |
261 | statp->defdname[sizeof(statp->defdname) - 1] = '\0'; | |
262 | if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL) | |
28f540f4 RM |
263 | *cp = '\0'; |
264 | havesearch = 0; | |
265 | continue; | |
266 | } | |
267 | /* set search list */ | |
268 | if (MATCH(buf, "search")) { | |
269 | if (haveenv) /* skip if have from environ */ | |
270 | continue; | |
271 | cp = buf + sizeof("search") - 1; | |
272 | while (*cp == ' ' || *cp == '\t') | |
273 | cp++; | |
274 | if ((*cp == '\0') || (*cp == '\n')) | |
275 | continue; | |
b43b13ac UD |
276 | strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); |
277 | statp->defdname[sizeof(statp->defdname) - 1] = '\0'; | |
278 | if ((cp = strchr(statp->defdname, '\n')) != NULL) | |
279 | *cp = '\0'; | |
28f540f4 RM |
280 | /* |
281 | * Set search list to be blank-separated strings | |
282 | * on rest of line. | |
283 | */ | |
b43b13ac UD |
284 | cp = statp->defdname; |
285 | pp = statp->dnsrch; | |
28f540f4 | 286 | *pp++ = cp; |
b43b13ac | 287 | for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) { |
28f540f4 RM |
288 | if (*cp == ' ' || *cp == '\t') { |
289 | *cp = 0; | |
290 | n = 1; | |
291 | } else if (n) { | |
292 | *pp++ = cp; | |
293 | n = 0; | |
294 | } | |
295 | } | |
296 | /* null terminate last domain if there are excess */ | |
297 | while (*cp != '\0' && *cp != ' ' && *cp != '\t') | |
298 | cp++; | |
299 | *cp = '\0'; | |
300 | *pp++ = 0; | |
301 | havesearch = 1; | |
302 | continue; | |
303 | } | |
304 | /* read nameservers to query */ | |
438e8239 UD |
305 | #ifdef _LIBC |
306 | if (MATCH(buf, "nameserver") && nservall < MAXNS) { | |
307 | #else | |
28f540f4 | 308 | if (MATCH(buf, "nameserver") && nserv < MAXNS) { |
438e8239 | 309 | #endif |
28f540f4 RM |
310 | struct in_addr a; |
311 | ||
312 | cp = buf + sizeof("nameserver") - 1; | |
313 | while (*cp == ' ' || *cp == '\t') | |
314 | cp++; | |
4aebaa6b UD |
315 | if ((*cp != '\0') && (*cp != '\n') |
316 | && __inet_aton(cp, &a)) { | |
b43b13ac UD |
317 | statp->nsaddr_list[nserv].sin_addr = a; |
318 | statp->nsaddr_list[nserv].sin_family = AF_INET; | |
319 | statp->nsaddr_list[nserv].sin_port = | |
28f540f4 RM |
320 | htons(NAMESERVER_PORT); |
321 | nserv++; | |
438e8239 UD |
322 | #ifdef _LIBC |
323 | nservall++; | |
324 | } else { | |
325 | struct in6_addr a6; | |
326 | char *el; | |
327 | ||
328 | if ((el = strchr(cp, '\n')) != NULL) | |
329 | *el = '\0'; | |
330 | if ((*cp != '\0') && | |
331 | (inet_pton(AF_INET6, cp, &a6) > 0)) { | |
332 | struct sockaddr_in6 *sa6; | |
333 | ||
334 | sa6 = malloc(sizeof(*sa6)); | |
335 | if (sa6 != NULL) { | |
336 | sa6->sin6_addr = a6; | |
337 | sa6->sin6_family = AF_INET6; | |
338 | sa6->sin6_port = htons(NAMESERVER_PORT); | |
339 | statp->_u._ext.nsaddrs[nservall] = sa6; | |
438e8239 | 340 | statp->_u._ext.nssocks[nservall] = -1; |
b64e1566 | 341 | statp->_u._ext.nsmap[nservall] = MAXNS + 1; |
438e8239 UD |
342 | nservall++; |
343 | } | |
344 | } | |
345 | #endif | |
28f540f4 RM |
346 | } |
347 | continue; | |
348 | } | |
349 | #ifdef RESOLVSORT | |
350 | if (MATCH(buf, "sortlist")) { | |
351 | struct in_addr a; | |
352 | ||
353 | cp = buf + sizeof("sortlist") - 1; | |
354 | while (nsort < MAXRESOLVSORT) { | |
355 | while (*cp == ' ' || *cp == '\t') | |
356 | cp++; | |
357 | if (*cp == '\0' || *cp == '\n' || *cp == ';') | |
358 | break; | |
359 | net = cp; | |
3d61b63c | 360 | while (*cp && !ISSORTMASK(*cp) && *cp != ';' && |
28f540f4 RM |
361 | isascii(*cp) && !isspace(*cp)) |
362 | cp++; | |
363 | n = *cp; | |
364 | *cp = 0; | |
4aebaa6b | 365 | if (__inet_aton(net, &a)) { |
b43b13ac | 366 | statp->sort_list[nsort].addr = a; |
3d61b63c | 367 | if (ISSORTMASK(n)) { |
28f540f4 RM |
368 | *cp++ = n; |
369 | net = cp; | |
3d61b63c RM |
370 | while (*cp && *cp != ';' && |
371 | isascii(*cp) && !isspace(*cp)) | |
28f540f4 RM |
372 | cp++; |
373 | n = *cp; | |
374 | *cp = 0; | |
4aebaa6b | 375 | if (__inet_aton(net, &a)) { |
b43b13ac | 376 | statp->sort_list[nsort].mask = a.s_addr; |
28f540f4 | 377 | } else { |
4aebaa6b | 378 | statp->sort_list[nsort].mask = |
b43b13ac | 379 | net_mask(statp->sort_list[nsort].addr); |
28f540f4 RM |
380 | } |
381 | } else { | |
4aebaa6b | 382 | statp->sort_list[nsort].mask = |
b43b13ac | 383 | net_mask(statp->sort_list[nsort].addr); |
28f540f4 RM |
384 | } |
385 | nsort++; | |
386 | } | |
3d61b63c | 387 | *cp = n; |
28f540f4 RM |
388 | } |
389 | continue; | |
390 | } | |
391 | #endif | |
392 | if (MATCH(buf, "options")) { | |
b43b13ac | 393 | res_setoptions(statp, buf + sizeof("options") - 1, "conf"); |
28f540f4 RM |
394 | continue; |
395 | } | |
396 | } | |
4aebaa6b | 397 | if (nserv > 1) |
b43b13ac | 398 | statp->nscount = nserv; |
438e8239 UD |
399 | #ifdef _LIBC |
400 | if (nservall - nserv > 0) | |
401 | statp->_u._ext.nscount6 = nservall - nserv; | |
402 | #endif | |
28f540f4 | 403 | #ifdef RESOLVSORT |
b43b13ac | 404 | statp->nsort = nsort; |
28f540f4 RM |
405 | #endif |
406 | (void) fclose(fp); | |
407 | } | |
b43b13ac UD |
408 | if (statp->defdname[0] == 0 && |
409 | __gethostname(buf, sizeof(statp->defdname) - 1) == 0 && | |
28f540f4 | 410 | (cp = strchr(buf, '.')) != NULL) |
b43b13ac | 411 | strcpy(statp->defdname, cp + 1); |
28f540f4 RM |
412 | |
413 | /* find components of local domain that might be searched */ | |
414 | if (havesearch == 0) { | |
b43b13ac UD |
415 | pp = statp->dnsrch; |
416 | *pp++ = statp->defdname; | |
28f540f4 RM |
417 | *pp = NULL; |
418 | ||
419 | #ifndef RFC1535 | |
420 | dots = 0; | |
b43b13ac | 421 | for (cp = statp->defdname; *cp; cp++) |
28f540f4 RM |
422 | dots += (*cp == '.'); |
423 | ||
b43b13ac UD |
424 | cp = statp->defdname; |
425 | while (pp < statp->dnsrch + MAXDFLSRCH) { | |
28f540f4 RM |
426 | if (dots < LOCALDOMAINPARTS) |
427 | break; | |
c4563d2d | 428 | cp = __rawmemchr(cp, '.') + 1; /* we know there is one */ |
28f540f4 RM |
429 | *pp++ = cp; |
430 | dots--; | |
431 | } | |
432 | *pp = NULL; | |
433 | #ifdef DEBUG | |
b43b13ac | 434 | if (statp->options & RES_DEBUG) { |
28f540f4 | 435 | printf(";; res_init()... default dnsrch list:\n"); |
b43b13ac | 436 | for (pp = statp->dnsrch; *pp; pp++) |
28f540f4 RM |
437 | printf(";;\t%s\n", *pp); |
438 | printf(";;\t..END..\n"); | |
439 | } | |
b43b13ac | 440 | #endif |
28f540f4 RM |
441 | #endif /* !RFC1535 */ |
442 | } | |
443 | ||
74955460 | 444 | if ((cp = getenv("RES_OPTIONS")) != NULL) |
b43b13ac UD |
445 | res_setoptions(statp, cp, "env"); |
446 | statp->options |= RES_INIT; | |
28f540f4 RM |
447 | return (0); |
448 | } | |
449 | ||
450 | static void | |
dfd2257a | 451 | internal_function |
e685e07d | 452 | res_setoptions(res_state statp, const char *options, const char *source) { |
b43b13ac | 453 | const char *cp = options; |
28f540f4 RM |
454 | int i; |
455 | ||
456 | #ifdef DEBUG | |
b43b13ac | 457 | if (statp->options & RES_DEBUG) |
28f540f4 RM |
458 | printf(";; res_setoptions(\"%s\", \"%s\")...\n", |
459 | options, source); | |
460 | #endif | |
461 | while (*cp) { | |
462 | /* skip leading and inner runs of spaces */ | |
463 | while (*cp == ' ' || *cp == '\t') | |
464 | cp++; | |
465 | /* search for and process individual options */ | |
466 | if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) { | |
467 | i = atoi(cp + sizeof("ndots:") - 1); | |
468 | if (i <= RES_MAXNDOTS) | |
b43b13ac | 469 | statp->ndots = i; |
28f540f4 | 470 | else |
b43b13ac | 471 | statp->ndots = RES_MAXNDOTS; |
28f540f4 | 472 | #ifdef DEBUG |
b43b13ac UD |
473 | if (statp->options & RES_DEBUG) |
474 | printf(";;\tndots=%d\n", statp->ndots); | |
28f540f4 | 475 | #endif |
b43b13ac UD |
476 | } else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) { |
477 | i = atoi(cp + sizeof("timeout:") - 1); | |
478 | if (i <= RES_MAXRETRANS) | |
479 | statp->retrans = i; | |
480 | else | |
481 | statp->retrans = RES_MAXRETRANS; | |
482 | } else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){ | |
483 | i = atoi(cp + sizeof("attempts:") - 1); | |
484 | if (i <= RES_MAXRETRY) | |
485 | statp->retry = i; | |
486 | else | |
487 | statp->retry = RES_MAXRETRY; | |
28f540f4 RM |
488 | } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) { |
489 | #ifdef DEBUG | |
b43b13ac | 490 | if (!(statp->options & RES_DEBUG)) { |
28f540f4 RM |
491 | printf(";; res_setoptions(\"%s\", \"%s\")..\n", |
492 | options, source); | |
b43b13ac | 493 | statp->options |= RES_DEBUG; |
28f540f4 RM |
494 | } |
495 | printf(";;\tdebug\n"); | |
496 | #endif | |
fa0bc87c | 497 | } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { |
b43b13ac | 498 | statp->options |= RES_USE_INET6; |
ee778b56 UD |
499 | } else if (!strncmp(cp, "ip6-bytestring", |
500 | sizeof("ip6-bytestring") - 1)) { | |
501 | statp->options |= RES_USEBSTRING; | |
340ef046 UD |
502 | } else if (!strncmp(cp, "no-ip6-dotint", |
503 | sizeof("no-ip6-dotint") - 1)) { | |
504 | statp->options |= RES_NOIP6DOTINT; | |
0acb7b83 UD |
505 | } else if (!strncmp(cp, "ip6-dotint", |
506 | sizeof("ip6-dotint") - 1)) { | |
507 | statp->options &= ~RES_NOIP6DOTINT; | |
b43b13ac UD |
508 | } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) { |
509 | statp->options |= RES_ROTATE; | |
510 | } else if (!strncmp(cp, "no-check-names", | |
511 | sizeof("no-check-names") - 1)) { | |
512 | statp->options |= RES_NOCHECKNAME; | |
28f540f4 RM |
513 | } else { |
514 | /* XXX - print a warning here? */ | |
515 | } | |
516 | /* skip to next run of spaces */ | |
517 | while (*cp && *cp != ' ' && *cp != '\t') | |
518 | cp++; | |
519 | } | |
520 | } | |
521 | ||
522 | #ifdef RESOLVSORT | |
3d61b63c | 523 | /* XXX - should really support CIDR which means explicit masks always. */ |
28f540f4 RM |
524 | static u_int32_t |
525 | net_mask(in) /* XXX - should really use system's version of this */ | |
526 | struct in_addr in; | |
527 | { | |
528 | register u_int32_t i = ntohl(in.s_addr); | |
529 | ||
530 | if (IN_CLASSA(i)) | |
531 | return (htonl(IN_CLASSA_NET)); | |
532 | else if (IN_CLASSB(i)) | |
533 | return (htonl(IN_CLASSB_NET)); | |
534 | return (htonl(IN_CLASSC_NET)); | |
535 | } | |
536 | #endif | |
537 | ||
1f64ac13 | 538 | u_int |
b43b13ac | 539 | res_randomid(void) { |
3d61b63c RM |
540 | struct timeval now; |
541 | ||
50304ef0 UD |
542 | __gettimeofday(&now, NULL); |
543 | return (0xffff & (now.tv_sec ^ now.tv_usec ^ __getpid())); | |
3d61b63c | 544 | } |
37ba7d66 UD |
545 | #ifdef _LIBC |
546 | libc_hidden_def (__res_randomid) | |
547 | #endif | |
e685e07d | 548 | |
2a3d906e | 549 | |
e685e07d UD |
550 | /* |
551 | * This routine is for closing the socket if a virtual circuit is used and | |
552 | * the program wants to close it. This provides support for endhostent() | |
553 | * which expects to close the socket. | |
554 | * | |
555 | * This routine is not expected to be user visible. | |
556 | */ | |
557 | void | |
558 | res_nclose(res_state statp) { | |
559 | int ns; | |
560 | ||
4aebaa6b | 561 | if (statp->_vcsock >= 0) { |
ce42435c | 562 | close_not_cancel_no_status(statp->_vcsock); |
e685e07d UD |
563 | statp->_vcsock = -1; |
564 | statp->_flags &= ~(RES_F_VC | RES_F_CONN); | |
565 | } | |
438e8239 | 566 | #ifdef _LIBC |
b64e1566 | 567 | for (ns = 0; ns < MAXNS; ns++) |
438e8239 UD |
568 | #else |
569 | for (ns = 0; ns < statp->_u._ext.nscount; ns++) | |
570 | #endif | |
b64e1566 UD |
571 | if (statp->_u._ext.nsaddrs[ns] |
572 | && statp->_u._ext.nssocks[ns] != -1) { | |
ce42435c | 573 | close_not_cancel_no_status(statp->_u._ext.nssocks[ns]); |
e685e07d UD |
574 | statp->_u._ext.nssocks[ns] = -1; |
575 | } | |
03fbfeb5 | 576 | statp->_u._ext.nsinit = 0; |
e685e07d | 577 | } |
2a3d906e RM |
578 | #ifdef _LIBC |
579 | libc_hidden_def (__res_nclose) | |
580 | #endif | |
581 | ||
582 | #ifdef _LIBC | |
583 | # ifdef _LIBC_REENTRANT | |
584 | /* This is called when a thread is exiting to free resources held in _res. */ | |
585 | static void __attribute__ ((section ("__libc_thread_freeres_fn"))) | |
586 | res_thread_freeres (void) | |
587 | { | |
c30dcea1 RM |
588 | if (_res.nscount == 0) |
589 | /* Never called res_ninit. */ | |
590 | return; | |
591 | ||
2a3d906e RM |
592 | __res_nclose (&_res); /* Close any VC sockets. */ |
593 | ||
594 | for (int ns = 0; ns < MAXNS; ns++) | |
595 | if (_res._u._ext.nsaddrs[ns] != NULL) | |
596 | { | |
597 | free (_res._u._ext.nsaddrs[ns]); | |
598 | _res._u._ext.nsaddrs[ns] = NULL; | |
599 | } | |
600 | } | |
601 | text_set_element (__libc_thread_subfreeres, res_thread_freeres); | |
602 | text_set_element (__libc_subfreeres, res_thread_freeres); | |
603 | # endif | |
604 | #endif |