]> git.ipfire.org Git - thirdparty/dhcp.git/blame - common/resolv.c
Update license.
[thirdparty/dhcp.git] / common / resolv.c
CommitLineData
a7de06ee
TL
1/* resolv.c
2
3 Parser for /etc/resolv.conf file. */
4
5/*
f39b6e00
TL
6 * Copyright (c) 1996-1999 Internet Software Consortium.
7 * Use is subject to license terms which appear in the file named
8 * ISC-LICENSE that should have accompanied this file when you
9 * received it. If a file named ISC-LICENSE did not accompany this
10 * file, or you are not sure the one you have is correct, you may
11 * obtain an applicable copy of the license at:
a7de06ee 12 *
f39b6e00 13 * http://www.isc.org/isc-license-1.0.html.
a7de06ee 14 *
f39b6e00
TL
15 * This file is part of the ISC DHCP distribution. The documentation
16 * associated with this file is listed in the file DOCUMENTATION,
17 * included in the top-level directory of this release.
a7de06ee 18 *
f39b6e00
TL
19 * Support and other services are available for ISC products - see
20 * http://www.isc.org for more information.
a7de06ee
TL
21 */
22
23#ifndef lint
24static char copyright[] =
f39b6e00 25"$Id: resolv.c,v 1.8 1999/03/16 05:50:37 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
a7de06ee
TL
26#endif /* not lint */
27
28#include "dhcpd.h"
29#include "dhctoken.h"
30
31struct name_server *name_servers;
32struct domain_search_list *domains;
33char path_resolv_conf [] = _PATH_RESOLV_CONF;
34
35void read_resolv_conf (parse_time)
36 TIME parse_time;
37{
38 FILE *cfile;
39 char *val;
40 int token;
41 int declaration = 0;
42 struct name_server *sp, *sl, *ns;
43 struct domain_search_list *dp, *dl, *nd;
44 struct iaddr *iaddr;
45
46 new_parse (path_resolv_conf);
47
48 eol_token = 1;
732a90b2 49 if ((cfile = fopen (path_resolv_conf, "r")) == NULL) {
8ae2d595 50 log_error ("Can't open %s: %m", path_resolv_conf);
732a90b2
TL
51 return;
52 }
53
a7de06ee
TL
54 do {
55 token = next_token (&val, cfile);
56 if (token == EOF)
57 break;
58 else if (token == EOL)
59 continue;
60 else if (token == DOMAIN || token == SEARCH) {
61 do {
62 struct domain_search_list *nd, **dp;
63 char *dn;
64
65 dn = parse_host_name (cfile);
66 if (!dn)
67 break;
68
69 dp = &domains;
70 for (nd = domains; nd; nd = nd -> next) {
71 dp = &nd -> next;
72 if (!strcmp (nd -> domain, dn))
73 break;
74 }
75 if (!nd) {
76 nd = new_domain_search_list
77 ("read_resolv_conf");
78 if (!nd)
8ae2d595 79 log_fatal ("No memory for %s", dn);
a7de06ee
TL
80 nd -> next =
81 (struct domain_search_list *)0;
82 *dp = nd;
83 nd -> domain = dn;
84 dn = (char *)0;
85 }
86 nd -> rcdate = parse_time;
c5fc5996 87 token = peek_token (&val, cfile);
2c50133e 88 } while (token != EOL);
a7de06ee
TL
89 if (token != EOL) {
90 parse_warn ("junk after domain declaration");
91 skip_to_semi (cfile);
92 }
2c50133e 93 token = next_token (&val, cfile);
a7de06ee
TL
94 } else if (token == NAMESERVER) {
95 struct name_server *ns, **sp;
96 struct iaddr iaddr;
97
98 parse_ip_addr (cfile, &iaddr);
99
100 sp = &name_servers;
101 for (ns = name_servers; ns; ns = ns -> next) {
102 sp = &ns -> next;
103 if (!memcmp (&ns -> addr.sin_addr,
104 iaddr.iabuf, iaddr.len))
105 break;
106 }
107 if (!ns) {
108 ns = new_name_server ("read_resolv_conf");
109 if (!ns)
8ae2d595 110 log_fatal ("No memory for nameserver %s",
a7de06ee
TL
111 piaddr (iaddr));
112 ns -> next = (struct name_server *)0;
113 *sp = ns;
114 memcpy (&ns -> addr.sin_addr,
115 iaddr.iabuf, iaddr.len);
116#ifdef HAVE_SA_LEN
117 ns -> addr.sin_len = sizeof ns -> addr;
118#endif
119 ns -> addr.sin_family = AF_INET;
120 ns -> addr.sin_port = htons (53);
121 memset (ns -> addr.sin_zero, 0,
122 sizeof ns -> addr.sin_zero);
123 }
124 ns -> rcdate = parse_time;
125 skip_to_semi (cfile);
357708da
TL
126 } else
127 skip_to_semi (cfile); /* Ignore what we don't grok. */
a7de06ee
TL
128 } while (1);
129 token = next_token (&val, cfile); /* Clear the peek buffer */
130
131 /* Lose servers that are no longer in /etc/resolv.conf. */
132 sl = (struct name_server *)0;
133 for (sp = name_servers; sp; sp = ns) {
134 ns = sp -> next;
135 if (sp -> rcdate != parse_time) {
136 if (sl)
137 sl -> next = sp -> next;
138 else
139 name_servers = sp -> next;
7e204261
TL
140 /* We can't actually free the name server structure,
141 because somebody might be hanging on to it. If
142 your /etc/resolv.conf file changes a lot, this
143 could be a noticable memory leak. */
a7de06ee
TL
144 } else
145 sl = sp;
146 }
147
148 /* Lose domains that are no longer in /etc/resolv.conf. */
149 dl = (struct domain_search_list *)0;
150 for (dp = domains; dp; dp = nd) {
151 nd = dp -> next;
152 if (dp -> rcdate != parse_time) {
153 if (dl)
154 dl -> next = dp -> next;
155 else
156 domains = dp -> next;
157 free_domain_search_list (dp, "pick_name_server");
158 } else
159 dl = dp;
160 }
161 eol_token = 0;
162}
163
164/* Pick a name server from the /etc/resolv.conf file. */
165
7e204261 166struct name_server *first_name_server ()
a7de06ee
TL
167{
168 FILE *rc;
169 static TIME rcdate;
170 struct stat st;
171
172 /* Check /etc/resolv.conf and reload it if it's changed. */
173 if (cur_time > rcdate) {
732a90b2 174 if (stat (path_resolv_conf, &st) < 0) {
8ae2d595 175 log_error ("Can't stat %s", path_resolv_conf);
7e204261 176 return (struct name_server *)0;
732a90b2 177 }
a7de06ee
TL
178 if (st.st_mtime > rcdate) {
179 char rcbuf [512];
180 char *s, *t, *u;
181 rcdate = cur_time + 1;
182
183 read_resolv_conf (rcdate);
184 }
185 }
186
7e204261 187 return name_servers;
a7de06ee 188}