Remove building with NOCRYPTO option
[minix.git] / external / bsd / dhcp / dist / common / resolv.c
blob91b117fc79744adfab502dbc9dc25d95c9fed416
1 /* $NetBSD: resolv.c,v 1.1.1.2 2014/07/12 11:57:46 spz Exp $ */
2 /* resolv.c
4 Parser for /etc/resolv.conf file. */
6 /*
7 * Copyright (c) 2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1996-2003 by Internet Software Consortium
11 * Permission to use, copy, modify, and distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies.
15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Internet Systems Consortium, Inc.
24 * 950 Charter Street
25 * Redwood City, CA 94063
26 * <info@isc.org>
27 * https://www.isc.org/
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: resolv.c,v 1.1.1.2 2014/07/12 11:57:46 spz Exp $");
34 #include "dhcpd.h"
36 struct name_server *name_servers;
37 struct domain_search_list *domains;
38 char path_resolv_conf [] = _PATH_RESOLV_CONF;
40 void read_resolv_conf (parse_time)
41 TIME parse_time;
43 int file;
44 struct parse *cfile;
45 const char *val;
46 int token;
47 struct name_server *sp, *sl, *ns;
48 struct domain_search_list *dp, *dl, *nd;
49 isc_result_t status;
51 if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
52 log_error ("Can't open %s: %m", path_resolv_conf);
53 return;
56 cfile = NULL;
57 status = new_parse(&cfile, file, NULL, 0, path_resolv_conf, 1);
58 if (status != ISC_R_SUCCESS || cfile == NULL)
59 return;
61 do {
62 token = next_token (&val, (unsigned *)0, cfile);
63 if (token == END_OF_FILE)
64 break;
65 else if (token == EOL)
66 continue;
67 else if (token == DOMAIN || token == SEARCH) {
68 do {
69 struct domain_search_list *nd, **dp;
70 char *dn;
72 dn = parse_host_name (cfile);
73 if (!dn)
74 break;
76 dp = &domains;
77 for (nd = domains; nd; nd = nd -> next) {
78 dp = &nd -> next;
79 if (!strcmp (nd -> domain, dn))
80 break;
82 if (!nd) {
83 nd = new_domain_search_list (MDL);
84 if (!nd)
85 log_fatal ("No memory for %s",
86 dn);
87 nd -> next =
88 (struct domain_search_list *)0;
89 *dp = nd;
90 nd -> domain = dn;
92 nd -> rcdate = parse_time;
93 token = peek_token (&val,
94 (unsigned *)0, cfile);
95 } while (token != EOL);
96 if (token != EOL) {
97 parse_warn (cfile,
98 "junk after domain declaration");
99 skip_to_semi (cfile);
101 skip_token(&val, (unsigned *)0, cfile);
102 } else if (token == NAMESERVER) {
103 struct name_server *ns, **sp;
104 struct iaddr iaddr;
106 parse_ip_addr (cfile, &iaddr);
108 sp = &name_servers;
109 for (ns = name_servers; ns; ns = ns -> next) {
110 sp = &ns -> next;
111 if (!memcmp (&ns -> addr.sin_addr,
112 iaddr.iabuf, iaddr.len))
113 break;
115 if (!ns) {
116 ns = new_name_server (MDL);
117 if (!ns)
118 log_fatal ("No memory for nameserver %s",
119 piaddr (iaddr));
120 ns -> next = (struct name_server *)0;
121 *sp = ns;
122 memcpy (&ns -> addr.sin_addr,
123 iaddr.iabuf, iaddr.len);
124 #ifdef HAVE_SA_LEN
125 ns -> addr.sin_len = sizeof ns -> addr;
126 #endif
127 ns -> addr.sin_family = AF_INET;
128 ns -> addr.sin_port = htons (53);
129 memset (ns -> addr.sin_zero, 0,
130 sizeof ns -> addr.sin_zero);
132 ns -> rcdate = parse_time;
133 skip_to_semi (cfile);
134 } else
135 skip_to_semi (cfile); /* Ignore what we don't grok. */
136 } while (1);
137 skip_token(&val, (unsigned *)0, cfile);
139 /* Lose servers that are no longer in /etc/resolv.conf. */
140 sl = (struct name_server *)0;
141 for (sp = name_servers; sp; sp = ns) {
142 ns = sp -> next;
143 if (sp -> rcdate != parse_time) {
144 if (sl)
145 sl -> next = sp -> next;
146 else
147 name_servers = sp -> next;
148 /* We can't actually free the name server structure,
149 because somebody might be hanging on to it. If
150 your /etc/resolv.conf file changes a lot, this
151 could be a noticeable memory leak. */
152 } else
153 sl = sp;
156 /* Lose domains that are no longer in /etc/resolv.conf. */
157 dl = (struct domain_search_list *)0;
158 for (dp = domains; dp; dp = nd) {
159 nd = dp -> next;
160 if (dp -> rcdate != parse_time) {
161 if (dl)
162 dl -> next = dp -> next;
163 else
164 domains = dp -> next;
165 free_domain_search_list (dp, MDL);
166 } else
167 dl = dp;
169 end_parse (&cfile);
172 /* Pick a name server from the /etc/resolv.conf file. */
174 struct name_server *first_name_server ()
176 static TIME rcdate;
177 struct stat st;
179 /* Check /etc/resolv.conf and reload it if it's changed. */
180 if (cur_time > rcdate) {
181 if (stat (path_resolv_conf, &st) < 0) {
182 log_error ("Can't stat %s", path_resolv_conf);
183 return (struct name_server *)0;
185 if (st.st_mtime > rcdate) {
186 rcdate = cur_time + 1;
188 read_resolv_conf (rcdate);
192 return name_servers;