From 8df2e702cf3e5ed9b8433585b357bbcd9f0d623e Mon Sep 17 00:00:00 2001 From: Adam Chlipala Date: Sun, 30 Jul 2006 22:00:16 +0000 Subject: [PATCH] Slaves and Exim --- Makefile | 6 ++-- configDefault/domtool.cfg | 1 + configDefault/domtool.cfs | 1 + configDefault/exim.cfg | 9 ++++++ configDefault/exim.cfs | 2 ++ configDefault/exim.csg | 11 ++++++++ src/domain.sml | 22 ++++----------- src/domtool.cm | 6 +++- src/plugins/exim.sig | 23 ++++++++++++++++ src/plugins/exim.sml | 58 +++++++++++++++++++++++++++++++++++++++ src/plugins/plugins.cm | 9 ------ src/slave.sig | 8 ++++++ src/slave.sml | 42 ++++++++++++++++++++++++++++ 13 files changed, 169 insertions(+), 29 deletions(-) create mode 100644 configDefault/exim.cfg create mode 100644 configDefault/exim.cfs create mode 100644 configDefault/exim.csg create mode 100644 src/plugins/exim.sig create mode 100644 src/plugins/exim.sml delete mode 100644 src/plugins/plugins.cm diff --git a/Makefile b/Makefile index 4f173d4..7964314 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,10 @@ all: configDefault/config.sig configDefault/configDefault.sml .PHONY: all configDefault/config.sig: src/config.sig.header \ - configDefault/*.cfs src/config.sig.footer - cat src/config.sig.header \ + configDefault/*.csg configDefault/*.cfs \ + src/config.sig.footer + cat configDefault/*.csg \ + src/config.sig.header \ configDefault/*.cfs \ src/config.sig.footer \ >configDefault/config.sig diff --git a/configDefault/domtool.cfg b/configDefault/domtool.cfg index aed3b0b..34d07ee 100644 --- a/configDefault/domtool.cfg +++ b/configDefault/domtool.cfg @@ -2,6 +2,7 @@ val libRoot = "/home/adamc/cvs/domtool2/lib" val resultRoot = "/home/adamc/domtool" val tmpDir = "/tmp" +val cat = "/bin/cat" val cp = "/bin/cp" val diff = "/usr/bin/diff" val rm = "/bin/rm" diff --git a/configDefault/domtool.cfs b/configDefault/domtool.cfs index 90be237..d72df6f 100644 --- a/configDefault/domtool.cfs +++ b/configDefault/domtool.cfs @@ -9,6 +9,7 @@ val tmpDir : string (* Filesystem location for creating temporary directories *) (* Paths to standard UNIX utilities *) +val cat : string val cp : string val diff : string val rm : string diff --git a/configDefault/exim.cfg b/configDefault/exim.cfg new file mode 100644 index 0000000..78c7228 --- /dev/null +++ b/configDefault/exim.cfg @@ -0,0 +1,9 @@ +structure Exim :> EXIM_CONFIG = struct + +val aliases = "/home/adamc/fake/aliases" +val aliasesDefault = "/home/adamc/fake/aliases.default" + +val reload = "echo \"I would reload exim now.\"" +(*"/etc/init.d/exim4 reload"*) + +end diff --git a/configDefault/exim.cfs b/configDefault/exim.cfs new file mode 100644 index 0000000..c1cd13a --- /dev/null +++ b/configDefault/exim.cfs @@ -0,0 +1,2 @@ +structure Exim : EXIM_CONFIG + diff --git a/configDefault/exim.csg b/configDefault/exim.csg new file mode 100644 index 0000000..c8a2232 --- /dev/null +++ b/configDefault/exim.csg @@ -0,0 +1,11 @@ +signature EXIM_CONFIG = sig + +val aliases : string +val aliasesDefault : string +(* Paths to e-mail alias files. + * The "default" version is for catch-alls. *) + +val reload : string +(* Command-line to reload exim configuration *) + +end diff --git a/src/domain.sml b/src/domain.sml index 394bf80..534e440 100644 --- a/src/domain.sml +++ b/src/domain.sml @@ -103,18 +103,6 @@ datatype file_action' = | Delete' of string | Modify' of {src : string, dst : string} -fun shell ss = OS.Process.isSuccess (OS.Process.system (String.concat ss)) - -fun shellF (ss, msg) = - let - val s = String.concat ss - in - if OS.Process.isSuccess (OS.Process.system s) then - () - else - ErrorMsg.error NONE (msg s) - end - fun findDiffs dom = let val realPath = getPath dom Config.resultRoot @@ -136,7 +124,7 @@ fun findDiffs dom = if Posix.FileSys.ST.isDir (Posix.FileSys.stat real) then loopReal acts else if Posix.FileSys.access (tmp, []) then - if shell [Config.diff, " ", real, " ", tmp] then + if Slave.shell [Config.diff, " ", real, " ", tmp] then loopReal acts else loopReal (Modify' {src = tmp, dst = real} :: acts) @@ -146,7 +134,7 @@ fun findDiffs dom = val acts = loopReal [] - val dir = Posix.FileSys.opendir realPath + val dir = Posix.FileSys.opendir tmpPath fun loopTmp acts = case Posix.FileSys.readdir dir of @@ -190,7 +178,7 @@ val _ = Env.container_one "domain" val diffs = findDiffs dom val diffs = map (fn Add' {src, dst} => - (shellF ([Config.cp, " ", src, " ", dst], + (Slave.shellF ([Config.cp, " ", src, " ", dst], fn cl => "Copy failed: " ^ cl); {action = Slave.Add, domain = dom, @@ -203,7 +191,7 @@ val _ = Env.container_one "domain" domain = dom, file = dst}) | Modify' {src, dst} => - (shellF ([Config.cp, " ", src, " ", dst], + (Slave.shellF ([Config.cp, " ", src, " ", dst], fn cl => "Copy failed: " ^ cl); {action = Slave.Modify, domain = dom, @@ -213,7 +201,7 @@ val _ = Env.container_one "domain" () else Slave.handleChanges diffs; - ignore (shellF ([Config.rm, " -rf ", Config.tmpDir, "/*"], + ignore (Slave.shellF ([Config.rm, " -rf ", Config.tmpDir, "/*"], fn cl => "Temp file cleanup failed: " ^ cl)) end) diff --git a/src/domtool.cm b/src/domtool.cm index bdc790b..29b39c0 100644 --- a/src/domtool.cm +++ b/src/domtool.cm @@ -47,7 +47,11 @@ slave.sml domain.sig domain.sml -plugins/plugins.cm +plugins/alias.sig +plugins/alias.sml + +plugins/exim.sig +plugins/exim.sml order.sig order.sml diff --git a/src/plugins/exim.sig b/src/plugins/exim.sig new file mode 100644 index 0000000..fde572b --- /dev/null +++ b/src/plugins/exim.sig @@ -0,0 +1,23 @@ +(* HCoop Domtool (http://hcoop.sourceforge.net/) + * Copyright (c) 2006, 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. + *) + +(* Exim MTA handling *) + +signature EXIM = sig + +end diff --git a/src/plugins/exim.sml b/src/plugins/exim.sml new file mode 100644 index 0000000..112ab5f --- /dev/null +++ b/src/plugins/exim.sml @@ -0,0 +1,58 @@ +(* HCoop Domtool (http://hcoop.sourceforge.net/) + * Copyright (c) 2006, 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. + *) + +(* Exim MTA handling *) + +structure Exim :> EXIM = struct + +val aliasesChanged = ref false +val aliasesDefaultChanged = ref false + +val () = Slave.registerPreHandler + (fn () => (aliasesChanged := false; + aliasesDefaultChanged := false)) + +val () = Slave.registerFileHandler (fn fs => + let + val spl = OS.Path.splitDirFile (#file fs) + in + if #file spl = "aliases" then + aliasesChanged := true + else if #file spl = "aliases.default" then + aliasesDefaultChanged := true + else + () + end) + +val () = Slave.registerPostHandler + (fn () => + (if !aliasesChanged then + Slave.concatTo (fn s => s = "aliases") Config.Exim.aliases + else + (); + if !aliasesDefaultChanged then + Slave.concatTo (fn s => s = "aliases.default") Config.Exim.aliasesDefault + else + (); + if !aliasesChanged orelse !aliasesDefaultChanged then + Slave.shellF ([Config.Exim.reload], + fn cl => "Error reloading exim with " ^ cl) + else + ())) + +end diff --git a/src/plugins/plugins.cm b/src/plugins/plugins.cm deleted file mode 100644 index 2f3be08..0000000 --- a/src/plugins/plugins.cm +++ /dev/null @@ -1,9 +0,0 @@ -Library - -signature ALIAS -structure Alias - -is - -alias.sig -alias.sml diff --git a/src/slave.sig b/src/slave.sig index 24082d4..76a4b05 100644 --- a/src/slave.sig +++ b/src/slave.sig @@ -39,4 +39,12 @@ signature SLAVE = sig (* Register code to run before or after making all changes. *) val handleChanges : file_status list -> unit + + val shell : string list -> bool + val shellF : string list * (string -> string) -> unit + + val concatTo : (string -> bool) -> string -> unit + (* Search through the result configuration hierarchy for all files matching + * the predicate, concatenating their contents in arbitrary order to the + * given file. *) end diff --git a/src/slave.sml b/src/slave.sml index b08d41d..1521b73 100644 --- a/src/slave.sml +++ b/src/slave.sml @@ -58,4 +58,46 @@ fun handleChanges fs = (!preHandler (); app (!fileHandler) fs; !postHandler ()) +fun shell ss = OS.Process.isSuccess (OS.Process.system (String.concat ss)) + +fun shellF (ss, msg) = + let + val s = String.concat ss + in + if OS.Process.isSuccess (OS.Process.system s) then + () + else + ErrorMsg.error NONE (msg s) + end + +fun concatTo p fname = + let + fun visitDir dname = + let + val dir = Posix.FileSys.opendir dname + + fun loop () = + case Posix.FileSys.readdir dir of + NONE => Posix.FileSys.closedir dir + | SOME fname' => + let + val path = OS.Path.joinDirFile {dir = dname, file = fname'} + in + if Posix.FileSys.ST.isDir (Posix.FileSys.stat path) then + visitDir path + else if p fname' then + shellF ([Config.cat, " ", path, " >>", fname], + fn cl => "Error concatenating: " ^ cl) + else + (); + loop () + end + in + TextIO.closeOut (TextIO.openOut fname); + loop () + end + in + visitDir Config.resultRoot + end + end -- 2.20.1