ref: 0fce274714b986665ce6f5f97ac259fa3d7a7c6c
parent: 1c1fd2f09c278e2f105abeadc5d5f0d2017c655a
author: Ori Bernstein <[email protected]>
date: Thu Jan 2 17:24:38 EST 2014
Get parsing hosts file working.
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -82,6 +82,45 @@
-> bfmtv(buf, fmt, vastart(&args))
}
+
+generic intfmt = {buf : byte[:], sval : @a::(tcnum,tctest,tcint), base, signed
+ var isneg
+ var val
+ var b : char[32]
+ var i
+ var j
+ var n
+
+ n = 0
+ i = 0
+ if signed && sval < 0
+ val = -sval castto(uint64)
+ isneg = true
+ else
+ val = sval castto(uint64)
+ val &= ((1 << 8*sizeof(@a)) - 1)
+ isneg = false
+ ;;
+
+ if val == 0
+ b[0] = '0'
+ i++
+ ;;
+ while val != 0
+ b[i] = digitchars[val % base]
+ val /= base
+ i++
+ ;;
+ n = 0
+ if isneg
+ n += encode(buf[n:], '-')
+ ;;
+ for j = i-1; j >= 0; j--
+ n += encode(buf[n:], b[j])
+ ;;
+ -> n
+}
+
/* formats a string of text as specified by 'fmt' into 'buf',
using a valist for the arguments */
const bfmtv = {buf, fmt, ap
@@ -129,22 +168,22 @@
/* format integers */
| 'b':
(b_val, ap) = vanext(ap)
- n += intfmt(buf[n:], b_val castto(int64), base, signed)
+ n += intfmt(buf[n:], b_val, base, signed)
| 'w':
(w_val, ap) = vanext(ap)
- n += intfmt(buf[n:], w_val castto(int64), base, signed)
+ n += intfmt(buf[n:], w_val, base, signed)
| 'i':
(i_val, ap) = vanext(ap)
- n += intfmt(buf[n:], i_val castto(int64), base, signed)
+ n += intfmt(buf[n:], i_val, base, signed)
| 'l':
(l_val, ap) = vanext(ap)
- n += intfmt(buf[n:], l_val castto(int64), base, signed)
+ n += intfmt(buf[n:], l_val, base, signed)
| 'z':
(z_val, ap) = vanext(ap)
- n += intfmt(buf[n:], z_val castto(int64), base, signed)
+ n += intfmt(buf[n:], z_val, base, signed)
| 'p':
(p_val, ap) = vanext(ap)
- n += intfmt(buf[n:], p_val castto(int64), 16, false)
+ n += intfmt(buf[n:], p_val castto(uint64), 16, false)
| 'c': (c_val, ap) = vanext(ap)
n += encode(buf[n:], c_val)
| _:
@@ -181,41 +220,4 @@
const digitchars = [
'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
]
-
-const intfmt = {buf, sval, base, signed
- var isneg
- var val
- var b : char[32]
- var i
- var j
- var n
-
- n = 0
- i = 0
- if signed && sval < 0
- val = -sval castto(uint64)
- isneg = true
- else
- val = sval castto(uint64)
- isneg = false
- ;;
-
- if val == 0
- b[0] = '0'
- i++
- ;;
- while val != 0
- b[i] = digitchars[val % base]
- val /= base
- i++
- ;;
- n = 0
- if isneg
- n += encode(buf[n:], '-')
- ;;
- for j = i-1; j >= 0; j--
- n += encode(buf[n:], b[j])
- ;;
- -> n
-}
--- a/libstd/htab.myr
+++ b/libstd/htab.myr
@@ -20,6 +20,7 @@
generic htfree : (ht : htab(@k, @v)# -> void)
generic htput : (ht : htab(@k, @v)#, k : @k, v : @v -> void)
generic htget : (ht : htab(@k, @v)#, k : @k -> option(@v))
+ generic hthas : (ht : htab(@k, @v)#, k : @k -> bool)
generic htkeys : (ht : htab(@k, @v)# -> @k[:])
;;
--- a/libstd/ipparse.myr
+++ b/libstd/ipparse.myr
@@ -1,6 +1,8 @@
-use "types.use"
+use "die.use"
use "intparse.use"
use "option.use"
+use "strfind.use"
+use "types.use"
/* FIXME: needed for decls which should be pulled in as hidden */
use "hasprefix.use"
@@ -7,10 +9,24 @@
use "utf.use"
pkg std =
- const ip4parse : (ip : byte[:] -> option(byte[4]))
- const ip6parse : (ip : byte[:] -> option(byte[16]))
+
+ type netaddr = union
+ `Ipv4 byte[4]
+ `Ipv6 byte[16]
+ ;;
+
+ const ipparse : (ip : byte[:] -> option(netaddr))
+ const ip4parse : (ip : byte[:] -> option(netaddr))
+ const ip6parse : (ip : byte[:] -> option(netaddr))
;;
+const ipparse = {ip
+ match strfind(ip, ":")
+ | `Some _: -> ip6parse(ip)
+ | `None: -> ip4parse(ip)
+ ;;
+}
+
const ip4parse = {ip
var addr
var last : size
@@ -20,6 +36,7 @@
var j : size
i = 0
+ last = 0
for j = 0; j < ip.len; j++
if ip[j] == '.' castto(byte)
match intparsebase(ip[last:j], 10)
@@ -48,5 +65,9 @@
if j != ip.len
-> `None
;;
- -> `Some addr
+ -> `Some (`Ipv4 addr)
+}
+
+const ip6parse = {ip
+ -> `None
}
--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -1,15 +1,23 @@
use "alloc.use"
+use "chartype.use"
use "die.use"
use "endian.use"
use "error.use"
+use "extremum.use"
+use "hashfuncs.use"
+use "htab.use"
+use "ipparse.use"
use "fmt.use"
use "option.use"
use "slcp.use"
+use "slpush.use"
use "slurp.use"
+use "strfind.use"
use "strsplit.use"
use "strstrip.use"
use "sys.use"
use "types.use"
+use "utf.use"
pkg std =
type resolveerr = union
@@ -19,11 +27,6 @@
`Badresp
;;
- type netaddr = union
- `Ipv4 byte[4]
- `Ipv6 byte[16]
- ;;
-
type hostinfo = struct
fam : sockfam
stype : socktype
@@ -42,40 +45,106 @@
;;
const Hostfile = "/etc/hosts"
+const Resolvfile = "/etc/resolv.conf"
-const resolve = {host : byte[:]
+var hostmap : htab(byte[:], hostinfo)#
+var search : byte[:][:]
+var nameservers : netaddr[:]
+var inited : bool = false
+
+
+const resolve = {host : byte[:] -> error(hostinfo[:], resolveerr)
match hostfind(host)
- | `Some h: -> h
- | `None: -> dnsresolve(host)
+ | `Some hinf:
+ -> `Success slpush([][:], hinf)
+ | `None:
+ put("********** Couldn't find host %s in hosts\n", host)
+ -> dnsresolve(host)
;;
}
const hostfind = {host
- -> `None
- /*
- var hdat
+ if !inited
+ hostmap = mkht(strhash, streq)
+ loadhosts()
+ inited = true
+ ;;
+ -> htget(hostmap, host)
+}
+
+const loadhosts = {
+ var h
var lines
- var ip
- var hn
- var str
- var i
match slurp(Hostfile)
- | `Success h: hdat = h
- | `Failure m: -> `None
+ | `Success d: h = d
+ | `Failure m: ->
;;
- lines = strsplit(hdat, "\n")
- for i = 0; i < lines.len; i++
- lines[i] = strstrip(lines[i])
- (ip, str) = nextword(lines)
- (hn, str) = nextword(str)
- if streq(hn, host)
- -> parseip(ip)
+ lines = strsplit(h, "\n")
+ for l in lines
+ /* trim comment */
+ match strfind(l, "#")
+ | `Some _idx: l = l[:_idx]
;;
+
+ match word(l)
+ | `Some (ip, rest):
+ match ipparse(ip)
+ | `None:
+ | `Some addr:
+ addhosts(addr, ip, rest)
+ ;;
+ | `None:
+ ;;
;;
- */
}
+
+const addhosts = {addr, as, str
+ var hinf
+ var fam
+
+ match addr
+ | `Ipv4 _: fam = Afinet
+ | `Ipv6 _: fam = Afinet6
+ ;;
+ while true
+ match word(str)
+ | `Some (name, rest):
+ if !hthas(hostmap, name)
+ hinf = [
+ .fam=fam,
+ .stype = 0,
+ .ttl = 0,
+ .addr = addr
+ ]
+ htput(hostmap, name, hinf)
+ ;;
+ str = rest
+ | `None:
+ ->
+ ;;
+ ;;
+}
+
+const loadresolv = {
+}
+
+const word = {s
+ var c, len
+
+ len = 0
+ s = strstrip(s)
+ for c = decode(s[len:]); c != Badchar && !isblank(c); c = decode(s[len:])
+ len += charlen(c)
+ ;;
+ if len == 0
+ -> `None
+ else
+ -> `Some (s[:len], s[len:])
+ ;;
+}
+
const dnsresolve = {host : byte[:]
/*var hosts*/
--- a/libstd/strstrip.myr
+++ b/libstd/strstrip.myr
@@ -30,7 +30,7 @@
var end
/* scan backwards for start of utf8 char */
- end = 0
+ end = str.len
for i = str.len; i != 0; i--
if str[i] & 0x80 == 0
if !isspace(decode(str[i-1:]))
--- a/libstd/sys-linux.myr
+++ b/libstd/sys-linux.myr
@@ -99,6 +99,7 @@
const Afunspec : sockfam = 0
const Afunix : sockfam = 1
const Afinet : sockfam = 2
+ const Afinet6 : sockfam = 10
/* socket types. */
const Sockstream : socktype = 1 /* sequenced, reliable byte stream */