Parse resolv.conf with new lineread implementation

Switch the resolv.conf parsing in conf.c to use the new lineread
implementation.  This means that it can now handle a resolv.conf file which
contains blank lines.

There are quite a few other fragilities with the resolv.conf parsing, but
that's out of scope for this patch.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
David Gibson 2022-06-24 12:17:30 +10:00 committed by Stefano Brivio
parent dab2c6ee1f
commit c589917e71

22
conf.c
View file

@ -38,6 +38,7 @@
#include "udp.h" #include "udp.h"
#include "tcp.h" #include "tcp.h"
#include "pasta.h" #include "pasta.h"
#include "lineread.h"
/** /**
* get_bound_ports() - Get maps of ports with bound sockets * get_bound_ports() - Get maps of ports with bound sockets
@ -320,7 +321,9 @@ static void get_dns(struct ctx *c)
struct in6_addr *dns6 = &c->dns6[0]; struct in6_addr *dns6 = &c->dns6[0];
struct fqdn *s = c->dns_search; struct fqdn *s = c->dns_search;
uint32_t *dns4 = &c->dns4[0]; uint32_t *dns4 = &c->dns4[0];
char buf[BUFSIZ], *p, *end; struct lineread resolvconf;
int line_len;
char *line, *p, *end;
dns4_set = !c->v4 || !!*dns4; dns4_set = !c->v4 || !!*dns4;
dns6_set = !c->v6 || !IN6_IS_ADDR_UNSPECIFIED(dns6); dns6_set = !c->v6 || !IN6_IS_ADDR_UNSPECIFIED(dns6);
@ -333,13 +336,14 @@ static void get_dns(struct ctx *c)
if ((fd = open("/etc/resolv.conf", O_RDONLY | O_CLOEXEC)) < 0) if ((fd = open("/etc/resolv.conf", O_RDONLY | O_CLOEXEC)) < 0)
goto out; goto out;
for (*buf = 0; line_read(buf, BUFSIZ, fd); *buf = 0) { lineread_init(&resolvconf, fd);
if (!dns_set && strstr(buf, "nameserver ") == buf) { while ((line_len = lineread_get(&resolvconf, &line)) > 0) {
p = strrchr(buf, ' '); if (!dns_set && strstr(line, "nameserver ") == line) {
p = strrchr(line, ' ');
if (!p) if (!p)
continue; continue;
end = strpbrk(buf, "%\n"); end = strpbrk(line, "%\n");
if (end) if (end)
*end = 0; *end = 0;
@ -356,13 +360,13 @@ static void get_dns(struct ctx *c)
dns6++; dns6++;
memset(dns6, 0, sizeof(*dns6)); memset(dns6, 0, sizeof(*dns6));
} }
} else if (!dnss_set && strstr(buf, "search ") == buf && } else if (!dnss_set && strstr(line, "search ") == line &&
s == c->dns_search) { s == c->dns_search) {
end = strpbrk(buf, "\n"); end = strpbrk(line, "\n");
if (end) if (end)
*end = 0; *end = 0;
if (!strtok(buf, " \t")) if (!strtok(line, " \t"))
continue; continue;
while (s - c->dns_search < ARRAY_SIZE(c->dns_search) - 1 while (s - c->dns_search < ARRAY_SIZE(c->dns_search) - 1
@ -374,6 +378,8 @@ static void get_dns(struct ctx *c)
} }
} }
if (line_len < 0)
warn("Error reading /etc/resolv.conf: %s", strerror(errno));
close(fd); close(fd);
out: out: