commit f6d7bf79b46543c47c48a88457fd38e67bc3257c
parent b2a17d2ab87ca3c9580d1aca086afa7a95b5b9c0
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 21 Jun 2021 12:00:19 -0400
unix::resolvconf: new module
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
4 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -556,7 +556,7 @@ net_dns() {
encoding.ha \
query.ha \
types.ha
- gen_ssa net::dns ascii endian net net::udp net::ip fmt
+ gen_ssa net::dns ascii endian net net::udp net::ip fmt unix::resolvconf
}
gensrcs_net_ip() {
@@ -761,6 +761,12 @@ unix_passwd() {
gen_ssa unix::passwd bufio io os strconv strings
}
+unix_resolvconf() {
+ gen_srcs unix::resolvconf \
+ load.ha
+ gen_ssa unix::resolvconf os io bufio net::ip
+}
+
unix_tty() {
gen_srcs unix::tty \
types.ha \
@@ -840,6 +846,7 @@ types
unicode
unix
unix::passwd
+unix::resolvconf
unix::tty
uuid"
stdlib() {
diff --git a/stdlib.mk b/stdlib.mk
@@ -325,6 +325,10 @@ hare_stdlib_deps+=$(stdlib_unix)
stdlib_unix_passwd=$(HARECACHE)/unix/passwd/unix_passwd.o
hare_stdlib_deps+=$(stdlib_unix_passwd)
+# gen_lib unix::resolvconf
+stdlib_unix_resolvconf=$(HARECACHE)/unix/resolvconf/unix_resolvconf.o
+hare_stdlib_deps+=$(stdlib_unix_resolvconf)
+
# gen_lib unix::tty
stdlib_unix_tty=$(HARECACHE)/unix/tty/unix_tty.o
hare_stdlib_deps+=$(stdlib_unix_tty)
@@ -827,7 +831,7 @@ stdlib_net_dns_srcs= \
$(STDLIB)/net/dns/query.ha \
$(STDLIB)/net/dns/types.ha
-$(HARECACHE)/net/dns/net_dns.ssa: $(stdlib_net_dns_srcs) $(stdlib_rt) $(stdlib_ascii) $(stdlib_endian) $(stdlib_net) $(stdlib_net_udp) $(stdlib_net_ip) $(stdlib_fmt)
+$(HARECACHE)/net/dns/net_dns.ssa: $(stdlib_net_dns_srcs) $(stdlib_rt) $(stdlib_ascii) $(stdlib_endian) $(stdlib_net) $(stdlib_net_udp) $(stdlib_net_ip) $(stdlib_fmt) $(stdlib_unix_resolvconf)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/net/dns
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::dns \
@@ -1076,6 +1080,16 @@ $(HARECACHE)/unix/passwd/unix_passwd.ssa: $(stdlib_unix_passwd_srcs) $(stdlib_rt
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::passwd \
-t$(HARECACHE)/unix/passwd/unix_passwd.td $(stdlib_unix_passwd_srcs)
+# unix::resolvconf
+stdlib_unix_resolvconf_srcs= \
+ $(STDLIB)/unix/resolvconf/load.ha
+
+$(HARECACHE)/unix/resolvconf/unix_resolvconf.ssa: $(stdlib_unix_resolvconf_srcs) $(stdlib_rt) $(stdlib_os) $(stdlib_io) $(stdlib_bufio) $(stdlib_net_ip)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(HARECACHE)/unix/resolvconf
+ @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::resolvconf \
+ -t$(HARECACHE)/unix/resolvconf/unix_resolvconf.td $(stdlib_unix_resolvconf_srcs)
+
# unix::tty
stdlib_unix_tty_srcs= \
$(STDLIB)/unix/tty/types.ha \
@@ -1427,6 +1441,10 @@ hare_testlib_deps+=$(testlib_unix)
testlib_unix_passwd=$(TESTCACHE)/unix/passwd/unix_passwd.o
hare_testlib_deps+=$(testlib_unix_passwd)
+# gen_lib unix::resolvconf
+testlib_unix_resolvconf=$(TESTCACHE)/unix/resolvconf/unix_resolvconf.o
+hare_testlib_deps+=$(testlib_unix_resolvconf)
+
# gen_lib unix::tty
testlib_unix_tty=$(TESTCACHE)/unix/tty/unix_tty.o
hare_testlib_deps+=$(testlib_unix_tty)
@@ -1949,7 +1967,7 @@ testlib_net_dns_srcs= \
$(STDLIB)/net/dns/query.ha \
$(STDLIB)/net/dns/types.ha
-$(TESTCACHE)/net/dns/net_dns.ssa: $(testlib_net_dns_srcs) $(testlib_rt) $(testlib_ascii) $(testlib_endian) $(testlib_net) $(testlib_net_udp) $(testlib_net_ip) $(testlib_fmt)
+$(TESTCACHE)/net/dns/net_dns.ssa: $(testlib_net_dns_srcs) $(testlib_rt) $(testlib_ascii) $(testlib_endian) $(testlib_net) $(testlib_net_udp) $(testlib_net_ip) $(testlib_fmt) $(testlib_unix_resolvconf)
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/net/dns
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::dns \
@@ -2202,6 +2220,16 @@ $(TESTCACHE)/unix/passwd/unix_passwd.ssa: $(testlib_unix_passwd_srcs) $(testlib_
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::passwd \
-t$(TESTCACHE)/unix/passwd/unix_passwd.td $(testlib_unix_passwd_srcs)
+# unix::resolvconf
+testlib_unix_resolvconf_srcs= \
+ $(STDLIB)/unix/resolvconf/load.ha
+
+$(TESTCACHE)/unix/resolvconf/unix_resolvconf.ssa: $(testlib_unix_resolvconf_srcs) $(testlib_rt) $(testlib_os) $(testlib_io) $(testlib_bufio) $(testlib_net_ip)
+ @printf 'HAREC \t$@\n'
+ @mkdir -p $(TESTCACHE)/unix/resolvconf
+ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::resolvconf \
+ -t$(TESTCACHE)/unix/resolvconf/unix_resolvconf.td $(testlib_unix_resolvconf_srcs)
+
# unix::tty
testlib_unix_tty_srcs= \
$(STDLIB)/unix/tty/types.ha \
diff --git a/unix/resolvconf/README b/unix/resolvconf/README
@@ -0,0 +1,4 @@
+[[unix::resolvconf]] provides a (basic) reader for the resolv.conf file found on
+many Unix-like operating systems. This implementation only supports the
+"nameserver" directive, and it will return a list of IP addresses to use as
+nameservers.
diff --git a/unix/resolvconf/load.ha b/unix/resolvconf/load.ha
@@ -0,0 +1,48 @@
+use bufio;
+use io;
+use net::ip;
+use os;
+use strings;
+
+// XXX: Different platforms may want to configure a different path
+def path: str = "/etc/resolv.conf";
+
+// Reads a list of nameservers from resolv.conf. Aborts the program if the file
+// does not exist, is written in an invalid format, or if any other error
+// occurs.
+export fn load() []ip::addr = {
+ // XXX: Would be cool if we could do this without allocating anything
+ let servers: []ip::addr = [];
+
+ const file = os::open(path)!;
+ defer io::close(file);
+
+ for (true) {
+ const line = match (bufio::scanline(file)) {
+ io::EOF => break,
+ line: []u8 => line,
+ };
+ defer free(line);
+
+ const scanner = bufio::fixed(line, io::mode::READ);
+ defer io::close(scanner);
+
+ const tok = match (bufio::scantok(scanner, ' ')!) {
+ io::EOF => break,
+ tok: []u8 => tok,
+ };
+ defer free(tok);
+ if (strings::fromutf8(tok) != "nameserver") {
+ continue;
+ };
+
+ const tok = match (bufio::scantok(scanner, ' ')!) {
+ io::EOF => break,
+ tok: []u8 => tok,
+ };
+ defer free(tok);
+ append(servers, ip::parse(strings::fromutf8(tok))!);
+ };
+
+ return servers;
+};