#!/bin/sh
#
# Install diskless client on Solbourne server
#
# Copyright (c) 1989 Solbourne Computer, Inc.


#
# Global variables
#

Myname=`basename "$0"`
Usage="[-v] [-x] [-e] [-b swap_size] [-s swap_file] [-n os_release_name] [-r root_dir]
		[-u usr_dir] [-h home_dir] [-p pid] client machine_arch
Where:
	'-v'		- specifies verbose output mode
	'-x'		- turns on shell execution trace
	'-e'		- specifies that server's exports file will NOT be modified
	'-b swap_size'	- size of client swap file (see mkfile(8)), such as 32m
	'-s swap_file'	- name of file to create for client swap
	'-n os_release_name' - subdirectory name to use for machine dependent directories
				(i.e., '-n sun4.sunos.4.1' or '-n sun4.sunos.4.0.3')
	'-r root_dir'	- directory which will become the client's root
	'-u usr_dir'	- directory which will become the client's /usr
	'-h home_dir'	- directory which will become the client's /home
	'-p pid'	- specifies process id of sysadmin install tool
			  (should be used only by tool)
	'client'	- name of the diskless client to be installed
	'machine_arch'	- machine type of the client (sun2, sun3, sun4, sun4c, Series4, Series5, Series6, S4000)"

Vflag=:
Xflag=:
NO_EXPORTS=no

#
# Filesystem specific pathnames
#

EXPORT_DIR=${EXPORT_DIR-/export}
EXPORT_ROOT=${EXPORT_ROOT-${EXPORT_DIR}/root}
EXPORT_USR=${EXPORT_USR-${EXPORT_DIR}/exec}
EXPORT_SWAP=${EXPORT_SWAP-${EXPORT_DIR}/swap}
EXPORT_CRASH=${EXPORT_CRASH-${EXPORT_DIR}/crash}
EXPORT_FILE=${EXPORT_FILE-/etc/exports}
LOG=${LOG-/var/log/diskless_log}
MYPATH=${MYPATH-/usr/etc/setup}
SERVER_HOME=${SERVER_HOME-/home}
SERVER_HOSTS=${SERVER_HOSTS-/etc/hosts}
SERVER_ETHERS=${SERVER_ETHERS-/etc/ethers}
SERVER_BOOT=${SERVER_BOOT-/etc/bootparams}
TMP_ERR=/tmp/ins_err$$
TMP_EXERR=/tmp/ins_exerr$$
TMP_CLN=/tmp/ins_cln$$
TMP_BOOT=/tmp/ins_boot$$
TMP_EXP=/tmp/ins_exp$$
TMP_KVM=/tmp/ins_kvm$$
CURR_DIR=`/bin/pwd`
#
# Sysadmin tool variables
#

ADMPID=""
TMP_ADMOUT=/tmp/ins_cs$$

#
# Set up default path
#

PATH=/bin:/usr/bin:/usr/ucb:/usr/etc:${MYPATH}
export PATH

#
# Main function - test arguments and verify valid call
#
main()
{

	# Get optional argument

	while getopts "vxeb:s:n:r:u:h:p:" arg
	do
		case "$arg" in
		v)
			Vflag= ;;
		x)
			Xflag="set -x"
			set -x;;
		e)	NO_EXPORTS="yes";;
		b)	SWAPSIZE="$OPTARG";;
		s)	SWAPFILE="$OPTARG";;
		n)	CLIENT_MACH_NAME=".$OPTARG";;
		r)	CLIENT_ROOT="$OPTARG";;
		u)	CLIENT_USR="$OPTARG";;
		h)	CLIENT_HOME="$OPTARG";;
		p)	ADMPID="$OPTARG"
			TMP_ADMOUT=/tmp/ins_cs${ADMPID};;
		*)
			usage ;;
		esac
	done

	shift `expr $OPTIND - 1`

	# Test for proper remaining arguments

	if [ $# -ne 2 ]
	then
		usage
	fi

	# Test to see if we are running as root

	am_i_root || fatal "Must be run by the super user"

	# Get our server's hostname

	SERVER=`hostname` || fatal "Can not determine server's hostname"

	# Set variables based on arguments given

	CLIENT=${1-unknown}
	MACH=${2-unknown}
	MACH_NAME=${MACH}${CLIENT_MACH_NAME}
	SWAPSIZE=${SWAPSIZE-32m}	# Default swap file size is 32 megabytes
	SWAPFILE=${SWAPFILE-${EXPORT_SWAP}/${CLIENT}/swap.${CLIENT}}
	CLIENT_ROOT=${CLIENT_ROOT-${EXPORT_ROOT}/${CLIENT}}
	CLIENT_USR=${CLIENT_USR-${EXPORT_USR}/${MACH_NAME}}
	CLIENT_HOME=${CLIENT_HOME-${CLIENT_ROOT}/home}

	# Check to see if swapfile has a full path name. If not, assign
	# a full path name to the swapfile.

	if [ "`expr ${SWAPFILE} : '\(\/\).*'`" != "/" ]
	then
		if [ "${CURR_DIR}" != "/" ]
		then
			SWAPFILE=${CURR_DIR}/${SWAPFILE}
		else
			SWAPFILE=${CURR_DIR}${SWAPFILE}
		fi
	fi

	# If the swap directory is not the standard one, it should exist
	# now, and it should not be under root.

	SWAPDIR=`dirname ${SWAPFILE}` || fatal "Can not execute 'dirname'"

	if [ "${SWAPDIR}" != "${EXPORT_SWAP}/${CLIENT}" ]
	then
		if [ ! -d "${SWAPDIR}" ]
		then
			fatal "Swap directory \"${SWAPDIR}\" does not exist.
Verify and make this directory first."
		else
			verify_swapdir ${SWAPDIR}
		fi
	fi

	if [ "${MACH_NAME}" = "${MACH}" ]
	then
		ROOT_PROTO=${EXPORT_ROOT}/proto.${MACH_NAME}
	else
		ROOT_PROTO=${EXPORT_ROOT}/${MACH_NAME}
	fi

	# Verify swapsize argument is reasonable

	verify_swapsize

	# Display directory names to user

	$Vflag display "	** New diskless client installation **
  Client name:			${CLIENT}
  Machine architecture:		${MACH}
  OS Release name:		${MACH_NAME}
  Swap file size:		${SWAPSIZE}
  Client swap file:		${SWAPFILE}
  Client root directory:	${CLIENT_ROOT}
  Client /usr directory:	${CLIENT_USR}
  Client /home directory:	${CLIENT_HOME}"

	# Maintain a cleanup script to remove things if there is an error

	create_cleanup

	# Verify client exists in hosts file and get hex equivalent

	DOMAIN=`/bin/domainname` || fatal "Can not determine domainname"

	if [ "${DOMAIN}" = "" ]
	then
		DOMAIN="noname"
	fi

	if [ "${DOMAIN}" != "noname" ]
	then
		Host="ypmatch ${CLIENT} hosts"
		Ether="ypmatch ${CLIENT} ethers"
	else
		Host="grep -w ${CLIENT} ${SERVER_HOSTS} | grep -v '^#'"
		Ether="grep -w ${CLIENT} ${SERVER_ETHERS} | grep -v '^#'"
	fi

	# The [] enclose a space and a TAB

	INETADDR=`eval ${Host} | awk '{print $1}'`

	if [ "${INETADDR}" = "" ]
	then
		fatal "Client internet address not found.  Check /etc/hosts or yp"
	fi

	HEXADDR=`hex_inet ${INETADDR}` || fatal "Can not convert internet address"

	# Verify server can find client ethernet address

	if [ "`eval ${Ether} 2>/dev/null`" = "" ]
	then
		fatal "Can not find \"${CLIENT}\" ethernet address.
Add entry in /etc/ethers or yellow pages first"
	fi

	# may need to adjust ${SERVER} if this client is
	# on a differently-named gateway of this server

	adjust_server

	# Verify machine architecture and set boot file name

	BOOTFILE=boot.${MACH}

	case "${MACH}" in
	sun2)	HEXADDR=${HEXADDR}.SUN2 
		display "Warning:  /usr/etc/ndbootd needs to be running on server";;
	sun3)	;;
	sun4)	HEXADDR=${HEXADDR}.SUN4 ;;
	sun4c)	HEXADDR=${HEXADDR}.SUN4C ;;
	sun386)	HEXADDR=${HEXADDR}.S386
		BOOTFILE=boot.S386 ;;
	Series4 | Series5 | Series6 | S4000)
		BOOTFILE=boot.sun4 ;;
	*)
		fatal "Invalid machine architecture \"${MACH}\"
Must be 'sun2', 'sun3', 'sun4', 'sun4c', 'sun386', 'Series4', 'Series5', 'Series6', or 'S4000'"
	esac

	# Verify server directories have been configured for this architecture

	for i in ${EXPORT_ROOT} ${ROOT_PROTO} ${ROOT_PROTO}/etc ${EXPORT_SWAP} \
				${CLIENT_USR} /tftpboot
	do
		if [ ! -d $i ]
		then
			fatal "The directory \"$i\" does not exist on server.
Verify arguments, and run \"config_server\" first"
		fi
	done

	# Test standard export directory for client name.  It should
	# not exist now, but will be created.  If a directory other
	# than the standard one was specified, it should exist now,
	# and we will create a symbolic link to it.

	if [ -d ${EXPORT_ROOT}/${CLIENT} ]
	then
		fatal "The directory/link \"${EXPORT_ROOT}/${CLIENT}\" already exists.
This client name may already be in use.  Verify name
and if necessary use \"remove_client\" first"
	elif [ "${CLIENT_ROOT}" != "${EXPORT_ROOT}/${CLIENT}" ]
	then
		if [ ! -d "${CLIENT_ROOT}" ]
		then
			fatal "Client root directory \"${CLIENT_ROOT}\" does not exist.
Verify and make this directory first"
		else
			Make_cmd="ln -s ${CLIENT_ROOT} ${EXPORT_ROOT}/${CLIENT}"
			add_cleanup "rm -f ${EXPORT_ROOT}/${CLIENT};"
			add_cleanup "cd ${CLIENT_ROOT}"
			add_cleanup "rm -rf `ls -a|egrep '^\.$|^\.\.$'`"
			add_cleanup "cd /"
		fi
	else
		Make_cmd="mkdir ${EXPORT_ROOT}/${CLIENT}"
		add_cleanup "rm -rf ${EXPORT_ROOT}/${CLIENT};"
	fi

	# Arguments okay.  Record start in log and catch signals

	log "========== Installing new diskless client =========="
	log "$* Started `date`"
	trap "sig_abort; wrapup 1" 1 2 3 15

	# Do real work in a sub-shell, to capture error output for log
	# Redirect standard input to /dev/null, just in case something
	# tries to read.

	if [ "$ADMPID" != "" ]
	then
		do_cmd >$TMP_ERR 2>&1
	else
		(
			do_cmd ${1+"$@"} 2>&1
		) </dev/null | tee ${TMP_ERR}
	fi

	# Record any error output to log, and display to user
	# If there was an error, pass exit status up

	cmp -s ${TMP_ERR} /dev/null
	wrapup $?
}

#
# Verify client name and directories, and do operation
#

do_cmd()
{
	trap 1 2 3 15

	# Make directory or symbolic link, as determined before

	${Make_cmd} && chmod 700 ${CLIENT_ROOT}/. && /etc/chown root ${CLIENT_ROOT}/.

	if [ $? -ne 0 ]
	then
		fatal "Can not create client root directory and set owner/permissions"
	fi

	# Check to see if we have enough free disk space

	check_free $MACH "${CLIENT_ROOT}" "${SWAPFILE}"

	# Create client swap file - if we are going to run out of
	# disk space, this will probably be where it happens
	# If swap directory is in the standard place, do a mkdir
	# to create it.  Otherwise, make a symbolic link 

	rm -rf ${SWAPFILE} ${EXPORT_SWAP}/${CLIENT}

	if [ "${SWAPDIR}" = "${EXPORT_SWAP}/${CLIENT}" ]
	then
		mkdir "${SWAPDIR}"
	else
		ln -s "${SWAPDIR}" "${EXPORT_SWAP}/${CLIENT}"
	fi

	if [ $? -ne 0 ]
	then
		fatal "Can not make/link client swapfile parent directory"
	fi

	# Now make the big file

	mkfile ${SWAPSIZE} ${SWAPFILE} || 
		fatal "Can not create client swap file"

	# Create client directory in /export/crash

	mkdir ${EXPORT_CRASH}/${CLIENT} 2>/dev/null
	chmod 777 ${EXPORT_CRASH}/${CLIENT} 2>/dev/null

	# Create approriate TFTPBOOT directory link

	tftpboot_link || fatal "Can not create tftpboot link"

	# Clone client copy of root file system from prototype directory

	set +x
	clone_root_proto -r ${TMP_KVM} -s ${SERVER} -n ${MACH_NAME} -d ${DOMAIN} -h ${CLIENT_HOME} ${CLIENT} ${MACH} || exit 1

	${Xflag}

	if [ -s ${TMP_KVM} ]
	then
		CLIENT_KVM=`cat ${TMP_KVM}`
	else
		CLIENT_KVM=
	fi

	# Update server BOOTPARAMS file with client info

	update_bootparams || fatal "Can not update bootparams"

	# Update server EXPORTS file with client info

	if [ "$NO_EXPORTS" = "no" ]
	then
		if [ -f ${EXPORT_FILE} ]
		then
			cp ${EXPORT_FILE} ${TMP_EXP}
		else
			touch ${TMP_EXP}
		fi

		if [ $? -ne 0 ]
		then
			fatal "Can not create temporary exports file"
		fi

		set +x
		EXPORT_FILE=${TMP_EXP} update_exports ${CLIENT} ${CLIENT_ROOT} \
			${SWAPFILE} ${CLIENT_HOME} ${CLIENT_USR} \
			${CLIENT_KVM} || exit 1
		${Xflag}

		# New versions of files have been created.  Now install them

		trap "" 1 2 3 15

		if [ -f ${EXPORT_FILE} ]
		then
			cp ${EXPORT_FILE} ${EXPORT_FILE}-old
		else
			rm -f ${EXPORT_FILE}-old
		fi

		if [ -f ${SERVER_BOOT} ]
		then
			cp ${SERVER_BOOT} ${SERVER_BOOT}-old
		else
			rm -f ${SERVER_BOOT}-old
		fi

		cp ${TMP_EXP} ${EXPORT_FILE} && cp ${TMP_BOOT} ${SERVER_BOOT} 

		if [ $? -ne 0 ]
		then
			fatal "Error occurred installing new server data file
Check server ${EXPORT_FILE} and ${SERVER_BOOT} files"
		fi

		# Run /usr/etc/exportfs to read new exports file and direct
		# output to new errror file. exportfs returns a bogus status, so
		# check error file for errors.  Fixes bug B910508371. 

		exportfs -a 2>${TMP_EXERR}

		if [ -s ${TMP_EXERR} ]
		then
			display "Error in ${EXPORT_FILE}.  Correct it and execute \"/usr/etc/exportfs -a\""
			log "Error in ${EXPORT_FILE}.  Correct it and execute \"/usr/etc/exportfs -a\""
		fi
	else
		cp ${TMP_BOOT} ${SERVER_BOOT}
		if [ $? -ne 0 ]
		then
			fatal "Error occurred installing new server data file
Check ${SERVER_BOOT} file"
		fi
	fi
}

#
# Check root, swap, and export directories to see if we have enough
# free disk space
#

check_free()
{
	Mach=${1-${MACH}}
	Rdir=${2-${EXPORT_ROOT}}
	Sdir=${3-${EXPORT_SWAP}}

	# Clone root needs minimal
	Needr=2000

	# Determine amount of swap needed by converting SWAPSIZE

	Needs=`echo $SWAPSIZE p | sed -e 's?\(.*\)m?\1 1024 *?' \
		-e 's?\(.*\)M?\1 1024 *?' \
		-e 's?\(.*\)k?\1 1 *?'  \
		-e 's?\(.*\)K?\1 1 *?' \
		-e 's?\(.*\)b?\1 1 + 2 /?' \
		-e 's?\(.*\)B?\1 1 + 2 /?' \
		-e 's?^\([0-9]*\) p$?\1 1023 + 1024 / p?' |
		dc`

	# If an error occurred, just return with no warning

	if [ $? -ne 0 ]
	then
		return
	fi

	# Now check root and swap directories to see what we have

	until [ -d $Rdir ]
	do
		Rdir=`dirname $Rdir`
	done
	until [ -d $Sdir ]
	do
		Sdir=`dirname $Sdir`
	done

	Haver=`df $Rdir|tail -1` || return
	Haves=`df $Sdir|tail -1` || return

	# If everything is on the same file system, add values

	if [ "$Haver" = "$Haves" ]
	then
		Needr=`expr $Needr + $Needs`
		Needs=0
	fi

	# Get real free values

	Haver=`echo $Haver|awk '{print $4}'`
	Haves=`echo $Haves|awk '{print $4}'`

	if [ "$Haver" -lt "$Needr" -o "$Haves" -lt "$Needs" ]
	then
		display "WARNING:  There may not be enough free disk space
WARNING:  in $Rdir or $Sdir for client
WARNING:  installation"
	fi
}

#
# Create boot file link in server's /tftpboot directory
#

tftpboot_link()
{
	if [ ! -f /tftpboot/$BOOTFILE ]
	then
		fatal "Server /tftpboot/$BOOTFILE does not exist
Verify machine architecture and run \"config_server\""
	fi

	ln -s /tftpboot/$BOOTFILE /tftpboot/${HEXADDR} || 
			 fatal "Can not create tftpboot link"

	add_cleanup "rm -f /tftpboot/${HEXADDR};"
}

#
# Update server /etc/bootparams file with client info
#

update_bootparams()
{
	if [ -f ${SERVER_BOOT} ]
	then
		cp ${SERVER_BOOT} ${TMP_BOOT} ||
			fatal "Can not copy \"${SERVER_BOOT}\""
	fi

	echo "# ${CLIENT}" >>${TMP_BOOT}

	ed - ${TMP_BOOT} <<-_EOF_
		H
		g/${CLIENT}/d
		\$a
		${CLIENT}	root=${SERVER}:${EXPORT_ROOT}/${CLIENT} \\
		        swap=${SERVER}:${EXPORT_SWAP}/${CLIENT}/`basename ${SWAPFILE}`	# ${CLIENT}
		.
		w
		q
	_EOF_
}

#
# Convert class A, B, or C internet addressed to hex
#
# Argument address is filtered by "sed(1)" and modified to
# give appropriate input to the "dc(1)" command.
# This result is forced to be 9 digits long,
# and "expr(1)" is used to remove the first character
# so that the final answer is a zero padded 8 characters long
#

hex_inet()
{
	expr `echo ${1-0} + + p | sed -e 's/\([0-9]*\)\.*/16o 0 256 \1 + 256 * 256 * 256 * 0 /' \
		-e 's/\./+ 256 */g' | dc` : '.\(.*\)'
}

#
# Create cleanup script
#

create_cleanup()
{
	cat <<-_EOF_ >${TMP_CLN}
		trap "" 1 2 3 15
		if [ -f ${TMP_ERR} ]; then rm -f ${TMP_ERR}; fi;
		if [ -f ${TMP_EXERR} ]; then rm -f ${TMP_EXERR}; fi;
		if [ -f ${TMP_BOOT} ]; then rm -f ${TMP_BOOT}; fi;
		if [ -f ${TMP_EXP} ]; then rm -f ${TMP_EXP}; fi;
		if [ -f ${TMP_KVM} ]; then rm -f ${TMP_KVM}; fi;
		rm -rf ${TMP_CLN} ${SWAPFILE} ${EXPORT_SWAP}/${CLIENT}
		rm -rf ${EXPORT_CRASH}/${CLIENT}
		if [ -f ${EXPORT_FILE}-old ]
		then
			mv ${EXPORT_FILE}-old ${EXPORT_FILE}
		fi
		if [ -f ${SERVER_BOOT}-old ]
		then
			mv ${SERVER_BOOT}-old ${SERVER_BOOT}
		fi
	_EOF_
}

#
# Add new cleanup command to script
#

add_cleanup()
{
	echo $1 >>${TMP_CLN}
}

#
# verify specified swapfile size is within reasonable limit
#

verify_swapsize()
{
	Size=`echo $SWAPSIZE | sed -e 's/[kK]/ 1024*/' -e 's/[mM]/ 1048576*/' -e 's:$: 1024/1024/p:' | dc`

	if [ "$Size" -lt 8 ]
	then
		fatal "Swapsize \`$SWAPSIZE\` should be at least 8 Megabytes"
	fi
}

#
# fatal error - print message and exit
#

fatal()
{
	error "$*"
	wrapup 1
	exit 1
}

#
# error() prints an error message to stderr
#

error()
{
	if [ "${ADMPID}" != "" ]
	then
		if [ -f ${TMP_ERR} ]
		then
			Errout="`cat ${TMP_ERR}`
$Myname: $*"
			rm -f ${TMP_ERR}
		else
			Errout="$Myname: $*"
		fi
		sysadm_display NOWAIT "$Errout"
	else
		echo "$Myname: $*" 1>&2
	fi
}

#
# Display message directly to user
#

display()
{
	if [ "${ADMPID}" != "" ]
	then
		sysadm_display NOWAIT "$*"
	else
		echo "$*" >/dev/tty
	fi
}

#
# usage() prints a usage message (usage is in the variable Usage)
#

usage()
{
	if [ "${ADMPID}" != "" ]
	then
		sysadm_display NOWAIT "$usage: $Myname $Usage"
	else
		echo "usage: $Myname $Usage" 1>&2
	fi
	exit 2
}

#
# Let sysadmin installation tool handle display to user
#

sysadm_display()
{
	# First argument signals WAIT/NOWAIT/EXIT; print on separate line
	echo "$1" >${TMP_ADMOUT}
	shift
	echo "$*" >>${TMP_ADMOUT}

	while
		kill -0 ${ADMPID:-x} 2>/dev/null || break
		test -f ${TMP_ADMOUT}
	do
		sleep 2
	done

	if [ -f ${TMP_ADMOUT} ]
	then
		echo "$*" >/dev/tty
		rm -f ${TMP_ADMOUT}
	fi
}


#
# Signal cleanup.  Print message to user and to log
#

sig_abort()
{
	log "Aborted by signal"
	display ""
}

#
# Record message in installation log
#
log()
{
	echo "$Myname: $*" >>${LOG}
}

#
# Final command wrap up.  Record errors and completion in log.
# Remove temporary files
#

wrapup()
{
	trap '' 1 2 3 15

	Errout="Failed due to error.  Cleaning up."
	if [ -f ${TMP_ERR} ]
	then
		cat ${TMP_ERR} >>${LOG}
		if [ "$ADMPID" != "" ]
		then
			Errout="`cat ${TMP_ERR}`
$Errout"
		fi
	fi

	log "Completed with status $1 `date`"
	if [ "$1" != "0" ]
	then
		log "***** Failed due to error.  Cleaning up *****"
		error "$Errout"
		if [ -f ${TMP_CLN} ]
		then
			/bin/sh ${TMP_CLN}
		fi
		if [ "$ADMPID" != "" ]
		then
			sysadm_display EXIT "Command Failed"
		fi
	else
		rm -f ${TMP_ERR} ${TMP_EXERR} ${TMP_CLN} ${TMP_BOOT} ${TMP_KVM}
		rm -f ${TMP_EXP} ${EXPORT_FILE}-old ${SERVER_BOOT}-old 
		if [ "$ADMPID" != "" ]
		then
			sysadm_display EXIT "Client Installed"
		else
			$Vflag display "Installation Complete"
		fi
	fi
	exit $1
}

#
# /usr/bin/dirname is part of the SysV package, and so it's existence can
# not be counted on
#
dirname()
{
	expr ${1-.}'/' : '\(/\)[^/]*/$' \| ${1-.}'/' : '\(.*[^/]\)//*[^/][^/]*//*$' \| .
}

#
# am_i_root is the equivalent of
#   (id | grep 'uid=0') > /dev/null
# which cannot be relied on because id is SysV only
#
am_i_root()
{
	if [ `whoami` = "root" ]
	then
		return 0
	else
		return 1
	fi
}

#
# adjust_server makes sure we have the right SERVER set in the case
# where the client is to be on a gateway of the server.  If so we
# want ${SERVER} to differ from `hostname`.  (If not we will end up
# with the same ${SERVER}, having gone around the barn to get it.)
#
adjust_server()
{
	oserver=$SERVER
	for eth in ei ex eg
	do
		for num in 0 1 2 3
		do
			# The bit with wc is to handle the case of
			# an existing interface that has not been
			# configured.  You get back a string along
			# the lines of ``eg0: flags=0<>'' and a
			# successful exit status

			result=`ifconfig $eth$num 2>/dev/null`
			if [ $? -eq 0 -a \
			     `echo "$result" | wc -w` -gt 4 ]
			then
				ipadr=`echo $result | awk '{ print $4 }'`
				bcast=`echo $result | awk '{ print $8 }'`
				while [ ! -z "`echo $bcast | grep '\.0$'`" ]
				do
					bcast=`echo $bcast | sed 's/\.0$//'`
				done

				bcast=`echo $bcast.`
				mbcast=`echo $bcast | sed "s/\./;/g"`
				mipadr=`echo $ipadr | sed "s/\./;/g"`
				mcladr=`echo $INETADDR | sed "s/\./;/g"`

				if [ `expr match $mipadr $mbcast` -eq \
				     `expr match $mcladr $mbcast` ]
				then
					SERVER=`grep -w "$ipadr" ${SERVER_HOSTS} | awk '{ print $2 }'`
					if [ -z "$SERVER" ]
					then
						# not in its own /etc/hosts?
						SERVER=$oserver
					fi
					return
				fi
			fi
		done
	done
}

#
# Verify that the swapfile directory is not below root
#

verify_swapdir()
{
	SWAPDIR=`get_realname "$1"` || fatal "can not execute 'get_realname'"

	if [ "${SWAPDIR}" = "/" ]
	then 
		fatal "swapfile \"$SWAPFILE\" cannot be on same partition as root"
	fi

	dirs=`mount | awk '{print $3}'`

	for i in $dirs
	do
		if [ $i != "/" ]
		then
			if isbelow "$SWAPDIR" "$i"
			then 
				return
			fi
		fi
	done	
		fatal "swapfile \"$SWAPFILE\" cannot be on same partition as root"
}

#
# Get real directory name instead of symbolic link name
# by changing to the directory and using "/bin/pwd"
#

get_realname()
{
	Dir="$1"

	if [ "$Dir" = "" ]
	then
		return
	fi

	if [ ! -d "$Dir" ]
	then
		# If $Dir isn't there, we have to believe the name as is.
		echo $Dir
	else
		cd $Dir
		/bin/pwd
	fi
}

#
# Decide whether given directory is below target directory
# (e.g. /usr/export/exec is below /usr, but not below /usr1)
#

isbelow()
{
	given="$1"
	target="$2"
	while true
	do
		if [ "${given}" = "/" -o "${given}" = "." ]
		then
			return 1
		fi
		if [ "${given}" = "${target}" ]
		then
			return 0
		fi
		given=`dirname "${given}"`
	done
}

#
# Perform main function
#
main ${1+"$@"}
exit 0
