First vmail support
[hcoop/domtool2.git] / src / msg.sml
CommitLineData
36e42cb8
AC
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(* Network messages *)
20
21structure Msg :> MSG = struct
22
23open OpenSSL MsgTypes Slave
24
25val a2i = fn Add => 0
26 | Delete => 1
27 | Modify => 2
28
29val i2a = fn 0 => Add
30 | 1 => Delete
31 | 2 => Modify
32 | _ => raise OpenSSL.OpenSSL "Bad action number to deserialize"
33
5ee41dd0
AC
34fun sendAcl (bio, {user, class, value}) =
35 (OpenSSL.writeString (bio, user);
36 OpenSSL.writeString (bio, class);
37 OpenSSL.writeString (bio, value))
38
39fun recvAcl bio =
40 case (OpenSSL.readString bio, OpenSSL.readString bio, OpenSSL.readString bio) of
41 (SOME user, SOME class, SOME value) => SOME {user = user, class = class, value = value}
42 | _ => NONE
43
c53e82e4
AC
44fun sendList f (bio, ls) =
45 (app (fn x =>
46 (OpenSSL.writeInt (bio, 1);
47 f (bio, x))) ls;
48 OpenSSL.writeInt (bio, 0))
49
50fun recvList f bio =
51 let
52 fun loop ls =
53 case OpenSSL.readInt bio of
54 SOME 0 => SOME (rev ls)
55 | SOME 1 =>
56 (case f bio of
57 SOME x => loop (x :: ls)
58 | NONE => NONE)
59 | _ => NONE
60 in
61 loop []
62 end
63
21d921a5
AC
64fun sendOption f (bio, opt) =
65 case opt of
66 NONE => OpenSSL.writeInt (bio, 0)
67 | SOME x => (OpenSSL.writeInt (bio, 1);
68 f (bio, x))
69
70fun recvOption f bio =
71 case OpenSSL.readInt bio of
72 SOME 0 => SOME NONE
73 | SOME 1 =>
74 (case f bio of
75 SOME x => SOME (SOME x)
76 | NONE => NONE)
77 | _ => NONE
78
36e42cb8
AC
79fun send (bio, m) =
80 case m of
81 MsgOk => OpenSSL.writeInt (bio, 1)
82 | MsgError s => (OpenSSL.writeInt (bio, 2);
83 OpenSSL.writeString (bio, s))
84 | MsgConfig s => (OpenSSL.writeInt (bio, 3);
85 OpenSSL.writeString (bio, s))
86 | MsgFile {action, domain, dir, file} =>
87 (OpenSSL.writeInt (bio, 4);
88 OpenSSL.writeInt (bio, a2i action);
89 OpenSSL.writeString (bio, domain);
90 OpenSSL.writeString (bio, dir);
91 OpenSSL.writeString (bio, file))
92 | MsgDoFiles => OpenSSL.writeInt (bio, 5)
5ee41dd0
AC
93 | MsgGrant acl => (OpenSSL.writeInt (bio, 6);
94 sendAcl (bio, acl))
411a85f2
AC
95 | MsgRevoke acl => (OpenSSL.writeInt (bio, 7);
96 sendAcl (bio, acl))
08a04eb4
AC
97 | MsgListPerms user => (OpenSSL.writeInt (bio, 8);
98 OpenSSL.writeString (bio, user))
99 | MsgPerms classes => (OpenSSL.writeInt (bio, 9);
c53e82e4
AC
100 sendList (fn (bio, (class, values)) =>
101 (OpenSSL.writeString (bio, class);
102 sendList OpenSSL.writeString (bio, values)))
103 (bio, classes))
094877b1
AC
104 | MsgWhoHas {class, value} => (OpenSSL.writeInt (bio, 10);
105 OpenSSL.writeString (bio, class);
106 OpenSSL.writeString (bio, value))
107 | MsgWhoHasResponse users => (OpenSSL.writeInt (bio, 11);
c53e82e4
AC
108 sendList OpenSSL.writeString (bio, users))
109 | MsgMultiConfig codes => (OpenSSL.writeInt (bio, 12);
110 sendList OpenSSL.writeString (bio, codes))
e69e60cc
AC
111 | MsgRmdom doms => (OpenSSL.writeInt (bio, 13);
112 sendList OpenSSL.writeString (bio, doms))
1824f573 113 | MsgRegenerate => OpenSSL.writeInt (bio, 14)
e69e60cc
AC
114 | MsgRmuser dom => (OpenSSL.writeInt (bio, 15);
115 OpenSSL.writeString (bio, dom))
21d921a5
AC
116 | MsgCreateDbUser {dbtype, passwd} => (OpenSSL.writeInt (bio, 16);
117 OpenSSL.writeString (bio, dbtype);
118 sendOption OpenSSL.writeString (bio, passwd))
90dd48df
AC
119 | MsgCreateDbTable {dbtype, dbname} => (OpenSSL.writeInt (bio, 17);
120 OpenSSL.writeString (bio, dbtype);
121 OpenSSL.writeString (bio, dbname))
08688401
AC
122 | MsgNewMailbox {domain, user, passwd, mailbox} =>
123 (OpenSSL.writeInt (bio, 18);
124 OpenSSL.writeString (bio, domain);
125 OpenSSL.writeString (bio, user);
126 OpenSSL.writeString (bio, passwd);
127 OpenSSL.writeString (bio, mailbox))
128 | MsgPasswdMailbox {domain, user, passwd} =>
129 (OpenSSL.writeInt (bio, 19);
130 OpenSSL.writeString (bio, domain);
131 OpenSSL.writeString (bio, user);
132 OpenSSL.writeString (bio, passwd))
133 | MsgRmMailbox {domain, user} =>
134 (OpenSSL.writeInt (bio, 20);
135 OpenSSL.writeString (bio, domain);
136 OpenSSL.writeString (bio, user))
36e42cb8
AC
137
138fun checkIt v =
139 case v of
140 NONE => raise OpenSSL.OpenSSL "Bad Msg format"
141 | _ => v
142
143fun recv bio =
144 case OpenSSL.readInt bio of
145 NONE => NONE
146 | SOME n =>
147 checkIt (case n of
148 1 => SOME MsgOk
149 | 2 => Option.map MsgError (OpenSSL.readString bio)
150 | 3 => Option.map MsgConfig (OpenSSL.readString bio)
151 | 4 => (case (OpenSSL.readInt bio,
152 OpenSSL.readString bio,
153 OpenSSL.readString bio,
154 OpenSSL.readString bio) of
155 (SOME action, SOME domain, SOME dir, SOME file) =>
156 SOME (MsgFile {action = i2a action,
157 domain = domain,
158 dir = dir,
159 file = file})
160 | _ => NONE)
161 | 5 => SOME MsgDoFiles
5ee41dd0
AC
162 | 6 => (case recvAcl bio of
163 SOME acl => SOME (MsgGrant acl)
164 | _ => NONE)
411a85f2
AC
165 | 7 => (case recvAcl bio of
166 SOME acl => SOME (MsgRevoke acl)
167 | _ => NONE)
08a04eb4
AC
168 | 8 => (case OpenSSL.readString bio of
169 SOME user => SOME (MsgListPerms user)
170 | _ => NONE)
c53e82e4
AC
171 | 9 => Option.map MsgPerms
172 (recvList (fn bio =>
173 case (OpenSSL.readString bio,
174 recvList OpenSSL.readString bio) of
175 (SOME class, SOME values) => SOME (class, values)
176 | _ => NONE) bio)
094877b1
AC
177 | 10 => (case (OpenSSL.readString bio, OpenSSL.readString bio) of
178 (SOME class, SOME value) => SOME (MsgWhoHas {class = class, value = value})
179 | _ => NONE)
c53e82e4
AC
180 | 11 => Option.map MsgWhoHasResponse
181 (recvList OpenSSL.readString bio)
182 | 12 => Option.map MsgMultiConfig
183 (recvList OpenSSL.readString bio)
e69e60cc 184 | 13 => Option.map MsgRmdom (recvList OpenSSL.readString bio)
1824f573 185 | 14 => SOME MsgRegenerate
e69e60cc 186 | 15 => Option.map MsgRmuser (OpenSSL.readString bio)
21d921a5
AC
187 | 16 => (case (OpenSSL.readString bio, recvOption OpenSSL.readString bio) of
188 (SOME dbtype, SOME passwd) =>
189 SOME (MsgCreateDbUser {dbtype = dbtype, passwd = passwd})
190 | _ => NONE)
90dd48df
AC
191 | 17 => (case (OpenSSL.readString bio, OpenSSL.readString bio) of
192 (SOME dbtype, SOME dbname) =>
193 SOME (MsgCreateDbTable {dbtype = dbtype, dbname = dbname})
194 | _ => NONE)
08688401
AC
195 | 18 => (case (OpenSSL.readString bio, OpenSSL.readString bio,
196 OpenSSL.readString bio, OpenSSL.readString bio) of
197 (SOME domain, SOME user, SOME passwd, SOME mailbox) =>
198 SOME (MsgNewMailbox {domain = domain, user = user,
199 passwd = passwd, mailbox = mailbox})
200 | _ => NONE)
201 | 19 => (case (OpenSSL.readString bio, OpenSSL.readString bio,
202 OpenSSL.readString bio) of
203 (SOME domain, SOME user, SOME passwd) =>
204 SOME (MsgPasswdMailbox {domain = domain, user = user,
205 passwd = passwd})
206 | _ => NONE)
207 | 20 => (case (OpenSSL.readString bio, OpenSSL.readString bio) of
208 (SOME domain, SOME user) =>
209 SOME (MsgRmMailbox {domain = domain, user = user})
210 | _ => NONE)
36e42cb8
AC
211 | _ => NONE)
212
213end