hare

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

commit 6b38b891ce50c16b29d8edf74734ac1acc5090d0
parent d1d410824213c6876e3105c59d2aa9e5030efcd5
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 21 Jun 2021 12:27:09 -0400

unix::hosts: new module

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mscripts/gen-stdlib | 9++++++++-
Mstdlib.mk | 32++++++++++++++++++++++++++++++--
Aunix/hosts/lookup.ha | 50++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -753,6 +753,12 @@ unix() { gen_ssa unix errors } +unix_hosts() { + gen_srcs unix::hosts \ + lookup.ha + gen_ssa unix::hosts os io bufio net::ip strings +} + unix_passwd() { gen_srcs unix::passwd \ group.ha \ @@ -764,7 +770,7 @@ unix_passwd() { unix_resolvconf() { gen_srcs unix::resolvconf \ load.ha - gen_ssa unix::resolvconf os io bufio net::ip + gen_ssa unix::resolvconf os io bufio net::ip strings } unix_tty() { @@ -845,6 +851,7 @@ time types unicode unix +unix::hosts unix::passwd unix::resolvconf unix::tty diff --git a/stdlib.mk b/stdlib.mk @@ -321,6 +321,10 @@ hare_stdlib_deps+=$(stdlib_unicode) stdlib_unix=$(HARECACHE)/unix/unix.o hare_stdlib_deps+=$(stdlib_unix) +# gen_lib unix::hosts +stdlib_unix_hosts=$(HARECACHE)/unix/hosts/unix_hosts.o +hare_stdlib_deps+=$(stdlib_unix_hosts) + # gen_lib unix::passwd stdlib_unix_passwd=$(HARECACHE)/unix/passwd/unix_passwd.o hare_stdlib_deps+=$(stdlib_unix_passwd) @@ -1068,6 +1072,16 @@ $(HARECACHE)/unix/unix.ssa: $(stdlib_unix_srcs) $(stdlib_rt) $(stdlib_errors) @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix \ -t$(HARECACHE)/unix/unix.td $(stdlib_unix_srcs) +# unix::hosts +stdlib_unix_hosts_srcs= \ + $(STDLIB)/unix/hosts/lookup.ha + +$(HARECACHE)/unix/hosts/unix_hosts.ssa: $(stdlib_unix_hosts_srcs) $(stdlib_rt) $(stdlib_os) $(stdlib_io) $(stdlib_bufio) $(stdlib_net_ip) $(stdlib_strings) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/unix/hosts + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::hosts \ + -t$(HARECACHE)/unix/hosts/unix_hosts.td $(stdlib_unix_hosts_srcs) + # unix::passwd stdlib_unix_passwd_srcs= \ $(STDLIB)/unix/passwd/group.ha \ @@ -1084,7 +1098,7 @@ $(HARECACHE)/unix/passwd/unix_passwd.ssa: $(stdlib_unix_passwd_srcs) $(stdlib_rt 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) +$(HARECACHE)/unix/resolvconf/unix_resolvconf.ssa: $(stdlib_unix_resolvconf_srcs) $(stdlib_rt) $(stdlib_os) $(stdlib_io) $(stdlib_bufio) $(stdlib_net_ip) $(stdlib_strings) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/unix/resolvconf @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::resolvconf \ @@ -1437,6 +1451,10 @@ hare_testlib_deps+=$(testlib_unicode) testlib_unix=$(TESTCACHE)/unix/unix.o hare_testlib_deps+=$(testlib_unix) +# gen_lib unix::hosts +testlib_unix_hosts=$(TESTCACHE)/unix/hosts/unix_hosts.o +hare_testlib_deps+=$(testlib_unix_hosts) + # gen_lib unix::passwd testlib_unix_passwd=$(TESTCACHE)/unix/passwd/unix_passwd.o hare_testlib_deps+=$(testlib_unix_passwd) @@ -2208,6 +2226,16 @@ $(TESTCACHE)/unix/unix.ssa: $(testlib_unix_srcs) $(testlib_rt) $(testlib_errors) @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix \ -t$(TESTCACHE)/unix/unix.td $(testlib_unix_srcs) +# unix::hosts +testlib_unix_hosts_srcs= \ + $(STDLIB)/unix/hosts/lookup.ha + +$(TESTCACHE)/unix/hosts/unix_hosts.ssa: $(testlib_unix_hosts_srcs) $(testlib_rt) $(testlib_os) $(testlib_io) $(testlib_bufio) $(testlib_net_ip) $(testlib_strings) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/unix/hosts + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::hosts \ + -t$(TESTCACHE)/unix/hosts/unix_hosts.td $(testlib_unix_hosts_srcs) + # unix::passwd testlib_unix_passwd_srcs= \ $(STDLIB)/unix/passwd/group.ha \ @@ -2224,7 +2252,7 @@ $(TESTCACHE)/unix/passwd/unix_passwd.ssa: $(testlib_unix_passwd_srcs) $(testlib_ 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) +$(TESTCACHE)/unix/resolvconf/unix_resolvconf.ssa: $(testlib_unix_resolvconf_srcs) $(testlib_rt) $(testlib_os) $(testlib_io) $(testlib_bufio) $(testlib_net_ip) $(testlib_strings) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/unix/resolvconf @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::resolvconf \ diff --git a/unix/hosts/lookup.ha b/unix/hosts/lookup.ha @@ -0,0 +1,50 @@ +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/hosts"; + +// Looks up a host from /etc/hosts. Aborts the program if the file does not +// exist, is written in an invalid format, or if any other error occurs. +export fn lookup(name: str) (ip::addr | void) = { + // XXX: Would be cool if we could do this without allocating anything + // XXX: Would be cool to add caching + 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); + if (line[0] == '#': u32: u8) { + continue; + }; + + const scanner = bufio::fixed(line, io::mode::READ); + defer io::close(scanner); + + const tok = match (bufio::scantok(scanner, ' ', '\t')!) { + io::EOF => break, + tok: []u8 => tok, + }; + defer free(tok); + const addr = ip::parse(strings::fromutf8(tok))!; + + for (true) { + const tok = match (bufio::scantok(scanner, ' ', '\t')!) { + io::EOF => break, + tok: []u8 => tok, + }; + defer free(tok); + + if (strings::fromutf8(tok) == name) { + return addr; + }; + }; + }; +};