00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "dhcpd.h"
00031
00032 struct name_server *name_servers;
00033 struct domain_search_list *domains;
00034 char path_resolv_conf [] = _PATH_RESOLV_CONF;
00035
00036 void read_resolv_conf (parse_time)
00037 TIME parse_time;
00038 {
00039 int file;
00040 struct parse *cfile;
00041 const char *val;
00042 int token;
00043 struct name_server *sp, *sl, *ns;
00044 struct domain_search_list *dp, *dl, *nd;
00045 isc_result_t status;
00046
00047 if ((file = open (path_resolv_conf, O_RDONLY | O_CLOEXEC)) < 0) {
00048 log_error ("Can't open %s: %m", path_resolv_conf);
00049 return;
00050 }
00051
00052 cfile = NULL;
00053 status = new_parse(&cfile, file, NULL, 0, path_resolv_conf, 1);
00054 if (status != ISC_R_SUCCESS || cfile == NULL)
00055 return;
00056
00057 do {
00058 token = next_token (&val, (unsigned *)0, cfile);
00059 if (token == END_OF_FILE)
00060 break;
00061 else if (token == EOL)
00062 continue;
00063 else if (token == DOMAIN || token == SEARCH) {
00064 do {
00065 struct domain_search_list *nd, **dp;
00066 char *dn;
00067
00068 dn = parse_host_name (cfile);
00069 if (!dn)
00070 break;
00071
00072 dp = &domains;
00073 for (nd = domains; nd; nd = nd -> next) {
00074 dp = &nd -> next;
00075 if (!strcmp (nd -> domain, dn))
00076 break;
00077 }
00078 if (!nd) {
00079 nd = new_domain_search_list (MDL);
00080 if (!nd)
00081 log_fatal ("No memory for %s",
00082 dn);
00083 nd -> next =
00084 (struct domain_search_list *)0;
00085 *dp = nd;
00086 nd -> domain = dn;
00087 }
00088 nd -> rcdate = parse_time;
00089 token = peek_token (&val,
00090 (unsigned *)0, cfile);
00091 } while (token != EOL);
00092 if (token != EOL) {
00093 parse_warn (cfile,
00094 "junk after domain declaration");
00095 skip_to_semi (cfile);
00096 }
00097 skip_token(&val, (unsigned *)0, cfile);
00098 } else if (token == NAMESERVER) {
00099 struct name_server *ns, **sp;
00100 struct iaddr iaddr;
00101
00102 parse_ip_addr (cfile, &iaddr);
00103
00104 sp = &name_servers;
00105 for (ns = name_servers; ns; ns = ns -> next) {
00106 sp = &ns -> next;
00107 if (!memcmp (&ns -> addr.sin_addr,
00108 iaddr.iabuf, iaddr.len))
00109 break;
00110 }
00111 if (!ns) {
00112 ns = new_name_server (MDL);
00113 if (!ns)
00114 log_fatal ("No memory for nameserver %s",
00115 piaddr (iaddr));
00116 ns -> next = (struct name_server *)0;
00117 *sp = ns;
00118 memcpy (&ns -> addr.sin_addr,
00119 iaddr.iabuf, iaddr.len);
00120 #ifdef HAVE_SA_LEN
00121 ns -> addr.sin_len = sizeof ns -> addr;
00122 #endif
00123 ns -> addr.sin_family = AF_INET;
00124 ns -> addr.sin_port = htons (53);
00125 memset (ns -> addr.sin_zero, 0,
00126 sizeof ns -> addr.sin_zero);
00127 }
00128 ns -> rcdate = parse_time;
00129 skip_to_semi (cfile);
00130 } else
00131 skip_to_semi (cfile);
00132 } while (1);
00133 skip_token(&val, (unsigned *)0, cfile);
00134
00135
00136 sl = (struct name_server *)0;
00137 for (sp = name_servers; sp; sp = ns) {
00138 ns = sp -> next;
00139 if (sp -> rcdate != parse_time) {
00140 if (sl)
00141 sl -> next = sp -> next;
00142 else
00143 name_servers = sp -> next;
00144
00145
00146
00147
00148 } else
00149 sl = sp;
00150 }
00151
00152
00153 dl = (struct domain_search_list *)0;
00154 for (dp = domains; dp; dp = nd) {
00155 nd = dp -> next;
00156 if (dp -> rcdate != parse_time) {
00157 if (dl)
00158 dl -> next = dp -> next;
00159 else
00160 domains = dp -> next;
00161 free_domain_search_list (dp, MDL);
00162 } else
00163 dl = dp;
00164 }
00165 end_parse (&cfile);
00166 }
00167
00168
00169
00170 struct name_server *first_name_server ()
00171 {
00172 static TIME rcdate;
00173 struct stat st;
00174
00175
00176 if (cur_time > rcdate) {
00177 if (stat (path_resolv_conf, &st) < 0) {
00178 log_error ("Can't stat %s", path_resolv_conf);
00179 return (struct name_server *)0;
00180 }
00181 if (st.st_mtime > rcdate) {
00182 rcdate = cur_time + 1;
00183
00184 read_resolv_conf (rcdate);
00185 }
00186 }
00187
00188 return name_servers;
00189 }