Initial mod_waklog support
[hcoop/domtool2.git] / src / domain.sml
index 9913dfc..7ee4690 100644 (file)
@@ -97,9 +97,19 @@ fun yourDomainHost s =
                                (Substring.slice (suf, 1, NONE)))
     end
 
+val yourDomain = yourDomainHost
+
 fun validUser s = size s > 0 andalso size s < 20
                  andalso CharVector.all Char.isAlphaNum s
 
+fun validEmailUser s =
+    size s > 0 andalso size s < 50
+    andalso CharVector.all (fn ch => Char.isAlphaNum ch
+                                    orelse ch = #"."
+                                    orelse ch = #"_"
+                                    orelse ch = #"-"
+                                    orelse ch = #"+") s
+
 val validGroup = validUser
 
 val _ = Env.type_one "no_spaces"
@@ -502,26 +512,28 @@ val _ = Env.containerV_one "domain"
                                       end
 
                                   fun saveNamed (kind, soa : soa, masterIp) node =
-                                      let
-                                          val outf = domainFile {node = node, name = "named.conf"}
-                                      in
-                                          TextIO.output (outf, "\nzone \"");
-                                          TextIO.output (outf, dom);
-                                          TextIO.output (outf, "\" IN {\n\ttype ");
-                                          TextIO.output (outf, kind);
-                                          TextIO.output (outf, ";\n\tfile \"");
-                                          TextIO.output (outf, Config.Bind.zonePath_real);
-                                          TextIO.output (outf, "/");
-                                          TextIO.output (outf, dom);
-                                          TextIO.output (outf, ".zone\";\n");
-                                          case kind of
-                                              "master" => TextIO.output (outf, "\tallow-update { none; };\n")
-                                            | _ => (TextIO.output (outf, "\tmasters { ");
-                                                    TextIO.output (outf, masterIp);
-                                                    TextIO.output (outf, "; };\n"));
-                                          TextIO.output (outf, "};\n");
-                                          TextIO.closeOut outf
-                                      end
+                                      if dom = "localhost" then
+                                          ()
+                                      else let
+                                              val outf = domainFile {node = node, name = "named.conf"}
+                                          in
+                                              TextIO.output (outf, "\nzone \"");
+                                              TextIO.output (outf, dom);
+                                              TextIO.output (outf, "\" IN {\n\ttype ");
+                                              TextIO.output (outf, kind);
+                                              TextIO.output (outf, ";\n\tfile \"");
+                                              TextIO.output (outf, Config.Bind.zonePath_real);
+                                              TextIO.output (outf, "/");
+                                              TextIO.output (outf, dom);
+                                              TextIO.output (outf, ".zone\";\n");
+                                              case kind of
+                                                  "master" => TextIO.output (outf, "\tallow-update { none; };\n")
+                                                | _ => (TextIO.output (outf, "\tmasters { ");
+                                                        TextIO.output (outf, masterIp);
+                                                        TextIO.output (outf, "; };\n"));
+                                              TextIO.output (outf, "};\n");
+                                              TextIO.closeOut outf
+                                          end
                               in
                                   case kind of
                                       NoDns => masterNode := NONE
@@ -652,45 +664,79 @@ val _ = Env.type_one "mail_node"
            orelse (hasPriv "mail"
                    andalso List.exists (fn x => x = node) Config.mailNodes_admin))
 
-fun rmdom dom =
+fun rmdom doms =
     let
-       val domPath = String.concatWith "/" (rev (String.fields (fn ch => ch = #".") dom))
-
        fun doNode (node, _) =
            let
                val dname = OS.Path.joinDirFile {dir = Config.resultRoot,
                                                 file = node}
-               val dname = OS.Path.concat (dname, domPath)
-
-               val dir = Posix.FileSys.opendir dname
 
-               fun loop actions =
-                   case Posix.FileSys.readdir dir of
-                       NONE => actions
-                     | SOME fname => loop ({action = Slave.Delete,
-                                            domain = dom,
-                                            dir = dname,
-                                            file = OS.Path.joinDirFile {dir = dname,
-                                                                        file = fname}} :: actions)
-
-               val actions = loop []
+               fun doDom (dom, actions) =
+                   let
+                       val domPath = String.concatWith "/" (rev (String.fields (fn ch => ch = #".") dom))
+                       val dname = OS.Path.concat (dname, domPath)
+
+                       fun visitDom (dom, dname, actions) =
+                           let
+                               val dir = Posix.FileSys.opendir dname
+
+                               fun loop actions =
+                                   case Posix.FileSys.readdir dir of
+                                       NONE => actions
+                                     | SOME fname =>
+                                       let
+                                           val fnameFull = OS.Path.joinDirFile {dir = dname,
+                                                                                file = fname}
+                                       in
+                                           if Posix.FileSys.ST.isDir (Posix.FileSys.stat fnameFull) then
+                                               loop (visitDom (fname ^ "." ^ dom,
+                                                               fnameFull,
+                                                               actions))
+                                           else                                                        
+                                               loop ({action = Slave.Delete,
+                                                      domain = dom,
+                                                      dir = dname,
+                                                      file = fnameFull} :: actions)
+                                       end
+                           in
+                               loop actions
+                               before Posix.FileSys.closedir dir
+                           end
+                               handle OS.SysErr _ =>
+                                      (print ("Warning: System error deleting domain " ^ dom ^ " on " ^ node ^ ".\n");
+                                       actions)
+                   in
+                       visitDom (dom, dname, actions)
+                   end
+
+               val actions = foldl doDom [] doms
            in
-               Posix.FileSys.closedir dir;
                handleSite (node, actions)
            end
-               handle IO.Io _ => print ("Warning: IO error deleting domain " ^ dom ^ " on " ^ node ^ ".\n")
+               handle IO.Io _ => print ("Warning: IO error deleting domains on " ^ node ^ ".\n")
 
        fun cleanupNode (node, _) =
            let
-               val dname = OS.Path.joinDirFile {dir = Config.resultRoot,
-                                                file = node}
-               val dname = OS.Path.concat (dname, domPath)
+               fun doDom dom =
+                   let
+                       val domPath = String.concatWith "/" (rev (String.fields (fn ch => ch = #".") dom))
+                       val dname = OS.Path.joinDirFile {dir = Config.resultRoot,
+                                                        file = node}
+                       val dname = OS.Path.concat (dname, domPath)
+                   in
+                       ignore (OS.Process.system (Config.rm ^ " -rf " ^ dname))
+                   end
            in
-               ignore (OS.Process.system (Config.rm ^ " -rf " ^ dname))
+               app doDom doms
            end
     in
        app doNode Config.nodeIps;
        app cleanupNode Config.nodeIps
     end
 
+fun homedirOf uname =
+    Posix.SysDB.Passwd.home (Posix.SysDB.getpwnam uname)
+
+fun homedir () = homedirOf (getUser ())
+
 end