Major overhaul. 1.0.0
authorMark Wooding <mdw@distorted.org.uk>
Wed, 7 Dec 2011 01:46:02 +0000 (01:46 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 7 Dec 2011 01:46:02 +0000 (01:46 +0000)
Turn this mess into a proper installable package.  Fixes various bugs
along the way.

.gitignore
.links [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
configure.ac [new file with mode: 0644]
userv.rc.in [moved from .userv/rc with 50% similarity]
zoneconf-install-ssh [moved from bin/ssh-install with 100% similarity]
zoneconf-install-userv [moved from bin/userv-install with 100% similarity]
zoneconf.in [moved from bin/zoneconf with 95% similarity, mode: 0644]

index c1a6249..fba45cc 100644 (file)
@@ -1,2 +1,7 @@
 .ssh
 config
+aclocal.m4
+Makefile.in
+configure
+COPYING
+autom4te.cache
diff --git a/.links b/.links
new file mode 100644 (file)
index 0000000..5a93e8f
--- /dev/null
+++ b/.links
@@ -0,0 +1,3 @@
+COPYING
+config/auto-version
+config/confsubst
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..a26d686
--- /dev/null
@@ -0,0 +1,89 @@
+### -*-makefile-*-
+###
+### Build script for zoneconf
+###
+### (c) 2011 Mark Wooding
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+sbin_SCRIPTS            =
+man_MANS                =
+noinst_DATA             =
+
+EXTRA_DIST              =
+CLEANFILES              =
+DISTCLEANFILES          =
+
+pkgconfdir              = $(sysconfdir)/$(PACKAGE)
+
+###--------------------------------------------------------------------------
+### Standard configuration substitutions.
+
+confsubst = $(top_srcdir)/config/confsubst
+EXTRA_DIST             += config/confsubst
+
+SUBSTITUTIONS = \
+               prefix=$(prefix) exec_prefix=$(exec_prefix) \
+               bindir=$(bindir) sbindir=$(sbindir) \
+               bindprogsdir=$(bindprogsdir) \
+               pkgconfdir=$(pkgconfdir) \
+               pkgstatedir=$(localstatedir)/lib/$(PACKAGE) \
+               PACKAGE=$(PACKAGE) VERSION=$(VERSION) \
+               TCLSH=$(TCLSH)
+
+V_SUBST = $(V_SUBST_$(V))
+V_SUBST_ = $(V_SUBST_$(AM_DEFAULT_VERBOSITY))
+V_SUBST_0 = @echo "  SUBST  $@";
+SUBST = $(V_SUBST)$(confsubst)
+
+###--------------------------------------------------------------------------
+### Executable scripts.
+
+## Main scripts.
+sbin_SCRIPTS           += zoneconf
+EXTRA_DIST             += zoneconf.in
+CLEANFILES             += zoneconf
+
+zoneconf: zoneconf.in Makefile
+       $(SUBST) $(srcdir)/zoneconf.in $(SUBSTITUTIONS) >zoneconf.new && \
+               chmod +x zoneconf.new && mv zoneconf.new zoneconf
+
+## Userv interface.
+sbin_SCRIPTS           += zoneconf-install-userv
+EXTRA_DIST             += zoneconf-install-userv
+
+noinst_DATA            += userv.rc
+EXTRA_DIST             += userv.rc.in
+
+userv.rc: userv.rc.in Makefile
+       $(SUBST) $(srcdir)/userv.rc.in $(SUBSTITUTIONS) >userv.rc.new && \
+               mv userv.rc.new userv.rc
+
+## SSH interface.
+sbin_SCRIPTS           += zoneconf-install-ssh
+EXTRA_DIST             += zoneconf-install-ssh
+
+###--------------------------------------------------------------------------
+### Distribution.
+
+EXTRA_DIST             += config/auto-version
+
+dist-hook:
+       echo $(VERSION) >$(distdir)/RELEASE
+
+###----- That's all, folks --------------------------------------------------
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..a74257f
--- /dev/null
@@ -0,0 +1,62 @@
+dnl -*-autoconf-*-
+dnl
+dnl Configuration script for zoneconf
+dnl
+dnl (c) 2011 Mark Wooding
+dnl
+
+dnl----- Licensing notice ---------------------------------------------------
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software Foundation,
+dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+dnl Initialization.
+mdw_AUTO_VERSION
+AC_INIT([zoneconf], AUTO_VERSION, [mdw@distorted.org.uk])
+AC_CONFIG_SRCDIR([zoneconf.in])
+AC_CONFIG_AUX_DIR([config])
+AM_INIT_AUTOMAKE([foreign])
+mdw_SILENT_RULES
+
+dnl Directories for things.
+AC_MSG_CHECKING([where the BIND utility programs are])
+bindprogsdir=none
+for dir in \
+  /bin /usr/bin /sbin /usr/sbin /usr/local/bin /usr/local/sbin \
+  $(echo $PATH | tr : " ")
+do
+  foundp=t
+  for prog in rndc named-checkzone dnssec-signzone; do
+    if ! test -x "$dir/$prog"; then
+      foundp=nil
+      break
+    fi
+  done
+  case $foundp in t) bindprogsdir=$dir; break ;; esac
+done
+case $bindprogsdir in
+  none) AC_MSG_ERROR([Failed to find BIND utilties.]) ;;
+esac
+AC_MSG_RESULT([$bindprogsdir])
+AC_SUBST([bindprogsdir])
+
+dnl Tcl language support.
+AX_PROG_TCL([8.5])
+
+dnl Output.
+AC_CONFIG_FILES(
+  [Makefile])
+AC_OUTPUT
+
+dnl----- That's all, folks --------------------------------------------------
similarity index 50%
rename from .userv/rc
rename to userv.rc.in
index 2c407e9..339ea04 100644 (file)
--- a/.userv/rc
@@ -7,14 +7,5 @@ if ( glob service install
        require-fd 0 read
        require-fd 1-2 write
        no-suppress-args
-       execute bin/userv-install
-fi
-
-if ( glob service update
-   & glob calling-user root
-   )
-       require-fd 0 read
-       require-fd 1-2 write
-       no-suppress-args
-       execute bin/zoneconf update
+       execute @sbindir@/zoneconf-install-userv
 fi
similarity index 100%
rename from bin/ssh-install
rename to zoneconf-install-ssh
similarity index 100%
rename from bin/userv-install
rename to zoneconf-install-userv
old mode 100755 (executable)
new mode 100644 (file)
similarity index 95%
rename from bin/zoneconf
rename to zoneconf.in
index 772088a..f0dcdef
@@ -1,4 +1,4 @@
-#! /usr/bin/tclsh8.5
+#! @TCLSH@
 ### -*-tcl-*-
 ###
 ### Generate `named.conf' stanze for multiple views.
@@ -981,40 +981,44 @@ define-configuration-space dynamic ZONECFG {
 }
 
 ## Everything about a zone.
+set HOME "@pkgstatedir@"
+set BINDPROGS "@bindprogsdir@"
 define-configuration-space zone ZONECFG {
   define-simple user root
-  define-simple master-dir "/var/lib/bind"
-  define-simple slave-dir "/var/cache/bind"
+  define-simple home-dir $HOME
+  define-simple static-dir "$HOME/static"
+  define-simple dynamic-dir "$HOME/dynamic"
   define-simple dir-mode 2775
   define-simple zone-file "%v/%z.zone"
   define-simple soa-format increment
   define-list views *
   define-list sign-views {}
-  define-list signzone-command {
-    /usr/sbin/dnssec-signzone
-    -g
-    -S
-    -K/var/lib/bind/key
-    -d/var/lib/bind/ds
-    -s-3600 -e+176400
-    -N%q
-    -o%z
-    -f%o
-    %f
-  }
+  define-list signzone-command \
+      [list "$BINDPROGS/dnssec-signzone" \
+          "-g" \
+          "-S" \
+          "-K%h/key" \
+          "-d%h/ds" \
+          "-s-3600" "-e+176400" \
+          "-N%q" \
+          "-o%z" \
+          "-f%o" \
+          "%f"]
   define-simple auto-dnssec off
-  define-list reload-command {/usr/sbin/rndc reload %z IN %v}
-  define-list autosign-command {/usr/sbin/rndc sign %z IN %v}
-  define-list checkzone-command {
-    /usr/sbin/named-checkzone
-    -ifull
-    -kfail
-    -Mfail
-    -nfail
-    -Sfail
-    -Wfail
-    %z
-    %f
+  define-list reload-command [list "$BINDPROGS/rndc" "reload" "%z" "IN" "%v"]
+  define-list autosign-command [list "$BINDPROGS/rndc" "sign" "%z" "IN" "%v"]
+  define-list checkzone-command \
+      [list "$BINDPROGS/named-checkzone" \
+          "-ifull" \
+          "-kfail" \
+          "-Mfail" \
+          "-nfail" \
+          "-Sfail" \
+          "-Wfail" \
+          "%z" "%f"]
+
+  define setvar {name value} {
+    dict set ZONECFG(var) $name $value
   }
 
   define primary {map} {
@@ -1066,7 +1070,7 @@ define-configuration-space toplevel ZONECFG {
   include zone
 
   define-list all-views {}
-  define-simple conf-file "/var/lib/zoneconf/config/%v.conf"
+  define-simple conf-file "$HOME/config/%v.conf"
   define-simple max-zone-size [expr {512*1024}]
   define-list reconfig-command {/usr/sbin/rndc reconfig}
 
@@ -1152,11 +1156,11 @@ proc compute-zone-properties {view config} {
   ## Work out the file names.
   switch -glob -- $zone(config-type):$zone(type) {
     master:static {
-      set dir $zone(master-dir)
+      set dir $zone(static-dir)
       set nameview $zone(mapped-view)
     }
     default {
-      set dir $zone(slave-dir)
+      set dir $zone(dynamic-dir)
       set nameview $view
     }
   }
@@ -1195,10 +1199,10 @@ proc write-ddns-update-policy {prefix chan config} {
     set rrtypes [lrange $item 4 end]
     puts $chan [format $policyskel \
                    $verb \
-                     $ident \
-                     $type \
-                     $name \
-                     $rrtypes]
+                   $ident \
+                   $type \
+                   $name \
+                   $rrtypes]
   }
 
   puts $chan [format $policyskel \
@@ -1211,19 +1215,28 @@ proc write-ddns-update-policy {prefix chan config} {
   puts $chan "${prefix}};"
 }
 
-proc sign-zone-file {info input soafmt} {
+proc sign-zone-file {info soafmt infile} {
   ## Sign the zone described by INFO.  The input zone file is INPUT; the SOA
   ## should be updated according to SOAFMT.
 
   global QUIS
 
   array set zone $info
-  return [run "zone `$zone(name)' in view `$zone(mapped-view)'" \
-             $zone(signzone-command) \
-             "%z" $zone(name) \
-             "%f" $zone(file-name) \
-             "%o" $zone(server-file-name) \
-             "%q" $soafmt]
+  set outfile "$zone(server-file-name).new"
+  if {![run "zone `$zone(name)' in view `$zone(mapped-view)'" \
+           $zone(signzone-command) \
+           "%h" $zone(home-dir) \
+           "%m" $zone(static-dir) \
+           "%s" $zone(dynamic-dir) \
+           "%z" $zone(name) \
+           "%f" $infile \
+           "%o" $outfile \
+           "%q" $soafmt]} {
+    file delete -force $outfile
+    return false
+  }
+  file rename -force $outfile $zone(server-file-name)
+  return true
 }
 
 proc write-zone-stanza {view chan config} {
@@ -1270,7 +1283,7 @@ proc write-zone-stanza {view chan config} {
 ###--------------------------------------------------------------------------
 ### Command-line interface.
 
-set CONFFILE "/etc/bind/zones.in"
+set CONFFILE "@pkgconfdir@/zones.in"
 
 defcmd outputs {} {
   help-text "List the output file names to stdout."
@@ -1316,7 +1329,9 @@ defcmd update {} {
   } {
 
     ## Close the open files.
-    foreach view $ZONECFG(all-views) { close $chan($view) }
+    foreach view $ZONECFG(all-views) {
+      catch { close $chan($view) }
+    }
 
     ## If we succeeded, rename the output files into their proper places;
     ## otherwise, delete them.
@@ -1326,7 +1341,7 @@ defcmd update {} {
       }
       eval exec $ZONECFG(reconfig-command)
     } else {
-      file delete -force -- "$out($view).new"
+      catch { file delete -force -- "$out($view).new" }
     }
   }
 }
@@ -1334,8 +1349,8 @@ defcmd update {} {
 defcmd install {user view name} {
   help-text "Install a new zone file.
 
-The file is for the given zone NAME and \(user-side) VIEW.  The file is
-provided by the named USER"
+           The file is for the given zone NAME and \(user-side) VIEW.  The file is
+           provided by the named USER"
 } {
   global QUIS ZONECFG ZONES CONFFILE errorInfo errorCode
 
@@ -1343,7 +1358,7 @@ provided by the named USER"
   confspc-eval toplevel [list source $CONFFILE]
 
   ## Make sure there's a temporary directory.
-  file mkdir [file join $ZONECFG(master-dir) "tmp"]
+  file mkdir [file join $ZONECFG(home-dir) "tmp"]
 
   ## Keep track of cleanup jobs.
   set cleanup {}
@@ -1374,7 +1389,7 @@ provided by the named USER"
     ## Make a new temporary file to read the zone into.
     set pid [pid]
     for {set i 0} {$i < 1000} {incr i} {
-      set tmp [file join $ZONECFG(master-dir) "tmp" \
+      set tmp [file join $ZONECFG(home-dir) "tmp" \
                   "tmp.$pid.$i.$user.$name"]
       if {![catch { set chan [open $tmp {WRONLY CREAT EXCL}] } msg]} {
        break
@@ -1401,15 +1416,15 @@ provided by the named USER"
 
     ## Check the zone for sanity.
     if {![run "zone check" $zone(checkzone-command) \
-            "%z" $name \
-            "%v" $view \
-            "%f" $tmp]} {
+             "%z" $name \
+             "%v" $view \
+             "%f" $tmp]} {
       eval $cleanup
       exit 1
     }
 
     ## If the zone wants signing, better to do that now.
-    if {![sign-zone-file $matchinfo $tmp keep]} {
+    if {![sign-zone-file $matchinfo keep $tmp]} {
       eval $cleanup
       exit 2
     }
@@ -1459,8 +1474,8 @@ defcmd sign {} {
        ## Sign the zone file if we haven't tried before.
        set id [list $zone(name) $zone(mapped-view)]
        if {![info exists seen($id)]} {
-         if {[sign-zone-file $compinfo \
-                  $zone(file-name) $zone(soa-format)]} {
+         if {[sign-zone-file $compinfo $zone(soa-format) \
+                  $zone(server-file-name)]} {
            set seen($id) true
          } else {
            set rc 2
@@ -1496,7 +1511,7 @@ defcmd sign {} {
 ###--------------------------------------------------------------------------
 ### Main program.
 
-set VERSION "1.0.0"
+set VERSION "@VERSION@"
 set USAGE() " \[-OPTIONS] SUBCOMMAND \[ARGUMENTS...]"
 
 define-options OPTS {