--- /dev/null
+#!/bin/bash
+set -e
+base=/var/named
+conf=$base/conf
+etcfile=/etc/named/zones-rgc
+
+check=true
+install=false
+hostdelg=false
+hostzone=false
+progress=true
+usage=true
+
+while [ $# -gt 0 ]
+do
+ case "$1" in
+ -f) usage=false; check=false; install=true ;;
+ -y) usage=false; check=true; install=true ;;
+ -n) usage=false; check=true; install=false ;;
+ -h) hostdelg=true; hostzone=false ;;
+ -z) hostdelg=true; hostzone=true ;;
+ -q) progress=false ;;
+ *) echo >&2 "$0: usage: $0 [-y|-f] [-h|-z] [-q]"; exit 3 ;;
+ esac
+ shift
+done
+
+if $usage
+then
+ cat <<END >&2
+usage: named-conf-regen -f|-y|-n [-h|-z]
+operation modes:
+ -f install without checking } but you must then
+ -y check and install } ndc reload
+ -n check only
+additional options:
+ -h check output from host -C
+ -z check output from host -C and host -val
+END
+ exit 1
+fi
+
+beginfile () {
+ if $install
+ then
+ exec >$conf/$1.new
+ else
+ exec >/dev/null
+ fi
+ currentfile=$1
+}
+
+endfile () {
+ exec >/dev/null
+ files="$files $currentfile"
+}
+
+installfiles () {
+ if $install
+ then
+ cd $conf
+ for f in $files
+ do
+ mv -f $f.new $f
+ done
+ fi
+}
+
+warnings=0
+
+warning () {
+ echo >&2 "$zone $style: $*"
+ warnings=$[$warnings+1]
+}
+
+equlines () {
+ if [ "x`echo \" $2\" | wc -l`" != "x`echo \" $3\" | wc -l`" ]
+ then
+ warning "$1 >$2|$3<"
+ fi
+}
+
+checkhostout () {
+ set +e
+ hostout="`host $1 \"$zone\" 2>&1 >/dev/null $2 | egrep -v \
+'^ \!\!\! .* SOA primary .* is not advertised via NS$'`"
+ set -e
+ if [ "x$hostout" = x ]; then return; fi
+ if $hostfirstwarn
+ then
+ warning "warnings from host:"
+ hostfirstwarn=false
+ fi
+ echo >&2 "$hostout"
+}
+
+progress () {
+ if $progress
+ then
+ echo -n "$zone $style " >&2
+ echo -ne '\r' >&2
+ fi
+}
+
+cd $base/primary
+zones="*_db"
+
+beginfile primary.zones
+for f in $zones
+do
+ zone="`echo $f | sed -e 's/_db$//'`"
+ cat <<END
+zone "$zone" {
+ type master;
+ file "primary/$f";
+};
+END
+done
+endfile
+
+myname=''
+
+beginfile secondary.zones
+exec <$etcfile
+while read style zone servers
+do
+ names=''
+ case "$style" in
+ myname)
+ myname=$zone
+ continue
+ ;;
+ secondary)
+ progress
+ file="slave/$zone"
+ if $check
+ then
+ rectype=SOA
+ set -e; soa="`host -t soa $zone.`"; set +e
+ soaname="`echo \" $soa\" | expand | sed -e '
+ s/^ [^ ][^ ]* *SOA *//; s/ .*$//; q
+ '`"
+ equlines SOA "$soaname" ''
+ fi
+ ;;
+ backup|unoff)
+ progress
+ rectype=NS
+ file="slave/$zone"
+ ;;
+ '#'|'')
+ continue
+ ;;
+ *)
+ echo >&2 "$etcfile: $style"
+ exit 3
+ esac
+
+ if $check
+ then
+ set -e; ns="`host -t ns $zone.`"; set +e
+ nsnames="`echo \" $ns\" | expand | tr A-Z a-z | sed -n '
+ 1s/^ //
+ s/^[^ ][^ ]* *ns *\([0-9a-z][-.0-9a-z]*\)$/\1/p
+ '`"
+ equlines NS "$nsnames" "$ns"
+ nsnames="`echo $nsnames | tr '
+' ' '`"
+
+ if [ "x$myname" != x ]
+ then
+ meadvert=false
+ for ns in $nsnames
+ do
+ if [ "x$myname" = "x$ns" ]
+ then
+ meadvert=true
+ fi
+ done
+ fi
+
+ case "$style" in
+ secondary) names="$soaname" ;;
+ unoff|backup) names="$nsnames" ;;
+ esac
+
+ case "$style" in
+ secondary|backup)
+ if [ $meadvert = false ]
+ then
+ warning "$myname unlisted NS $nsnames"
+ fi
+ ;;
+ unoff)
+ if $meadvert = false
+ then
+ warning "$myname advertised NS $nsnames"
+ fi
+ ;;
+ esac
+
+ addrs=''
+ for ns in $names
+ do
+ set -e; a="`host -t a \"$ns\".`"; set +e
+ taddrs="`echo \" $a\" | expand | sed -n '
+ 1s/^ //
+ s/^[^ ][^ ]* *A *\([0-9][.0-9]*\)/\1/p
+ '`"
+ equlines "A $ns" "$a" "$taddrs"
+ addrs="$addrs $taddrs"
+ done
+ fi
+
+ cat <<END
+zone "$zone" {
+ type slave;
+ file "$file";
+ masters {
+END
+ for server in $servers
+ do
+ echo " $server;"
+ if $check
+ then
+ notfound=true
+ for addr in $addrs
+ do
+ if [ "x$addr" = "x$server" ]
+ then
+ notfound=false
+ fi
+ done
+ if $notfound
+ then
+ warning "server $server? but $rectype $names" $addrs
+ fi
+ fi
+ done
+ cat <<END
+ };
+};
+END
+ hostfirstwarn=true
+ if $hostdelg
+ then
+ checkhostout -C
+ fi
+ if $hostzone
+ then
+ checkhostout -val localhost
+ fi
+done
+endfile
+
+if [ $warnings != 0 ]
+then
+ echo >&2 "$warnings warnings "
+fi
+
+installfiles