Initial revision
[hcoop/zz_old/domtool.git] / src / exim / exim.sml
CommitLineData
182a2654
AC
1(*
2Domtool (http://hcoop.sf.net/)
3Copyright (C) 2004 Adam Chlipala
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18*)
19
20(* Exim e-mail alias and local domain configuration *)
21
22structure Exim :> EXIM =
23struct
24 open Config EximConfig Util
25
26 val aliases = ref (NONE : TextIO.outstream option)
27 val aliasesDefault = ref (NONE : TextIO.outstream option)
28 val local_domains = ref (NONE : TextIO.outstream option)
29
30 fun init () = (aliases := SOME (TextIO.openOut (scratchDir ^ "/aliases"));
31 aliasesDefault := SOME (TextIO.openOut (scratchDir ^ "/aliases.default"));
32 local_domains := SOME (TextIO.openOut (scratchDir ^ "/local_domains"));
33 TextIO.output (valOf (!local_domains), "local_domains = localhost"))
34 fun finish () = (TextIO.output (valOf (!local_domains), "\n\n");
35 TextIO.closeOut (valOf (!aliases));
36 aliases := NONE;
37 TextIO.closeOut (valOf (!aliasesDefault));
38 aliasesDefault := NONE;
39 TextIO.closeOut (valOf (!local_domains));
40 local_domains := NONE)
41
42 fun handler {path, domain, parent, vars, paths, users, groups} =
43 let
44 val _ = Domtool.dprint ("Reading aliases " ^ path ^ " for " ^ domain ^ "....")
45
46 val aliases = valOf (!aliases)
47 val aliasesDefault = valOf (!aliasesDefault)
48
49 val domain = "@" ^ parent
50 val al = TextIO.openIn path
51
52 fun loop (line, ()) =
53 let
54 fun err () = Domtool.error (path, "invalid entry: " ^ line)
55 in
56 case String.tokens Char.isSpace line of
57 [] => ()
58 | ["*", target] =>
59 if validUser target then
60 TextIO.output (aliasesDefault, "*" ^ domain ^ ":\t" ^ target ^ "@localhost\n")
61 else if validEmail target then
62 TextIO.output (aliasesDefault, "*" ^ domain ^ ":\t" ^ target ^ "\n")
63 else
64 err ()
65 | ["**", target] =>
66 if validUser target then
67 TextIO.output (aliases, "*" ^ domain ^ ":\t" ^ target ^ "@localhost\n")
68 else if validEmail target then
69 TextIO.output (aliases, "*" ^ domain ^ ":\t" ^ target ^ "\n")
70 else
71 err ()
72 | [user, target] =>
73 if validUser user then
74 (if target = "!" then
75 TextIO.output (aliases, user ^ domain ^ ":\t/dev/null\n")
76 else if validUser target then
77 TextIO.output (aliases, user ^ domain ^ ":\t" ^ target ^ "@localhost\n")
78 else if validEmail target then
79 TextIO.output (aliases, user ^ domain ^ ":\t" ^ target ^ "\n")
80 else
81 err ())
82 else
83 err ()
84 | _ => err ()
85 end
86 in
87 ioLoop (fn () => Domtool.inputLine al) loop ();
88 TextIO.closeIn al
89 end handle Io => Domtool.error (path, "IO error")
90
91 fun publish () =
92 if OS.Process.isSuccess (OS.Process.system
93 (diff ^ " " ^ scratchDir ^ "/aliases " ^ aliasesFile))
94 andalso OS.Process.isSuccess (OS.Process.system
95 (diff ^ " " ^ scratchDir ^ "/aliases.default " ^ aliasesDefaultFile))
96 andalso OS.Process.isSuccess (OS.Process.system
97 (diff ^ " " ^ scratchDir ^ "/local_domains " ^
98 scratchDir ^ "/local_domains.last"))
99 then
100 OS.Process.success
101 else if not (OS.Process.isSuccess (OS.Process.system
102 (cp ^ " " ^ scratchDir ^ "/aliases " ^ aliasesFile))) then
103 (print "Error copying aliases\n";
104 OS.Process.failure)
105 else if not (OS.Process.isSuccess (OS.Process.system
106 (cp ^ " " ^ scratchDir ^ "/aliases.default " ^ aliasesDefaultFile))) then
107 (print "Error copying aliases.default\n";
108 OS.Process.failure)
109 else if not (OS.Process.isSuccess (OS.Process.system
110 (cp ^ " " ^ scratchDir ^ "/local_domains " ^
111 scratchDir ^ "/local_domains.last"))) then
112 (print "Error copying local_domains\n";
113 OS.Process.failure)
114 else if not (OS.Process.isSuccess (OS.Process.system
115 (cat ^ " " ^ scratchDir ^ "/local_domains " ^ eximBase ^
116 " >" ^ eximFile))) then
117 (print "Error creating exim.conf\n";
118 OS.Process.failure)
119 else if OS.Process.isSuccess (OS.Process.system pubCommand) then
120 OS.Process.success
121 else
122 (print "Error publishing exim data\n";
123 OS.Process.failure)
124
125 fun mkdom _ = OS.Process.success
126
127 val _ = Domtool.setHandler (".aliases", {init = init,
128 file = handler,
129 finish = finish,
130 publish = publish,
131 mkdom = mkdom})
132
133 fun localDomain domain = TextIO.output (valOf (!local_domains), ":" ^ domain)
134end
135
136