+structure StringMap = DataStructures.StringMap
+
+fun parseRules _ =
+ let
+ val inf = TextIO.openIn Config.Firewall.firewallRules
+ val out_lines = ref StringMap.empty
+ val in_lines = ref StringMap.empty
+
+ fun confLine r (uname, line) =
+ let
+ val line = String.concat ["\t", line, "\n"]
+ val lines = case StringMap.find (!r, uname) of
+ NONE => []
+ | SOME lines => lines
+ in
+ r := StringMap.insert (!r, uname, line :: lines)
+ end
+
+ val confLine_in = confLine in_lines
+ val confLine_out = confLine out_lines
+
+ fun parsePorts ports =
+ case String.fields (fn ch => ch = #",") ports of
+ [pp] => pp
+ | pps => String.concat ["(", String.concatWith " " pps, ")"]
+
+ fun parseHosts addr hosts =
+ case hosts of
+ [] => ""
+ | [host] => String.concat [" ", addr, " ", host]
+ | _ => String.concat [" ", addr, " (", String.concatWith " " hosts, ")"]
+
+ fun loop () =
+ case TextIO.inputLine inf of
+ NONE => ()
+ | SOME line =>
+ case String.tokens Char.isSpace line of
+ uname :: rest =>
+ (case rest of
+ "Client" :: ports :: hosts =>
+ confLine_out (uname, String.concat ["dport ", parsePorts ports, parseHosts "daddr" hosts, " ACCEPT;"])
+ | "Server" :: ports :: hosts =>
+ confLine_in (uname, String.concat ["dport ", parsePorts ports, parseHosts "daddr" hosts, " ACCEPT;"])
+ | ["LocalServer", ports] =>
+ confLine_in (uname, String.concat ["saddr $WE dport ", parsePorts ports, " ACCEPT;"])
+ | _ => print "Invalid config line\n";
+ loop ())
+ | _ => loop ()
+ val _ = loop ()
+ in
+ {server_rules = !in_lines, client_rules = !out_lines}
+ end
+