56c0e176 |
1 | fun isMember (list, addr) = |
2 | let |
3 | val proc = Unix.execute ("/usr/sbin/find_member", ["-l", list, addr]) |
4 | in |
5 | (case TextIO.inputLine (Unix.textInstreamOf proc) of |
6 | NONE => false |
7 | | _ => true) |
8 | before ignore (Unix.reap proc) |
9 | end |
10 | |
11 | fun isIdent ch = Char.isLower ch orelse Char.isDigit ch |
12 | |
13 | fun validHost s = |
14 | size s > 0 andalso size s < 20 andalso List.all isIdent (String.explode s) |
15 | |
16 | fun validDomain s = |
17 | size s > 0 andalso size s < 100 andalso List.all validHost (String.fields (fn ch => ch = #".") s) |
18 | |
19 | fun validEmailUser s = |
20 | size s > 0 andalso size s < 50 andalso List.all |
21 | (fn ch => Char.isAlphaNum ch orelse ch = #"." orelse ch = #"_" orelse ch = #"-" orelse ch = #"+") |
22 | (String.explode s) |
23 | |
24 | fun validEmail s = |
25 | (case String.fields (fn ch => ch = #"@") s of |
26 | [user, host] => validEmailUser user andalso validDomain host |
27 | | _ => false) |
28 | |
29 | fun main () = |
30 | case CommandLine.arguments () of |
31 | [list, cmd, addr] => |
7c1a0a61 |
32 | if list <> "hcoop-discuss" andalso list <> "hcoop-misc" andalso list <> "hcoop-announce" andalso list <> "hcoop-sysadmin" then |
56c0e176 |
33 | (print "Bad mailing list name\n"; |
34 | OS.Process.failure) |
35 | else if not (validEmail addr) then |
36 | (print "Invalid e-mail address\n"; |
37 | OS.Process.failure) |
38 | else (case cmd of |
39 | "check" => |
40 | if isMember (list, addr) then |
41 | OS.Process.success |
42 | else |
43 | OS.Process.failure |
44 | | "add" => |
45 | if isMember (list, addr) then |
46 | OS.Process.success |
47 | else |
48 | OS.Process.system (String.concat ["echo ", addr, " | /usr/sbin/add_members -r - ", list]) |
49 | | "rm" => |
4b8df0b1 |
50 | if list = "hcoop-announce" then |
51 | (print "You can't remove anyone from hcoop-announce.\n"; |
52 | OS.Process.failure) |
53 | else if isMember (list, addr) then |
56c0e176 |
54 | OS.Process.system (String.concat ["/usr/sbin/remove_members ", list, " ", addr]) |
55 | else |
56 | OS.Process.success |
57 | | _ => (print ("Invalid command " ^ cmd ^ "\n"); |
58 | OS.Process.failure)) |
59 | | _ => (print "Bad command-line arguments\n"; |
60 | OS.Process.failure) |
61 | |
7c1a0a61 |
62 | val _ = OS.Process.exit (main ()) |