#!/sbin/sh
#
# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
# All rights reserved.
#
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
# The copyright notice above does not evidence any
# actual or intended publication of such source code.
#
# Copyright (c) 1996-1999 by Sun Microsystems, Inc.
# All rights reserved.
#
#ident	"@(#)rootusr	1.20	99/02/03 SMI"

# Make sure that the libraries essential to this stage of booting can be found.

LD_LIBRARY_PATH=/etc/lib; export LD_LIBRARY_PATH

# Configure the software loopback driver. The network initialization is
# done early to support diskless and dataless configurations.

/sbin/ifconfig lo0 127.0.0.1 up 2>&1 >/dev/null

# For interfaces that were configured by the kernel (e.g. those on diskless
# machines), reset the netmask using the local "/etc/netmasks" file, if 
# one exists.

/sbin/ifconfig -au netmask + broadcast + 2>&1 >/dev/null

# Get the list of network interfaces to configure by breaking 
# /etc/hostname.* into separate args by using "." as a shell separator 
# character, then step through args and ifconfig every other arg.
# Set the netmask along the way using local "/etc/netmasks" file.
# This also sets up the streams plumbing for the interface.
# With an empty /etc/hostname.* file this only sets up the streams plumbing
# allowing the ifconfig auto-dhcp / auto-revarp command will attempt to
# set the address.

interface_names="`echo /etc/hostname.*[0-9] 2>/dev/null`"
if [ "$interface_names" != '/etc/hostname.*[0-9]' ]; then
	(
		echo 'configuring network interfaces:\c'
                IFS="${IFS}."
                set -- $interface_names
                while test $# -ge 2; do
			shift
			if [ "$1" != "xx0" ]; then
				addr=`shcat /etc/hostname\.$1`
				/sbin/ifconfig $1 plumb
				if [ -n "$addr" ]; then
					/sbin/ifconfig $1 inet "$addr" \
					   netmask + broadcast + -trailers up \
					   2>&1 >/dev/null
				fi
				echo " $1\c"
			fi
			shift
		done
		echo '.'
	)
fi

# Run DHCP if host has been configured

if [ ! -f /etc/.UNCONFIGURED ]; then
	interface_names="`echo /etc/dhcp.*[0-9] 2>/dev/null`"
	if [ "$interface_names" != '/etc/dhcp.*[0-9]' ]; then

	# Allow configuration to be interrupted.  First find the
	# primary interface. Default to the first interface
	# if not specified. First primary interface found "wins"
	# Run thru the list of interfaces again, this time trying DHCP.

        (
		firstif=
		primary=
		IFS="${IFS}."
		set -- $interface_names

		while [ $# -ge 2 ]; do
			shift
			[ -z "$firstif" ] && firstif=$1

			for i in `shcat /etc/dhcp\.$1`; do
				if [ "$i" = primary ]; then
					primary=$1
					break
				fi
			done

			[ -n "$primary" ] && break
			shift
		done

		[ -z "$primary" ] && primary="$firstif"
		cmdline=`shcat /etc/dhcp\.${primary}`

		echo "starting DHCP on primary interface $primary"
		trap "" 2 3
		/sbin/ifconfig $primary auto-dhcp primary $cmdline

		trap 2 3
		set -- $interface_names

		while [ $# -ge 2 ]; do
			shift
			cmdline=`shcat /etc/dhcp\.$1`
			if [ "$1" != "$primary" ]; then
				echo "starting DHCP on interface $1"
				/sbin/ifconfig $1 dhcp start wait 0 $cmdline
			fi
			shift
		done
	)
	fi
fi

# Configure the rest of the interfaces automatically, quietly.

/sbin/ifconfig -adD auto-revarp netmask + broadcast + -trailers up \
    2>&1 >/dev/null

# If DHCP was used on a primary interface then set the hostname
# that was returned. If no hostname was returned, set the name
# to be "unknown". The hostname must be set to something, because
# tooltalk will hang unless the name can be locally resolved.
# Sendmail also requires the name to be resolvable locally.
# Later, in inetsvc, we create a name "unknown" and create a entry
# in the local /etc/inet/hosts file pairing "unknown" with the IP
# address assigned by DHCP.

if [ "x`echo /etc/dhcp.*[0-9]`" = 'x/etc/dhcp.*[0-9]' ]; then
	try_dhcp=no
	hostname=
else
	try_dhcp=yes
	hostname=`/sbin/dhcpinfo Hostname`

	case $? in
	0) [ -z "$hostname" ] && hostname='unknown' ;;
	2) try_dhcp=no ;;
	esac
fi


# Set the hostname from a local config file, if one exists and if
# DHCP was not used to configure any primary interface.

if [ -z "$hostname" ]; then
	hostname="`shcat /etc/nodename 2>/dev/null`"
	[ -n "$hostname" ] && /sbin/uname -S $hostname
fi

# Otherwise, set host information from bootparams RPC protocol.

[ -z "$hostname" ] && /sbin/hostconfig -p bootparams

# If local and network configuration failed, re-try network
# configuration until we get an answer.  We want this loop to be
# interruptible so that the machine can still be brought up manually
# when the servers are not cooperating.

trap 'intr=1' 2 3
while [ -z "`/sbin/uname -n`" -a ! -f /etc/.UNCONFIGURED -a -z "$intr" ]; do
	echo "re-trying host configuration..."
	/sbin/ifconfig -adD auto-revarp up 2>&1 >/dev/null
	/sbin/hostconfig -p bootparams 2>&1 >/dev/null
done
trap 2 3

echo "Hostname: `/sbin/uname -n`" >&2

# If "/usr" is going to be NFS mounted from a host on a different
# network, we must have a routing table entry before the mount is
# attempted.  One may be added by the diskless kernel or by the
# "hostconfig" program above.  Setting a default router here is a problem
# because the default system configuration does not include the
# "route" program in "/sbin".  Thus we only try to add a default route
# at this point if someone managed to place a static version of "route" into
# "/sbin".  Otherwise, we may add the route at run level 2 after "/usr"
# has been mounted and NIS is running.

# Note that since NIS is not running at this point, the router's name
# must be in "/etc/hosts" or its numeric IP address must be used in the file.

[ $try_dhcp = yes ] && gateways=`/sbin/dhcpinfo Router` || gateways=

if [ -z "$gateways" -a -f /etc/defaultrouter ]; then
	gateways=`shcat /etc/defaultrouter`
	if [ -x /sbin/route -a ! -z "$gateways" ]; then
		/sbin/route -f add default $gateways 1
	fi
else
	if [ -x /sbin/route ]; then
		/sbin/route -f
		for gateway in $gateways; do
			/sbin/route add default $gateway 1
		done
	fi
fi

# Root is already mounted (by the kernel), but still needs to be checked,
# possibly remounted and entered into mnttab. First mount /usr read only
# if it is a separate file system. This must be done first to allow
# utilities such as fsck and setmnt to reside on /usr minimizing the space
# required by the root file system.

exec < $vfstab; readvfstab "/usr"

if [ "$mountp" ]; then
	if [ "$fstype" = cachefs ]; then

		# Mount without the cache initially.  We'll enable it
		# later at remount time.  This lets us avoid
		# teaching the statically linked mount program about
		# cachefs.  Here we determine the backfstype.
		# This is not pretty, but we have no tools for parsing
		# the option string until we get /usr mounted...

		case "$mntopts" in
		*backfstype=nfs*)
			cfsbacktype=nfs
			;;
		*backfstype=hsfs*)
			cfsbacktype=hsfs
			;;
		*)
			echo 'invalid vfstab entry for /usr'
			cfsbacktype=nfs
			;;
		esac
		/sbin/mount -m -F $cfsbacktype -o ro $special $mountp
	else
		# Must use -o largefiles here to ensure the read-only mount
		# does not fail as a result of having a large file present
		# on /usr. This gives fsck a chance to fix up the largefiles
		# flag before we remount /usr read-write.

		if [ "x$mntopts" = x- ]; then
			mntopts='ro,largefiles'
		else
			checkopt largefiles $mntopts
			if [ "x$option" != xlargefiles ]; then
				mntopts="largefiles,$mntopts"
			fi

			checkopt ro $mntopts
			if [ "x$option" != xro ]; then
				mntopts="ro,$mntopts"
			fi
		fi

		/sbin/mount -m -o $mntopts /usr
	fi
fi

[ -f /etc/.dynamic_routing ] && /usr/bin/rm -f /etc/.dynamic_routing

# Reset the library path now that we are past the critical stage

LD_LIBRARY_PATH=; export LD_LIBRARY_PATH

# If we need the consadm daemon, start it as soon as /usr/lib becomes available.
[ -x /usr/sbin/consadmd -a -r /etc/consadm.conf ] && /usr/sbin/consadmd &
