hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Mscripts/gen-stdlib | 9++++++++-
Mstdlib.mk | 32++++++++++++++++++++++++++++++--
Aunix/resolvconf/README | 4++++
Aunix/resolvconf/load.ha | 48++++++++++++++++++++++++++++++++++++++++++++++++
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; +};