Fix c-ares failing to get the search sequence of /etc/hosts and

DNS from /etc/nsswitch.conf, /etc/host.conf or /etc/svc.conf when
/etc/resolv.conf did not exist or was unable to read it.
This commit is contained in:
Yang Tse 2007-02-13 16:14:25 +00:00
parent 5649b738be
commit ecbc7f89c0
2 changed files with 82 additions and 32 deletions

View File

@ -1,5 +1,11 @@
Changelog for the c-ares project Changelog for the c-ares project
* February 13
- Yang Tse: Fix failure to get the search sequence of /etc/hosts and
DNS from /etc/nsswitch.conf, /etc/host.conf or /etc/svc.conf when
/etc/resolv.conf did not exist or was unable to read it.
* November 22 * November 22
- Install ares_dns.h too - Install ares_dns.h too

View File

@ -574,7 +574,7 @@ DhcpNameServer
do { do {
space = strchr(pos, ' '); space = strchr(pos, ' ');
if (space) if (space)
*space = 0; *space = '\0';
status = config_nameserver(&servers, &nservers, pos); status = config_nameserver(&servers, &nservers, pos);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
break; break;
@ -612,30 +612,41 @@ DhcpNameServer
int linesize; int linesize;
fp = fopen(PATH_RESOLV_CONF, "r"); fp = fopen(PATH_RESOLV_CONF, "r");
if (!fp) if (fp) {
return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE; while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) {
{ if ((p = try_config(line, "domain")) && channel->ndomains == -1)
if ((p = try_config(line, "domain")) && channel->ndomains == -1) status = config_domain(channel, p);
status = config_domain(channel, p); else if ((p = try_config(line, "lookup")) && !channel->lookups)
else if ((p = try_config(line, "lookup")) && !channel->lookups) status = config_lookup(channel, p, "bind", "file");
status = config_lookup(channel, p, "bind", "file"); else if ((p = try_config(line, "search")) && channel->ndomains == -1)
else if ((p = try_config(line, "search")) && channel->ndomains == -1) status = set_search(channel, p);
status = set_search(channel, p); else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1) status = config_nameserver(&servers, &nservers, p);
status = config_nameserver(&servers, &nservers, p); else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
else if ((p = try_config(line, "sortlist")) && channel->nsort == -1) status = config_sortlist(&sortlist, &nsort, p);
status = config_sortlist(&sortlist, &nsort, p); else if ((p = try_config(line, "options")))
else if ((p = try_config(line, "options"))) status = set_options(channel, p);
status = set_options(channel, p); else
else status = ARES_SUCCESS;
status = ARES_SUCCESS; if (status != ARES_SUCCESS)
if (status != ARES_SUCCESS) break;
break; }
fclose(fp);
}
else {
switch(errno) {
case ENOENT:
status = ARES_EOF;
break;
default:
DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
DEBUGF(fprintf(stderr, "fopen() failed with error: %d\n", errno));
status = ARES_EFILE;
}
} }
fclose(fp);
if (!channel->lookups) { if ((status == ARES_EOF) && (!channel->lookups)) {
/* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */ /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
fp = fopen("/etc/nsswitch.conf", "r"); fp = fopen("/etc/nsswitch.conf", "r");
if (fp) { if (fp) {
@ -646,9 +657,20 @@ DhcpNameServer
} }
fclose(fp); fclose(fp);
} }
else {
switch(errno) {
case ENOENT:
status = ARES_EOF;
break;
default:
DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
DEBUGF(fprintf(stderr, "fopen() failed with error: %d\n", errno));
status = ARES_EFILE;
}
}
} }
if (!channel->lookups) { if ((status == ARES_EOF) && (!channel->lookups)) {
/* Linux / GNU libc 2.x and possibly others have host.conf */ /* Linux / GNU libc 2.x and possibly others have host.conf */
fp = fopen("/etc/host.conf", "r"); fp = fopen("/etc/host.conf", "r");
if (fp) { if (fp) {
@ -659,9 +681,20 @@ DhcpNameServer
} }
fclose(fp); fclose(fp);
} }
else {
switch(errno) {
case ENOENT:
status = ARES_EOF;
break;
default:
DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
DEBUGF(fprintf(stderr, "fopen() failed with error: %d\n", errno));
status = ARES_EFILE;
}
}
} }
if (!channel->lookups) { if ((status == ARES_EOF) && (!channel->lookups)) {
/* Tru64 uses /etc/svc.conf */ /* Tru64 uses /etc/svc.conf */
fp = fopen("/etc/svc.conf", "r"); fp = fopen("/etc/svc.conf", "r");
if (fp) { if (fp) {
@ -672,6 +705,17 @@ DhcpNameServer
} }
fclose(fp); fclose(fp);
} }
else {
switch(errno) {
case ENOENT:
status = ARES_EOF;
break;
default:
DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
DEBUGF(fprintf(stderr, "fopen() failed with error: %d\n", errno));
status = ARES_EFILE;
}
}
} }
if(line) if(line)
@ -785,7 +829,7 @@ static int config_domain(ares_channel channel, char *str)
q = str; q = str;
while (*q && !ISSPACE(*q)) while (*q && !ISSPACE(*q))
q++; q++;
*q = 0; *q = '\0';
return set_search(channel, str); return set_search(channel, str);
} }
@ -812,7 +856,7 @@ static int config_lookup(ares_channel channel, const char *str,
while (*p && (ISSPACE(*p) || (*p == ','))) while (*p && (ISSPACE(*p) || (*p == ',')))
p++; p++;
} }
*l = 0; *l = '\0';
channel->lookups = strdup(lookups); channel->lookups = strdup(lookups);
return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM; return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
} }
@ -839,7 +883,7 @@ static int config_nameserver(struct server_state **servers, int *nservers,
if (*p) if (*p)
{ {
*p = 0; *p = '\0';
more = 1; more = 1;
} }
@ -897,7 +941,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
while (*q && *q != '/' && *q != ';' && !ISSPACE(*q)) while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
q++; q++;
memcpy(ipbuf, str, (int)(q-str)); memcpy(ipbuf, str, (int)(q-str));
ipbuf[(int)(q-str)] = 0; ipbuf[(int)(q-str)] = '\0';
/* Find the prefix */ /* Find the prefix */
if (*q == '/') if (*q == '/')
{ {
@ -905,11 +949,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
while (*q && *q != ';' && !ISSPACE(*q)) while (*q && *q != ';' && !ISSPACE(*q))
q++; q++;
memcpy(ipbufpfx, str, (int)(q-str)); memcpy(ipbufpfx, str, (int)(q-str));
ipbufpfx[(int)(q-str)] = 0; ipbufpfx[(int)(q-str)] = '\0';
str = str2; str = str2;
} }
else else
ipbufpfx[0] = 0; ipbufpfx[0] = '\0';
/* Lets see if it is CIDR */ /* Lets see if it is CIDR */
/* First we'll try IPv6 */ /* First we'll try IPv6 */
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx ? ipbufpfx : ipbuf, if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx ? ipbufpfx : ipbuf,
@ -938,7 +982,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
if (ipbufpfx) if (ipbufpfx)
{ {
memcpy(ipbuf, str, (int)(q-str)); memcpy(ipbuf, str, (int)(q-str));
ipbuf[(int)(q-str)] = 0; ipbuf[(int)(q-str)] = '\0';
if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr.addr4) != 0) if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr.addr4) != 0)
natural_mask(&pat); natural_mask(&pat);
} }