Proper handling of Apache log file deletion while Apache might have that file open
[hcoop/domtool2.git] / src / msg.sml
... / ...
CommitLineData
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
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
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
64fun send (bio, m) =
65 case m of
66 MsgOk => OpenSSL.writeInt (bio, 1)
67 | MsgError s => (OpenSSL.writeInt (bio, 2);
68 OpenSSL.writeString (bio, s))
69 | MsgConfig s => (OpenSSL.writeInt (bio, 3);
70 OpenSSL.writeString (bio, s))
71 | MsgFile {action, domain, dir, file} =>
72 (OpenSSL.writeInt (bio, 4);
73 OpenSSL.writeInt (bio, a2i action);
74 OpenSSL.writeString (bio, domain);
75 OpenSSL.writeString (bio, dir);
76 OpenSSL.writeString (bio, file))
77 | MsgDoFiles => OpenSSL.writeInt (bio, 5)
78 | MsgGrant acl => (OpenSSL.writeInt (bio, 6);
79 sendAcl (bio, acl))
80 | MsgRevoke acl => (OpenSSL.writeInt (bio, 7);
81 sendAcl (bio, acl))
82 | MsgListPerms user => (OpenSSL.writeInt (bio, 8);
83 OpenSSL.writeString (bio, user))
84 | MsgPerms classes => (OpenSSL.writeInt (bio, 9);
85 sendList (fn (bio, (class, values)) =>
86 (OpenSSL.writeString (bio, class);
87 sendList OpenSSL.writeString (bio, values)))
88 (bio, classes))
89 | MsgWhoHas {class, value} => (OpenSSL.writeInt (bio, 10);
90 OpenSSL.writeString (bio, class);
91 OpenSSL.writeString (bio, value))
92 | MsgWhoHasResponse users => (OpenSSL.writeInt (bio, 11);
93 sendList OpenSSL.writeString (bio, users))
94 | MsgMultiConfig codes => (OpenSSL.writeInt (bio, 12);
95 sendList OpenSSL.writeString (bio, codes))
96 | MsgRmdom dom => (OpenSSL.writeInt (bio, 13);
97 OpenSSL.writeString (bio, dom))
98
99fun checkIt v =
100 case v of
101 NONE => raise OpenSSL.OpenSSL "Bad Msg format"
102 | _ => v
103
104fun recv bio =
105 case OpenSSL.readInt bio of
106 NONE => NONE
107 | SOME n =>
108 checkIt (case n of
109 1 => SOME MsgOk
110 | 2 => Option.map MsgError (OpenSSL.readString bio)
111 | 3 => Option.map MsgConfig (OpenSSL.readString bio)
112 | 4 => (case (OpenSSL.readInt bio,
113 OpenSSL.readString bio,
114 OpenSSL.readString bio,
115 OpenSSL.readString bio) of
116 (SOME action, SOME domain, SOME dir, SOME file) =>
117 SOME (MsgFile {action = i2a action,
118 domain = domain,
119 dir = dir,
120 file = file})
121 | _ => NONE)
122 | 5 => SOME MsgDoFiles
123 | 6 => (case recvAcl bio of
124 SOME acl => SOME (MsgGrant acl)
125 | _ => NONE)
126 | 7 => (case recvAcl bio of
127 SOME acl => SOME (MsgRevoke acl)
128 | _ => NONE)
129 | 8 => (case OpenSSL.readString bio of
130 SOME user => SOME (MsgListPerms user)
131 | _ => NONE)
132 | 9 => Option.map MsgPerms
133 (recvList (fn bio =>
134 case (OpenSSL.readString bio,
135 recvList OpenSSL.readString bio) of
136 (SOME class, SOME values) => SOME (class, values)
137 | _ => NONE) bio)
138 | 10 => (case (OpenSSL.readString bio, OpenSSL.readString bio) of
139 (SOME class, SOME value) => SOME (MsgWhoHas {class = class, value = value})
140 | _ => NONE)
141 | 11 => Option.map MsgWhoHasResponse
142 (recvList OpenSSL.readString bio)
143 | 12 => Option.map MsgMultiConfig
144 (recvList OpenSSL.readString bio)
145 | 13 => Option.map MsgRmdom (OpenSSL.readString bio)
146 | _ => NONE)
147
148end