diff options
author | Ori Bernstein <ori@eigenstate.org> | 2014-01-02 22:24:38 -0500 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2014-01-02 22:24:38 -0500 |
commit | 0fce274714b986665ce6f5f97ac259fa3d7a7c6c (patch) | |
tree | 820d0c49b120cdb5a58896810238b5bbb1b86559 | |
parent | 1c1fd2f09c278e2f105abeadc5d5f0d2017c655a (diff) | |
download | mc-0fce274714b986665ce6f5f97ac259fa3d7a7c6c.tar.gz |
Get parsing hosts file working.
-rw-r--r-- | libstd/fmt.myr | 88 | ||||
-rw-r--r-- | libstd/htab.myr | 1 | ||||
-rw-r--r-- | libstd/ipparse.myr | 29 | ||||
-rw-r--r-- | libstd/resolve.myr | 119 | ||||
-rw-r--r-- | libstd/strstrip.myr | 2 | ||||
-rw-r--r-- | libstd/sys-linux.myr | 1 |
6 files changed, 167 insertions, 73 deletions
diff --git a/libstd/fmt.myr b/libstd/fmt.myr index 4756b52..38ea136 100644 --- a/libstd/fmt.myr +++ b/libstd/fmt.myr @@ -82,6 +82,45 @@ const bfmt = {buf, fmt, args -> 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 @@ const bfmtv = {buf, fmt, ap /* 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) | _: @@ -182,40 +221,3 @@ 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 -} - diff --git a/libstd/htab.myr b/libstd/htab.myr index df0221f..4016b1c 100644 --- a/libstd/htab.myr +++ b/libstd/htab.myr @@ -20,6 +20,7 @@ pkg std = 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[:]) ;; diff --git a/libstd/ipparse.myr b/libstd/ipparse.myr index 9017791..7b6136d 100644 --- a/libstd/ipparse.myr +++ b/libstd/ipparse.myr @@ -1,16 +1,32 @@ -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" 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 @@ const ip4parse = {ip 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 @@ const ip4parse = {ip if j != ip.len -> `None ;; - -> `Some addr + -> `Some (`Ipv4 addr) +} + +const ip6parse = {ip + -> `None } diff --git a/libstd/resolve.myr b/libstd/resolve.myr index 7012833..e84b4b7 100644 --- 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 @@ pkg std = `Badresp ;; - type netaddr = union - `Ipv4 byte[4] - `Ipv6 byte[16] - ;; - type hostinfo = struct fam : sockfam stype : socktype @@ -42,41 +45,107 @@ pkg std = ;; const Hostfile = "/etc/hosts" +const Resolvfile = "/etc/resolv.conf" + +var hostmap : htab(byte[:], hostinfo)# +var search : byte[:][:] +var nameservers : netaddr[:] +var inited : bool = false + -const resolve = {host : byte[:] +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*/ var nsrv diff --git a/libstd/strstrip.myr b/libstd/strstrip.myr index b28e3f1..d7b25b3 100644 --- a/libstd/strstrip.myr +++ b/libstd/strstrip.myr @@ -30,7 +30,7 @@ const strrstrip = {str 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:])) diff --git a/libstd/sys-linux.myr b/libstd/sys-linux.myr index 22f567c..3b0abce 100644 --- a/libstd/sys-linux.myr +++ b/libstd/sys-linux.myr @@ -99,6 +99,7 @@ pkg std = 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 */ |