#!/bin/sh
#	program:	cachebuild
#	release:	1.5.0
#	purpose:	Build a new root cache file for a BIND nameserver.
#			Default builds like named.root file on Internic FTP site,
#			but you can also have it group record types too.
#	input:		optional nameserver to direct queries to,
#			optional "-o" option for old output format.
#	output:		"A" and "NS" records, with comments, in the form of
#			a root.cache file for a BIND nameserver.
#	exit value:	0 if succeeds, 1 if "root" tool fails,
#			2 if "root" returned no records,
#			3 if could not obtain NS records for any nameserver.
#			Errors go to stderr.
#
#
# Copyright (C) 1993-2000 Paul A. Balyoz <pab@domtools.com>
#
#    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., 675 Mass Ave, Cambridge, MA 02139, USA.
#

# Temporary storage file
TMP=/tmp/`basename $0`.$$
TMPTXT=/tmp/`basename $0`-txt.$$

# --------------------------------------------------------------------------

usage() {
	echo "usage: $0 [-o] [@nameserver]" >&2
	echo 'ERROR'
	exit 1
}

if test $# -gt 2; then
	usage
fi

oldstyle=0
atnameserver=
while test $# -gt 0; do
	case "$1" in
		-o)  oldstyle=1 ;;
		@*)  atnameserver="$1" ;;
		*)   usage ;;
	esac
	shift
done

# Determine if we're using SysV or BSD style echo's.

if test `echo "a\c" | wc -l` -eq 1; then
	ECHON=-n ECHOC=			# BSD
else
	ECHON= ECHOC='\c'		# SysV
fi

# Locate all root nameservers

/usr/local/domtools/bin/root > $TMP
if test $? -ne 0; then
	echo "cachebuild: ERROR: 'root' tool returned failure." >&2
	rm -f $TMP
	exit 1
fi
if test `wc -l < $TMP` -lt 1; then
	echo "cachebuild: ERROR: 'root' tool returned no records." >&2
	rm -f $TMP
	exit 2
fi

# Generate header info

echo ";"
echo "; root.cache (named.ca, named.root)"
echo "; Created by $USER@`hostname` on `date`"
echo "; Automatically built by cachebuild, any changes you make may go away."
echo ";"
echo ""

if test $oldstyle -eq 1; then

	echo ";"
	echo "; Initial cache data for root domain servers."
	echo ";"
	echo ""

	# List NS records for root nameservers

	echo $ECHON ".$ECHOC"
	for ns in `cat $TMP`; do
		echo "			99999999	IN	NS	$ns"
	done

	# More header info

	echo ""
	echo ";"
	echo "; Prep the cache (hotwire the addresses).	 Order does not matter."
	echo ";"
	echo ""

	# List A records for root nameservers

	for ns in `cat $TMP`; do
		addrs=`/usr/local/domtools/bin/address $atnameserver $ns`
		if test $? -ne 0; then
			echo "cachebuild: ERROR: could not obtain address RRs for $ns" >&2
			rm -f $TMP
			exit 3
		fi
		for addr in $addrs; do
			echo $ECHON "$ns	$ECHOC"
			len=`echo $ECHON "$ns$ECHOC" | wc -c`
			if test $len -lt 8; then
				echo $ECHON "		$ECHOC"
			elif test $len -lt 16; then
				echo $ECHON "	$ECHOC"
			fi
			echo "99999999	IN	A	$addr"
		done
	done

# New-style, where each nameserver has TXT record comments above it.

else

	in="IN"			# we blank this out after it's printed once
	for ns in `/usr/local/domtools/bin/domsort < $TMP`; do
		# print comments
		echo ";"
		/usr/local/domtools/bin/txt $atnameserver $ns > $TMPTXT 2>/dev/null
		if test $? -eq 0; then
			sed -e 's/^"//; s/"$//; s/^/; /' < $TMPTXT	# print txt recs as comments
			echo ";"
		fi

		# print NS record
		echo ".                        3600000  $in  NS    $ns"
		in="  "

		# print A record
		addrs=`/usr/local/domtools/bin/address $atnameserver $ns`
		if test $? -ne 0; then
			echo "cachebuild: ERROR: could not obtain address RRs for $ns" >&2
			rm -f $TMP $TMPTXT
			exit 3
		fi
		for addr in $addrs; do
			echo $ECHON "$ns$ECHOC"				# ns
			perl -e 'print " "x(24-length($ARGV[0]))' $ns	# (spaces)
			echo " 3600000  $in  A     $addr"		# rest of rec
		done
	done

	echo "; End of File"

fi

rm -f $TMP $TMPTXT
exit 0
