| ["ping"] => OS.Process.exit (Main.requestPing ())
| ["slave-shutdown"] => Main.requestSlaveShutdown ()
| ["slave-ping"] => OS.Process.exit (Main.requestSlavePing ())
+ | ["package", node, pkg] => OS.Process.exit (Main.requestApt {node = node, pkg = pkg})
| _ => print "Invalid command-line arguments\n"
val requestSaSet : string * bool -> unit
val requestSmtpLog : string -> unit
+
+ val requestApt : {node : string, pkg : string} -> OS.Process.status
end
OpenSSL.close bio
end
+fun requestApt {node, pkg} =
+ let
+ val (_, bio) = requestBio (fn () => ())
+
+ val _ = Msg.send (bio, MsgApt pkg)
+
+ fun loop () =
+ case Msg.recv bio of
+ NONE => (print "Server closed connection unexpectedly.\n";
+ OS.Process.failure)
+ | SOME m =>
+ case m of
+ MsgYes => (print "Package is installed.\n";
+ OS.Process.success)
+ | MsgNo => (print "Package is not installed.\n";
+ OS.Process.failure)
+ | MsgError s => (print ("APT query failed: " ^ s ^ "\n");
+ OS.Process.failure)
+ | _ => (print "Unexpected server reply.\n";
+ OS.Process.failure)
+ in
+ loop ()
+ before OpenSSL.close bio
+ end
+
fun regenerate context =
let
val b = basis ()
NONE)))
(fn () => ())
+ | MsgApt pkg =>
+ doIt (fn () => (Msg.send (bio, if Apt.installed pkg then
+ MsgYes
+ else
+ MsgNo);
+ ("User requested installation status of package " ^ pkg,
+ NONE)))
+ (fn () => ())
+
| _ =>
doIt (fn () => ("Unexpected command",
SOME "Unexpected command"))
OpenSSL.writeString (bio, dbtype);
OpenSSL.writeString (bio, passwd))
| MsgShutdown => OpenSSL.writeInt (bio, 29)
+ | MsgYes => OpenSSL.writeInt (bio, 30)
+ | MsgNo => OpenSSL.writeInt (bio, 31)
+ | MsgApt s => (OpenSSL.writeInt (bio, 32);
+ OpenSSL.writeString (bio, s))
fun checkIt v =
case v of
SOME (MsgDbPasswd {dbtype = dbtype, passwd = passwd})
| _ => NONE)
| 29 => SOME MsgShutdown
+ | 30 => SOME MsgYes
+ | 31 => SOME MsgNo
+ | 32 => Option.map MsgApt (OpenSSL.readString bio)
| _ => NONE)
end
(* Change a DBMS user's password *)
| MsgShutdown
(* Halt the server *)
+ | MsgYes
+ | MsgNo
+ (* Answers to boolean queries *)
+ | MsgApt of string
+ (* Is this apt package installed on your host? *)
end
--- /dev/null
+(* HCoop Domtool (http://hcoop.sourceforge.net/)
+ * Copyright (c) 2006-2007, Adam Chlipala
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *)
+
+(* APT package database querying *)
+
+signature APT = sig
+
+ val installed : string -> bool
+ (* Is the named package installed on this host? *)
+
+end
--- /dev/null
+(* HCoop Domtool (http://hcoop.sourceforge.net/)
+ * Copyright (c) 2006-2007, Adam Chlipala
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *)
+
+(* APT package database querying *)
+
+structure Apt :> APT = struct
+
+fun validName s = CharVector.all (fn ch => Char.isAlphaNum ch orelse ch = #"_" orelse ch = #"-" orelse ch = #".") s
+ andalso (size s > 0 andalso String.sub (s, 0) <> #"-")
+
+fun installed name =
+ validName name
+ andalso OS.Process.isSuccess (OS.Process.system ("/usr/bin/dpkg -p " ^ name ^ " >/dev/null 2>/dev/null"))
+
+end
plugins/mysql.sig
plugins/mysql.sml
+plugins/apt.sig
+plugins/apt.sml
+
mail/vmail.sig
mail/vmail.sml