shithub: mc

Download patch

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 */