From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top
Subject: [PATCH v2 2/4] Parse resolv.conf with new lineread implementation
Date: Fri, 24 Jun 2022 12:17:30 +1000 [thread overview]
Message-ID: <20220624021732.4062212-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20220624021732.4062212-1-david@gibson.dropbear.id.au>
[-- Attachment #1: Type: text/plain, Size: 2283 bytes --]
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(a)gibson.dropbear.id.au>
---
conf.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/conf.c b/conf.c
index 3a5d650..22949fd 100644
--- a/conf.c
+++ b/conf.c
@@ -38,6 +38,7 @@
#include "udp.h"
#include "tcp.h"
#include "pasta.h"
+#include "lineread.h"
/**
* 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 fqdn *s = c->dns_search;
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;
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)
goto out;
- for (*buf = 0; line_read(buf, BUFSIZ, fd); *buf = 0) {
- if (!dns_set && strstr(buf, "nameserver ") == buf) {
- p = strrchr(buf, ' ');
+ lineread_init(&resolvconf, fd);
+ while ((line_len = lineread_get(&resolvconf, &line)) > 0) {
+ if (!dns_set && strstr(line, "nameserver ") == line) {
+ p = strrchr(line, ' ');
if (!p)
continue;
- end = strpbrk(buf, "%\n");
+ end = strpbrk(line, "%\n");
if (end)
*end = 0;
@@ -356,13 +360,13 @@ static void get_dns(struct ctx *c)
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) {
- end = strpbrk(buf, "\n");
+ end = strpbrk(line, "\n");
if (end)
*end = 0;
- if (!strtok(buf, " \t"))
+ if (!strtok(line, " \t"))
continue;
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);
out:
--
@@ -38,6 +38,7 @@
#include "udp.h"
#include "tcp.h"
#include "pasta.h"
+#include "lineread.h"
/**
* 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 fqdn *s = c->dns_search;
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;
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)
goto out;
- for (*buf = 0; line_read(buf, BUFSIZ, fd); *buf = 0) {
- if (!dns_set && strstr(buf, "nameserver ") == buf) {
- p = strrchr(buf, ' ');
+ lineread_init(&resolvconf, fd);
+ while ((line_len = lineread_get(&resolvconf, &line)) > 0) {
+ if (!dns_set && strstr(line, "nameserver ") == line) {
+ p = strrchr(line, ' ');
if (!p)
continue;
- end = strpbrk(buf, "%\n");
+ end = strpbrk(line, "%\n");
if (end)
*end = 0;
@@ -356,13 +360,13 @@ static void get_dns(struct ctx *c)
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) {
- end = strpbrk(buf, "\n");
+ end = strpbrk(line, "\n");
if (end)
*end = 0;
- if (!strtok(buf, " \t"))
+ if (!strtok(line, " \t"))
continue;
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);
out:
--
2.36.1
next prev parent reply other threads:[~2022-06-24 2:17 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-24 2:17 [PATCH v2 0/4] New line reading implementation David Gibson
2022-06-24 2:17 ` [PATCH v2 1/4] Add cleaner line-by-line reading primitives David Gibson
2022-06-27 10:36 ` Stefano Brivio
2022-06-28 0:47 ` David Gibson
2022-06-24 2:17 ` David Gibson [this message]
2022-06-24 2:17 ` [PATCH v2 3/4] Use new lineread implementation for procfs_scan_listen() David Gibson
2022-06-24 2:17 ` [PATCH v2 4/4] Remove unused line_read() David Gibson
2022-07-06 17:46 ` [PATCH v2 0/4] New line reading implementation Stefano Brivio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220624021732.4062212-3-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).