]> git.ipfire.org Git - thirdparty/dhcp.git/blob - common/resolv.c
Change names of error functions to be more consistent.
[thirdparty/dhcp.git] / common / resolv.c
1 /* resolv.c
2
3 Parser for /etc/resolv.conf file. */
4
5 /*
6 * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
38 * Enterprises. To learn more about the Internet Software Consortium,
39 * see ``http://www.vix.com/isc''. To learn more about Vixie
40 * Enterprises, see ``http://www.vix.com''.
41 */
42
43 #ifndef lint
44 static char copyright[] =
45 "$Id: resolv.c,v 1.7 1999/02/24 17:56:48 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
46 #endif /* not lint */
47
48 #include "dhcpd.h"
49 #include "dhctoken.h"
50
51 struct name_server *name_servers;
52 struct domain_search_list *domains;
53 char path_resolv_conf [] = _PATH_RESOLV_CONF;
54
55 void read_resolv_conf (parse_time)
56 TIME parse_time;
57 {
58 FILE *cfile;
59 char *val;
60 int token;
61 int declaration = 0;
62 struct name_server *sp, *sl, *ns;
63 struct domain_search_list *dp, *dl, *nd;
64 struct iaddr *iaddr;
65
66 new_parse (path_resolv_conf);
67
68 eol_token = 1;
69 if ((cfile = fopen (path_resolv_conf, "r")) == NULL) {
70 log_error ("Can't open %s: %m", path_resolv_conf);
71 return;
72 }
73
74 do {
75 token = next_token (&val, cfile);
76 if (token == EOF)
77 break;
78 else if (token == EOL)
79 continue;
80 else if (token == DOMAIN || token == SEARCH) {
81 do {
82 struct domain_search_list *nd, **dp;
83 char *dn;
84
85 dn = parse_host_name (cfile);
86 if (!dn)
87 break;
88
89 dp = &domains;
90 for (nd = domains; nd; nd = nd -> next) {
91 dp = &nd -> next;
92 if (!strcmp (nd -> domain, dn))
93 break;
94 }
95 if (!nd) {
96 nd = new_domain_search_list
97 ("read_resolv_conf");
98 if (!nd)
99 log_fatal ("No memory for %s", dn);
100 nd -> next =
101 (struct domain_search_list *)0;
102 *dp = nd;
103 nd -> domain = dn;
104 dn = (char *)0;
105 }
106 nd -> rcdate = parse_time;
107 token = peek_token (&val, cfile);
108 } while (token != EOL);
109 if (token != EOL) {
110 parse_warn ("junk after domain declaration");
111 skip_to_semi (cfile);
112 }
113 token = next_token (&val, cfile);
114 } else if (token == NAMESERVER) {
115 struct name_server *ns, **sp;
116 struct iaddr iaddr;
117
118 parse_ip_addr (cfile, &iaddr);
119
120 sp = &name_servers;
121 for (ns = name_servers; ns; ns = ns -> next) {
122 sp = &ns -> next;
123 if (!memcmp (&ns -> addr.sin_addr,
124 iaddr.iabuf, iaddr.len))
125 break;
126 }
127 if (!ns) {
128 ns = new_name_server ("read_resolv_conf");
129 if (!ns)
130 log_fatal ("No memory for nameserver %s",
131 piaddr (iaddr));
132 ns -> next = (struct name_server *)0;
133 *sp = ns;
134 memcpy (&ns -> addr.sin_addr,
135 iaddr.iabuf, iaddr.len);
136 #ifdef HAVE_SA_LEN
137 ns -> addr.sin_len = sizeof ns -> addr;
138 #endif
139 ns -> addr.sin_family = AF_INET;
140 ns -> addr.sin_port = htons (53);
141 memset (ns -> addr.sin_zero, 0,
142 sizeof ns -> addr.sin_zero);
143 }
144 ns -> rcdate = parse_time;
145 skip_to_semi (cfile);
146 } else
147 skip_to_semi (cfile); /* Ignore what we don't grok. */
148 } while (1);
149 token = next_token (&val, cfile); /* Clear the peek buffer */
150
151 /* Lose servers that are no longer in /etc/resolv.conf. */
152 sl = (struct name_server *)0;
153 for (sp = name_servers; sp; sp = ns) {
154 ns = sp -> next;
155 if (sp -> rcdate != parse_time) {
156 if (sl)
157 sl -> next = sp -> next;
158 else
159 name_servers = sp -> next;
160 /* We can't actually free the name server structure,
161 because somebody might be hanging on to it. If
162 your /etc/resolv.conf file changes a lot, this
163 could be a noticable memory leak. */
164 } else
165 sl = sp;
166 }
167
168 /* Lose domains that are no longer in /etc/resolv.conf. */
169 dl = (struct domain_search_list *)0;
170 for (dp = domains; dp; dp = nd) {
171 nd = dp -> next;
172 if (dp -> rcdate != parse_time) {
173 if (dl)
174 dl -> next = dp -> next;
175 else
176 domains = dp -> next;
177 free_domain_search_list (dp, "pick_name_server");
178 } else
179 dl = dp;
180 }
181 eol_token = 0;
182 }
183
184 /* Pick a name server from the /etc/resolv.conf file. */
185
186 struct name_server *first_name_server ()
187 {
188 FILE *rc;
189 static TIME rcdate;
190 struct stat st;
191
192 /* Check /etc/resolv.conf and reload it if it's changed. */
193 if (cur_time > rcdate) {
194 if (stat (path_resolv_conf, &st) < 0) {
195 log_error ("Can't stat %s", path_resolv_conf);
196 return (struct name_server *)0;
197 }
198 if (st.st_mtime > rcdate) {
199 char rcbuf [512];
200 char *s, *t, *u;
201 rcdate = cur_time + 1;
202
203 read_resolv_conf (rcdate);
204 }
205 }
206
207 return name_servers;
208 }