]>
Commit | Line | Data |
---|---|---|
a7de06ee TL |
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[] = | |
8ae2d595 | 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"; |
a7de06ee TL |
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; | |
732a90b2 | 69 | if ((cfile = fopen (path_resolv_conf, "r")) == NULL) { |
8ae2d595 | 70 | log_error ("Can't open %s: %m", path_resolv_conf); |
732a90b2 TL |
71 | return; |
72 | } | |
73 | ||
a7de06ee TL |
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) | |
8ae2d595 | 99 | log_fatal ("No memory for %s", dn); |
a7de06ee TL |
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; | |
c5fc5996 | 107 | token = peek_token (&val, cfile); |
2c50133e | 108 | } while (token != EOL); |
a7de06ee TL |
109 | if (token != EOL) { |
110 | parse_warn ("junk after domain declaration"); | |
111 | skip_to_semi (cfile); | |
112 | } | |
2c50133e | 113 | token = next_token (&val, cfile); |
a7de06ee TL |
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) | |
8ae2d595 | 130 | log_fatal ("No memory for nameserver %s", |
a7de06ee TL |
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); | |
357708da TL |
146 | } else |
147 | skip_to_semi (cfile); /* Ignore what we don't grok. */ | |
a7de06ee TL |
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; | |
7e204261 TL |
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. */ | |
a7de06ee TL |
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 | ||
7e204261 | 186 | struct name_server *first_name_server () |
a7de06ee TL |
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) { | |
732a90b2 | 194 | if (stat (path_resolv_conf, &st) < 0) { |
8ae2d595 | 195 | log_error ("Can't stat %s", path_resolv_conf); |
7e204261 | 196 | return (struct name_server *)0; |
732a90b2 | 197 | } |
a7de06ee TL |
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 | ||
7e204261 | 207 | return name_servers; |
a7de06ee | 208 | } |