#!/bin/sh
#
#	$Header: /afs/sipb.mit.edu/project/sipb-athena/repository/src/mkserv/mkserv.sh,v 1.20 1996/06/02 07:41:44 ghudson Exp $
#
#	Make server script.
#
#	This script does various hacing to a workstation to make it
#	act as a server. The type of servers are described below.
#
#	remote: Configure a system that some one can login on remotly.
#	ops: configuration for Athena Operations
#
#	For example, to make an Athena standalone NFS server, type:
#	"mkserv ops nfs"
#
#	If the RVDROOT environment variable is set, use that over the default
#	root directory of the RVD (/srvd, currently).
#
#	If the SRVDIR environment variable is set, use that over the default
#	directory that contains the configuration files (currently it is
#	/srvd/usr/athena/lib/update).


RVDROOT=${RVDROOT-/srvd}
export RVDROOT

SRVDIR=${SRVDIR-/srvd/usr/athena/lib/update}
export SRVDIR

LOGFILE=/tmp/mkserv.log
export LOGFILE

PATH=/bin/athena:/usr/athena/bin:/usr/athena/etc:/usr/ucb:/bin:/usr/bin:/etc:/usr/etc:${RVDROOT}/usr/bin:${SRVDIR}
export PATH

. /etc/athena/rc.conf

pflag="false"
cflag=""
uflag=""
bad=0

#
# Parse command line
#
while [ 1 ]; do
case $1 in
	-v)	vflag=""; shift;;
	*)	break;;
esac
done

SYNCOPTS="${SYNCOPTS--nodstrules} ${vflag--q}"
export SYNCOPTS

if [ $# = 0 ]; then
	/bin/echo "Usage: mkserv [-v] [service ...] [-service ...]"
	exit 1
fi

if [ ! -f ${RVDROOT}/.rvdinfo ]; then
	/bin/echo "System packs Not present."
	exit 1
fi

if [ "`/usr/ucb/whoami`" != "root" ]; then
	/bin/echo "You must be root to run this script."
	exit 1
fi



# #
# # Try to find out where the servers directory is by looking at the
# # command line
# #
# dir=`/bin/expr "$0" : '^\(.*/\)[^/]*$'`
# if [ "${dir}" = "" ]; then dir=/srvd/servers; fi
# 
# chdir ${SRVDIR=$dir}
# if [ $? != 0 ]; then
# 	/bin/echo "Can't find standard server install directory."
# 	exit 1
# fi
# export SRVDIR


#
# Initialize some more variables and start the update
#
#PATH=${SRVDIR}:${PATH}
VERS="`/bin/awk '{a=$0}; END{print a}' /etc/athena/version`"
MACH=`/bin/expr "${VERS}" : '.* .\(.*\). Version .*'`
VERS=`/bin/expr "${VERS}" : '.* Version \([^ ]*\) .*'`
export VERS
export MACH

##########################
# Machine specific setup #
##########################
if [ "${SERVERDIR}" = "" ]; then
case "${MACH}" in
DS*|DECMIPS)
	SERVERDIR=/var/server
	;;
RSAIX|POWER*)
	if [ ! -d /usr/local ]; then /bin/mkdir /usr/local; fi
	SERVERDIR=/usr/local/server
	;;
*)
	SERVERDIR=/site/server
	;;
esac
export SERVERDIR
fi

if [ $VERS = "Update" ]; then
	/bin/echo "You are in the middle of an update.."
	exit 1
fi

umask 22
/bin/echo "Athena Server ($MACH) Version Update `/bin/date`" >> /etc/athena/version

if [ ! -d ${SERVERDIR} ]; then
	/bin/mkdir ${SERVERDIR}
fi
if [ ! -f ${SERVERDIR}/.services -a -f ${SERVERDIR}/.servers ]; then
	/bin/sed s/stand/ops/ ${SERVERDIR}/.servers > ${SERVERDIR}/.services
fi
if [ ! -f ${SERVERDIR}/.services ]; then
	/bin/cp /dev/null ${SERVERDIR}/.services
fi


#
# Validate the new services (determine additions/deletions)
#
/bin/rm -f ${LOGFILE} /tmp/rc.conf.change
/bin/rm -f /tmp/.services /tmp/.services.old /tmp/.services.sed

/bin/cp ${SERVERDIR}/.services /tmp/.services.old
/bin/cp /dev/null /tmp/.services
/bin/cp /dev/null ${LOGFILE}

for i in $*; do
	case $i in
	-*)
		a=`expr $i : '-\(.*\)$'`
		echo "/^$a\$/d" >> /tmp/.services.sed
		;;
	update)	uflag="yes" ;;
	clean)	cflag="yes" ;;
	public)	pflag="true" ;;
	*)
		if [ -f ${SRVDIR}/$i.add ]; then
			/bin/echo $i >> /tmp/.services
		else
			/bin/echo "$i is not a valid server type"
		fi
		;;
	esac
done

/bin/echo p >> /tmp/.services.sed
if [ "${cflag}" = "" ]; then
	/bin/sed -n -f /tmp/.services.sed \
		${SERVERDIR}/.services >> /tmp/.services
fi
if [ "${pflag}" = "true" ]; then
	/bin/cp /dev/null /tmp/.services
fi
/bin/rm -f /tmp/.services.sed

a="`/bin/cat /tmp/.services`"
if [ "$a" = "" ]; then
	/bin/rm -rf ${SERVERDIR}
else
	# Record the base services
	/bin/rm -f ${SERVERDIR}/.services
	/usr/bin/sort -u /tmp/.services > ${SERVERDIR}/.services
fi

# Work out dependencies
for srvfile in .services.old .services; do
    a=0; b=1
    while [ $a != $b ]; do
	for i in `cat /tmp/${srvfile}`; do
		awk '($1=="depend" && $2=="'$i'") \
			{for (i=3;i<=NF;i++){printf("%s\n",$i);}};' \
			${SRVDIR}/config >> /tmp/${srvfile}
	done
	/usr/bin/sort -u /tmp/${srvfile} > /tmp/.services.new
	/bin/mv -f /tmp/.services.new /tmp/${srvfile}
	a=$b;b=`/bin/awk 'END{print NR}' /tmp/${srvfile}`
    done
done

# Compute rc.conf changes
(echo `cat /tmp/.services`; cat ${SRVDIR}/config) | awk \
	'(NR==1) {for (ns=1;ns<=NF;ns++) {s[ns]=$ns}}; \
	 ($1=="rc.conf") {x=4;for (i=5;i<=NF;i++) { \
				for (j=1;j<ns;j++) { \
				 if (s[j]==$i) {x=3;break}}}; \
			  if ($x!="?") {printf("%s=%s\n",$2,$x)}};' \
	>> /tmp/rc.conf.change

for i in `comm -23 /tmp/.services.old /tmp/.services`; do
	if [ -f ${SRVDIR}/$i.del ]; then
		/bin/echo ""; /bin/echo "Running ${SRVDIR}/$i.del"
		/bin/sh ${SRVDIR}/$i.del
	fi
done
for i in `cat /tmp/.services`; do
	if [ -f ${SRVDIR}/$i.add ]; then
		/bin/echo ""; /bin/echo "Running ${SRVDIR}/$i.add"
		/bin/sh ${SRVDIR}/$i.add
	fi
done

#
# Run the two synctrees...
#
/bin/echo ""
if [ -d ${SERVERDIR} ]; then
	/bin/echo "Updating ${SERVERDIR}..."

	if [ -f ${SERVERDIR}/.private.sync ]; then
		/bin/sed -e 's/^\( *[a-z].*\)$/"\1"/' \
			${SERVERDIR}/.private.sync > /tmp/private.sync
	else
		/bin/cp /dev/null /tmp/private.sync
	fi

	/bin/sed -e 's/^\( *[a-z].*\)$/"\1"/' ${SRVDIR}/services.sync | \
		/lib/cpp -I/tmp `/bin/sed -e 's/^/-D/' /tmp/.services` | \
		/bin/sed -e '/^$/d' -e '/^[^"]/d' -e 's/^"\(.*\)"$/\1/' \
		> /tmp/services.sync.cpp
	synctree -s ${RVDROOT} -d ${SERVERDIR} \
		-a /tmp/services.sync.cpp ${SYNCOPTS}
	if [ $? != 0 ]; then bad=1; fi
fi

/bin/echo "Updating root symlinks..."
if [ -f /etc/svcorder -o -f /etc/svc.conf ]; then
	for i in `find / -mount -type l -exec /bin/ls -l {} \; | \
		/bin/sed -n -e "s:^.*${SERVERDIR}::p"`; do
		/bin/rm -f $i; /bin/ln -s ${RVDROOT}$i $i
	done
else
	for i in `find / -xdev -type l -ls | \
		/bin/sed -n -e "s:^.*${SERVERDIR}::p"`; do
		/bin/rm -f $i; /bin/ln -s ${RVDROOT}$i $i
	done
fi

if [ -d ${SERVERDIR} -a ${SERVERDIR} != "/" -a $bad = 0 ]; then
	synctree -s ${SERVERDIR} -d / -a ${SRVDIR}/final.sync ${SYNCOPTS}
fi

/bin/rm -f /tmp/services.sync.cpp /tmp/private.sync /tmp/.services



#
# Update rc.conf
#
/bin/echo "Updating rc.conf"
/bin/sed -e '/=?/d' \
	-e 's:^\([^=]*\)=\(.*\)$:s/^\1=.*export/\1=\2;		export/:' \
	/tmp/rc.conf.change > /tmp/rc.conf.sed
/bin/sed -e "s/PUBLIC=.*export/PUBLIC=${pflag};		export/" \
	/etc/athena/rc.conf > /tmp/rc.conf
if [ ! -f /etc/athena/rc.conf.old ]; then
	/bin/rm -f /etc/athena/rc.conf.old
	/bin/mv -f /etc/athena/rc.conf /etc/athena/rc.conf.old
fi
/bin/rm -f /etc/athena/rc.conf
/bin/sed -f /tmp/rc.conf.sed /tmp/rc.conf > /etc/athena/rc.conf
/bin/rm -f /tmp/rc.conf /tmp/rc.conf.sed /tmp/rc.conf.change


#
# Finish off
#

/bin/echo ""
/bin/cat ${LOGFILE}
/bin/rm -f ${LOGFILE}

if [ -f ${SERVERDIR}/.private ]; then
	/bin/echo "Running ${SERVERDIR}/.private ..."
	sh ${SERVERDIR}/.private
	if [ $? != 0 ]; then bad=1; fi
fi

if [ -d ${SERVERDIR} ]; then
	wstype=Server
else
	wstype=Workstation
fi

if [ $bad = 0 ]; then
    /bin/echo "Athena $wstype ($MACH) Version $VERS `/bin/date`" >> /etc/athena/version
fi

/bin/cat << EOF

Update finished.

The service change requests will take effect upon the next reboot
of the machine.
EOF

if [ -d ${SERVERDIR} ]; then
	/bin/cat << EOF

${SERVERDIR} has been used for the server specific files
Do not modify these files as they can be replaced at any time.
EOF
fi

/bin/sync
exit $bad
