#!/sbin/sh
# @(#) $Revision: 78.2 $
#
# NOTE:    This script is not configurable!  Any changes made to this
#          scipt will be overwritten when you upgrade to the next
#          release of HP-UX.
#
# WARNING: Changing this script in any way may lead to a system that
#          is unbootable.  Do not modify this script.

PATH=/sbin:/usr/sbin


Log()
{
	# Echo the message to stdout.  If s800 and /${NEW_ROOT} is mounted,
	# append it to the console log kept in the private root.

	echo "$*"
	if [[ $ARCHTYPE = 800 && $NEW_ROOT_MOUNTED = yes ]] ; then
		echo "$*" >>/${NEW_ROOT}/conslog.nfsd
	fi
}

init_exit()
{
	Log "Initial NFS diskless initialization completed"
	Log ""

	if [[ $ARCHTYPE = 800 ]] ; then
		# Copy the output from this script into our private root,
		# overwriting the earlier log info (which was logged a
		# line-at-a-time using Log() so that if we didn't get this
		# far, there would be some record of the progress made.)

		/${NEW_ROOT}/sbin/cat /conslog >/${NEW_ROOT}/conslog.nfsd 2>&1

		# Create an empty file for use by the *real* pre_init_rc
		# that is run later on.  For NFSD, that script won't produce
		# any output, but being a shell script, it needs a target
		# for stdout/stderr.

		>/${NEW_ROOT}/conslog
	fi

	exit 0
}

#
# Convert a string of the format: "[0|0x|0X]<digits>[k,K,m,M]" 
# into a nubmer
#
function s_to_num
{
        case $1 in
        0[x,X]*)
                value=${1##0[x,X]}
                value=${value%[k,K,m,M]}
                value=$((16#$value))
                ;;
        0*)
                value=${1##0}
                value=${value%[k,K,m,M]}
                value=$((8#$value))
                ;;
        +([0-9])*)
                value=${1%[k,K,m,M]}
                ;;
        *)
                value=0
                ;;
        esac

        case $1 in
        *[k,K])
                value=$value*1024/${BSIZE}
                ;;
        *[m,M])
                value=$value*1024*1024/${BSIZE}
                ;;
        *[0-9])
                ;;
        *)
                value=0
        esac

        echo $value
}



# determine architecture type the RAM FS was built for:
if [ -e /etc/700 ] ; then
	ARCHTYPE=700
else
	ARCHTYPE=800
fi

# get configuration info from the kernel's copy of the bootp packet

MY_NAME=`get_bootp_info -h`
MY_IP=`get_bootp_info -y`
MY_SVR_IP=`get_bootp_info -s`
MY_FILE=`get_bootp_info -f`

MY_MASK=`get_bootp_info -m 2> /dev/null`
MY_GATEWAY=`get_bootp_info -g 2> /dev/null`

NEW_ROOT=newroot
NEW_ROOT_MOUNTED=no

Log "\nKRC Revision$Revision: 78.2 $"
Log "\nStarting NFS diskless client $MY_NAME ($MY_IP) served by $MY_SVR_IP"

hostname $MY_NAME
uname -S $MY_NAME

Log "Configuring networking..."

Log "ifconfig lo0 inet 127.0.0.1 up"
ifconfig lo0 inet 127.0.0.1 up

# sm field may be empty
if [ -n "$MY_MASK" ]; then
	NETMASK="netmask $MY_MASK"
else
	NETMASK=""
fi
Log "ifconfig lan0 inet $MY_IP $NETMASK up"
ifconfig lan0 inet $MY_IP $NETMASK up 

# gw field may be empty
if [ -n "$MY_GATEWAY" ]; then
	if [ "$MY_GATEWAY" = "$MY_IP" ]; then
		# use proxy ARP to get routing info
		HOP="0"
	else
		HOP="1"
	fi
	Log "route add default $MY_GATEWAY $HOP"
	route add default $MY_GATEWAY $HOP
else
	Log "no default route setup"
fi

# Remove files which are no longer needed (to gain additional ramdisk space)
unlink /sbin/hostname
unlink /sbin/uname
unlink /sbin/ifconfig

STAND_DIR="${MY_FILE%/*}"		# get "dirname" of the path

# get info file (this is copied to the ramdisk)
INFO_FILE="${STAND_DIR}/info"
echo "mode binary\nget $INFO_FILE /etc/info" | \
	tftp $MY_SVR_IP 69 >/dev/null 2>&1
. /etc/info >/dev/null 2>&1

if [ "$DEBUG_KRC" = "1" ]; then
	Log "Content of boot reply:"
	get_bootp_info -A
fi

unlink /sbin/get_bootp_info
unlink /sbin/route

# NFS mount private root for this machine
if [ -z "$ROOT_SERVER_IP" ]; then
	ROOT_SERVER_IP=$MY_SVR_IP
fi
if [ -z "$PRIVATE_ROOT" ]; then
	PRIVATE_ROOT=/export/private_roots/$MY_NAME
fi

# NFS mount /stand for this machine
if [ -z "$STAND_SERVER_IP" ]; then
	STAND_SERVER_IP=$MY_SVR_IP
fi

# If STAND_DIR doesn't begin with "/export/", (e.g. tftp was setup with
# a home directory), then prepend "/export/tftpboot".
if [ -n "${STAND_DIR##/export/*}" ] ; then
	STAND_DIR=/export/tftpboot${STAND_DIR}
fi

Log "Mounting filesystems..."

# mount /
if [ -n "$MOUNT_ROOT_OPTS" ] ; then
	MOUNT_OPTS="-o $MOUNT_ROOT_OPTS"
else
	MOUNT_OPTS="-o hard,retry=3,nointr"
fi
Log "mount $MOUNT_OPTS $ROOT_SERVER_IP:$PRIVATE_ROOT /"
mount $MOUNT_OPTS $ROOT_SERVER_IP:$PRIVATE_ROOT /$NEW_ROOT

#
# At this point we have what will become our root filesystem mounted,
# So we can log to it.
#
NEW_ROOT_MOUNTED=yes

# mount /stand
if [ -n "$MOUNT_STAND_OPTS" ] ; then
	MOUNT_OPTS="-o $MOUNT_STAND_OPTS"
else
	MOUNT_OPTS="-o hard,nodevs,retry=3,nointr"
fi
Log "mount $MOUNT_OPTS $STAND_SERVER_IP:$STAND_DIR /stand"
mount $MOUNT_OPTS $STAND_SERVER_IP:$STAND_DIR /$NEW_ROOT/stand

BADMSG="Boot time mounting of local filesystems are not allowed"

# There is a symbolic from  /etc/hosts to /$NEW_ROOT/etc/hosts
#	so that we can do the mounting using hostname

# Scan through fstab and compose commands to mount
# client file systems.

while read LINE
do
	# Skip comments
	set $LINE >/dev/null
	case $1 in
	\#*)
		continue
		;;
	esac

	# Check for default swap info while we're here
	case $3 in
	swapfs)
		if [ "$2" = / ]; then
			SWAP_DIR=$2
			IFS=,
			set $4 >/dev/null
			unset IFS
			while [ $# -gt 0 ]; do
				SNUM=${1##*=}
				case $1 in
				min=*)
					SWAP_MIN=$SNUM
					;;
				lim=*)
					SWAP_LIMIT=$SNUM
					;;
				res=*)
					SWAP_RESERVE=$SNUM
					;;
				pri=*)
					typeset -i SWAP_PRIORITY=$1
					;;
				esac
				shift
			done
			continue
		fi
		;;
	esac

	# Only "boot" flagged entries are allowed. Skip others.
	case $4 in
	*boot*)
		;;
	*)
		continue
		;;
	esac

	# Not a comment and is flagged as boot. However, make
	# sure it's not local as specified by a leading '/'
	case $1 in
	/*)
		Log "${1}: $BADMSG"
		continue
		;;
	esac

	# "/" and "/stand" don't need mounting. Others do.
	if [ "$2" = "/" ] ; then
		continue
	fi
	if [ "$2" = "/stand" ] ; then
		continue
	fi

	# Abbreviate the special name echoed to the console to make the
	# mount command easier to read.
	t1=$1
	if [[ $t1 = *:/export/shared_roots/OS_700* ]] ; then
	    ta1=${t1%%:*}
	    ta1s=${ta1%%.*}
	    tz1=${t1##*:}
	    tz1s=${tz1##/export/shared_roots/OS_700}
	    t1="$ta1s: ...$tz1s"
	    fi
	s1="mount $t1"
	while [ "${#s1}" -lt "44" ]; do 
	    s1="$s1 " ; 
	    done
	Log "$s1 $2"
	mount -o $4,nodevs $1 /${NEW_ROOT}$2

done < /$NEW_ROOT/etc/fstab


if [ "$NO_SWAP_TO_NFS" = "1" ]; then
	Log "Skip configuring default swap to NFS"
	init_exit
fi

if [ -z "$SWAP_DIR" ]; then
	Log "Default NFS swap not configured (swapfs to / not found in fstab)"
	init_exit
fi

Log "Configuring default NFS swap in $SWAP_DIR (${SWAP_DIR}paging) directory"

#
# Although we currently only support SWAP_DIR=/, we'll leave this code
# in place for future support of a separately mounted SWAP_DIR.
#
if [ -d /$NEW_ROOT$SWAP_DIR ]; then
	# if paging directory exist, then it could be a mount point
	BSIZE=`vminfo -b /$NEW_ROOT$SWAP_DIR`
else
	BSIZE=`vminfo -b /$NEW_ROOT`
fi

MSIZE=`vminfo -m`
SWCHUNK=`vminfo -s`

if [ "$DEBUG_KRC" = "1" ]; then
	Log "MSIZE: $MSIZE "
	Log "BSIZE: $BSIZE "
	Log "SWCHUNK: $SWCHUNK "
fi

# calculate the minimum swap required
if [ -n "$SWAP_MIN" ]; then
        typeset -i min=$(s_to_num $SWAP_MIN)
else
	min=0
fi

# calculate the swap limit
if [ -n "$SWAP_LIMIT" ]; then
	typeset -i limit=$(s_to_num $SWAP_LIMIT)
else
#	default is unlimited
	limit=0
fi

# determine the swap priority
if [ -n "$SWAP_PRIORITY" ]; then
	typeset -i priority=$SWAP_PRIORITY
else
#	default is 5
	priority=5
fi

# determine the swap reserve
if [ -n "$SWAP_RESERVE" ]; then
	typeset -i reserve=$(s_to_num $SWAP_RESERVE)
else
#	default is 0
	reserve=0
fi

# number of swchunks
((swap_count=min*${BSIZE}/${SWCHUNK}))

# rename existing swap files to the lowest numbers so that
# we don't have to re-create them.  Remove unneeded swap files
# *always*, unless REMOVE_EXTRA_SWAPFILES is set to zero.

if [ -d /$NEW_ROOT$SWAP_DIR/paging ]; then
	cd /$NEW_ROOT$SWAP_DIR/paging
	typeset -i count=0

	# check if there is any NFS files to be deleted
	YY=\.nfs
	i=`echo ${YY}*`
	if [ "$i" != "${YY}*" ]; then
		for i in ${YY}*
		do
			if [ "$DEBUG_KRC" = "1" ]; then
				Log "unlink $i "
			fi
			unlink $i
		done
	fi

	# check if there is any file. If yes, we sort them first
	i=`echo ${MY_NAME}.?`
	if [ "$i" != "${MY_NAME}.?" ]; then
		for i in ${MY_NAME}.?
		do
			FN[$count]=$i
			((count=count+1))
		done
	fi
	i=`echo ${MY_NAME}.??`
	if [ "$i" != "${MY_NAME}.??" ]; then
	for i in ${MY_NAME}.??
		do
			FN[$count]=$i
			((count=count+1))
		done
	fi
	i=`echo ${MY_NAME}.???`
	if [ "$i" != "${MY_NAME}.???" ]; then
		for i in ${MY_NAME}.???
		do
			FN[$count]=$i
			((count=count+1))
		done
	fi
	typeset -i idx=0
	typeset -i idx2=$count
	while ((idx < count))
	do
		if [ ! -f $MY_NAME.$idx ] ; then
			((idx2=idx2-1))
			if [ "$DEBUG_KRC" = "1" ]; then
				Log "rename ${FN[$idx2]} $MY_NAME.$idx "
			fi
			rename ${FN[$idx2]} $MY_NAME.$idx
		fi
		if [ "$REMOVE_EXTRA_SWAPFILES" != "0" ] ; then
			if ((idx >= swap_count)) ; then
				if [ "$DEBUG_KRC" = "1" ]; then
					Log "unlink $MY_NAME.$idx "
				fi
				unlink $MY_NAME.$idx
			fi
		fi
		((idx=idx+1))
	done

	cd /
fi

# finally, enable the primary swap
Log "swapon -p $priority -m $min -l $limit -r $reserve $SWAP_DIR"
swapon -p $priority -m $min -l $limit -r $reserve /$NEW_ROOT$SWAP_DIR

if [ "$DEBUG_KRC" = "1" ]; then
	/${NEW_ROOT}/sbin/ls -lia /
	# (Don't recursively list /newroot!):
	/${NEW_ROOT}/sbin/ls -liaR /lost+found /dev /etc /sbin /tmp
fi

init_exit
