Record user for Mailman vhosts
[hcoop/domtool2.git] / src / plugins / mailman.sml
1 (* HCoop Domtool (http://hcoop.sourceforge.net/)
2 * Copyright (c) 2006, Adam Chlipala
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *)
18
19 (* Mailman mailing list handling *)
20
21 structure Mailman :> MAILMAN = struct
22
23 val files = ref ([] : TextIO.outstream list)
24 val write = ref (fn _ : string => ())
25
26 val () = Env.action_one "mailmanWebHost"
27 ("hostname", Env.string)
28 (fn host =>
29 let
30 val {write, writeDom, close} = Domain.domainsFile {node = Config.Mailman.node,
31 name = "mailman"}
32 in
33 write "\t'";
34 write host;
35 write "' : '";
36 writeDom ();
37 write "',\n";
38 close ()
39 end)
40
41 val () = Env.actionV_one "mailmanVhost"
42 ("host", Env.string)
43 (fn (env, host) =>
44 let
45 val nodes = Env.env (Env.list Env.string) (env, "WebNodes")
46
47 val ssl = Env.env Apache.ssl (env, "SSL")
48 val user = Env.env Env.string (env, "User")
49
50 val fullHost = host ^ "." ^ Domain.currentDomain ()
51 val vhostId = fullHost ^ (if Option.isSome ssl then ".ssl" else "")
52 val confFile = fullHost ^ (if Option.isSome ssl then ".vhost_ssl" else ".vhost")
53 in
54 app (fn node =>
55 let
56 val file = Domain.domainFile {node = node,
57 name = confFile}
58 fun print s = TextIO.output (file, s)
59
60 val ld = Apache.logDir {user = user, node = node, vhostId = vhostId}
61 in
62 print "# Owner: ";
63 print user;
64 print "\n";
65 print "<VirtualHost ";
66 print (Domain.nodeIp node);
67 print ":";
68 print (case ssl of
69 SOME _ => "443"
70 | NONE => "80");
71 print "\n";
72 print " ServerName $LISTDOMAIN\n";
73 print " ServerAdmin ";
74 print user;
75 print "@hcoop.net\n";
76 print " SuexecUserGroup list list\n";
77 print "\n";
78 print " ErrorLog ";
79 print ld;
80 print "/error.log\n";
81 print " CustomLog ";
82 print ld;
83 print "/access.log combined\n";
84 print "\n";
85 print " RewriteEngine on\n";
86 print "\n";
87 print " # Default to showing listinfo page\n";
88 print " RewriteRule ^/$ http://";
89 print fullHost;
90 print "/listinfo/\n";
91 print "\n";
92 print " Alias /images/mailman /usr/share/images/mailman\n";
93 print " Alias /pipermail /var/lib/mailman/archives/public\n";
94 print "\n";
95 print " DocumentRoot /usr/lib/cgi-bin/mailman\n";
96 print " <Directory /usr/lib/cgi-bin/mailman>\n";
97 print " AllowOverride None\n";
98 print " Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch\n";
99 print " ForceType cgi-script\n";
100 print " Order allow,deny\n";
101 print " Allow from all\n";
102 print " </Directory>\n";
103 print "\n";
104 print " <Directory /usr/share/doc/mailman>\n";
105 print " Order allow,deny\n";
106 print " Allow from all\n";
107 print " </Directory>\n";
108 print "</VirtualHost>\n";
109
110 TextIO.closeOut file
111 end) nodes
112 end)
113
114 val mailmanChanged = ref false
115
116 val () = Slave.registerPreHandler (fn () => mailmanChanged := false)
117
118 val () = Slave.registerFileHandler (fn fs =>
119 let
120 val spl = OS.Path.splitDirFile (#file fs)
121 in
122 case #file spl of
123 "mailman" => mailmanChanged := true
124 | _ => ()
125 end)
126
127 val () = Slave.registerPostHandler (fn () =>
128 if !mailmanChanged then
129 (Slave.concatTo (fn s => s = "mailman")
130 Config.Mailman.mapFile;
131 Slave.enumerateTo (fn s => s = "mailman") ":"
132 Config.Mailman.handleDomains;
133 Slave.shellF ([Config.Mailman.reload],
134 fn cl => "Error reloading Mailman with " ^ cl))
135 else
136 ())
137
138 val () = Domain.registerDescriber (Domain.considerAll
139 [Domain.Filename {filename = "mailman",
140 heading = "Mailman web host mapping",
141 showEmpty = false}])
142
143 end