#! /bin/sh
#
# $Header: nsmake.sh,v 4.300 91/06/08 23:51:22 root Rel41 $ SONY;
#
PATH=/usr/ucb:/usr/bin:/bin:/usr/etc:/etc
DIR=data
IGNORE=false

### check arguments
if [ $# -lt 2 ] ; then
	echo "Usage: $0 default_domain hosts_file [hosts_file ...]"
	exit 1
fi
DEFDOM=$1
shift

### set up environment
if [ ! -d $DIR ] ; then mkdir $DIR; fi
for FILE in $DIR/*.hosts ; do
	rm -f $FILE
done

WHOAMI=`whoami`
if [ x$WHOAMI = xroot ] ; then
	if [ x$USER = x -o x$USER = xroot ]; then
		TTY=`tty | sed 's/.*\///'`
		USER=`who | grep "$TTY" | sed 's/[ 	].*//'`
		if [ "$USER" = "" ] ; then
			USER=root
		fi
	fi
	WHOAMI=$USER
fi

HOSTNAME=`hostname`
case $HOSTNAME in
*.*)	HOSTNAME=$HOSTNAME.	;;
*)	HOSTNAME=$HOSTNAME.$DEFDOM. ;;
esac

### read data from each hosts file
for SRC
do
	DOMAIN=$DEFDOM
	IGNORE=false
	sed -e 's/\(.\)#.*/\1/' -e '/^[ 	]*$/d' $SRC |
	while read LINE ; do
### handle comment and command line
		case "$LINE" in
		"#ns"*|"#NS"*)
			COMMAND=`echo "$LINE" | tr A-Z a-z | 
				sed 's/^#..[ 	]*//'`
			case $COMMAND in
			stop*|STOP*)
				IGNORE=true ;;
			cont*|CONT*)
				IGNORE=false ;;
			domain*|DOMAIN*)
				DOMAIN=`expr "$COMMAND" : '.*=[	 ]*\(.*\)'` ;;
			esac
			continue ;;
		"#"*)	continue ;;
		esac
		if $IGNORE ; then continue ; fi
### read data from line
		set -$- $LINE
		ADDR=$1; shift
		CNAME=$1; shift
		case $CNAME in
		*.$DOMAIN)	CNAME=`expr $CNAME : '\([^\.]*\)'` ;;
		*.*)		CNAME=$CNAME. ;;
		esac
		ALIAS=
		while [ x$1 != x ] ; do
			case $1 in
			localhost.my.domain)	NAME=localhost ;;
			*.$DOMAIN)	NAME=`expr $1 : '\([^\.]*\)'` ;;
			*)		NAME=$1 ;;
			esac
			shift
			if [ x$NAME != x$CNAME ] ; then
				ALIAS="$ALIAS $NAME"
			fi
		done
### convert dot notation to 4 octet decimal
		eval `echo $ADDR | sed -e 's/^/A1=/' -e 's/\./; A2=/' \
			-e 's/\./; A3=/' -e 's/\./; A4=/' -e 's/\..*//'`
		case $ADDR in
		*.*.*.*)	A4=`expr 0$A4 + 0`
				A3=`expr 0$A3 + 0`
				A2=`expr 0$A2 + 0`
				A1=`expr 0$A1 + 0`
				;;
		*.*.*)		A4=`expr 0$A3 % 256`
				A3=`expr 0$A3 / 256`
				A2=`expr 0$A2 + 0`
				A1=`expr 0$A1 + 0`
				;;
		*.*)		A4=`expr 0$A2 % 256`
				A3=`expr 0$A2 / 256 % 256`
				A2=`expr 0$A2 / 65536`
				A1=`expr 0$A1 + 0`
				;;
		*)		A4=`expr 0$A1 % 256`
				A3=`expr 0$A1 / 256 % 256`
				A2=`expr 0$A1 / 65536 % 256`
				A1=`expr 0$A1 / 16777216`
				;;
		esac
### make up local label, domain name and nets
		case $CNAME in
		localhost)
			DOM=localhost
			NAME=localhost.
			;;
		*.)	DOM=`echo $CNAME | sed 's/^[^\.*]*.\(.*\)\./\1/'`
			NAME=`echo $CNAME | sed 's/\..*//'`
			;;
		*)	DOM=$DOMAIN
			NAME=$CNAME
			;;
		esac
		if [ $A1 -lt 128 ] ; then
			NET=$A1
			HOST=$A4.$A3.$A2
		elif [ $A1 -lt 192 ] ; then
			NET=$A1.$A2
			HOST=$A4.$A3
		else
			NET=$A1.$A2.$A3
			HOST=$A4
		fi

### write to hosts data file
		if [ x$DOM = x ] ; then DOM=root; fi
		echo $NAME $A1.$A2.$A3.$A4 |
			awk '{ printf "%-32sIN\tA\t%s\n", $1, $2 }' \
			>> $DIR/$DOM.hosts

		for NAME in $ALIAS ; do
			case $NAME in
			*.)	DOM=`echo $NAME | sed 's/^[^\.*]*.\(.*\)\./\1/'`
				NAME=`echo $NAME | sed 's/\..*//'`
				case $CNAME in
				*.)	CNAM=$CNAME ;;
				*)	CNAM=$CNAME.$DOMAIN. ;;
				esac
				;;
			*)	DOM=$DOMAIN
				CNAM=$CNAME
				;;
			esac
			if [ x$DOM = x ] ; then DOM=root; fi
			echo $NAME $CNAM |
				awk '{ printf "%-32sIN\tCNAME\t%s\n", $1, $2 }' \
				>> $DIR/$DOM.hosts
		done
### write to reverse hosts data file
		case $CNAME in
		localhost)	echo $HOST $CNAME.;;
		*.)	echo $HOST $CNAME ;;
		*)	echo $HOST $CNAME.$DOMAIN. ;;
		esac |
			awk '{ printf "%-32sIN\tPTR\t%s\n", $1, $2 }' \
			>> $DIR/$NET.hosts
	done # each line
done # each file

### make zone file from hosts data files
for ZONE in `ls *.template $DIR/*.hosts 2>&- |
		sed -e 's;.*/;;' -e 's;\.[^\.]*$;;'` ; do
	if [ -f $DIR/$ZONE.zone ] ; then
		mv $DIR/$ZONE.zone $DIR/$ZONE.zone.BAK
	fi
	case $ZONE in
	[0-9]*)	
			ORIGIN=`echo $ZONE | awk '{ FS="."; print $3, $2, $1}'\
				| sed 's/^ *//' | tr ' ' .`.in-addr.arpa. ;;
	root)		ORIGIN=.			;;
	*)		ORIGIN=$ZONE.			;;
	esac
### increment serial number
	if [ -f $DIR/$ZONE.serial ] ; then
		SERIAL=`cat $DIR/$ZONE.serial`
		SERIAL=`expr $SERIAL + 1`
	else
		SERIAL=1
	fi
	echo $SERIAL > $DIR/$ZONE.serial
### make template file if it does not exist
	if [ ! -f $ZONE.template ] ; then
		cat > $ZONE.template << EOF
;
;	template for $ORIGIN
;
\$ORIGIN	$ORIGIN

@				IN	SOA	%HOSTNAME% %WHOAMI%.%HOSTNAME% (
						%SERIAL%	; Serial
						3600	; Refresh
						300	; Retry
						3600000	; Expire
						3600	; Minimum
						)
				IN	NS	%HOSTNAME%
EOF
		case $ZONE in
		[0-9]*|localhost)	;;
		*)	if grep -siw mailhost $DIR/$ZONE.hosts ; then
				MAILHOST=mailhost
			else
				MAILHOST=$HOSTNAME
			fi
			cat >> $ZONE.template << EOF

@				IN	MX 100	$MAILHOST

localhost			IN	CNAME	localhost.
EOF
			;;
		esac
	fi
### write to zone file, use template if it exists
	cat > $DIR/$ZONE.zone << EOF
; Do not edit this file directly.
; This file was generated by $0

EOF
	sed -e "s/%SERIAL%/$SERIAL/g" \
		-e "s/%ORIGIN%/$ORIGIN/g" \
		-e "s/%WHOAMI%/$WHOAMI/g" \
		-e "s/%HOSTNAME%/$HOSTNAME/g" \
		$ZONE.template >> $DIR/$ZONE.zone
### append hosts file to zone file
	if [ -f $DIR/$ZONE.hosts ] ; then
		case $ZONE in
		[0-9]*)	sort -bfu +0 -1 $DIR/$ZONE.hosts | \
				sort -bfn | sort -bfn -t. +1 -2	;;
		*)	sort -bfu $DIR/$ZONE.hosts		;;
		esac >> $DIR/$ZONE.zone
	fi
done # each hosts file

exit 0
