#!/sbin/sh
#
#       @(#)startup.sh 1.77 00/10/29 SMI
#
# Copyright (c) 1992-1995 Sun Microsystems, Inc.  All Rights Reserved. Sun
# considers its source code as an unpublished, proprietary trade secret, and
# it is available only under strict license provisions.  This copyright
# notice is placed here only to protect Sun in the event the source is
# deemed a published work.  Dissassembly, decompilation, or other means of
# reducing the object code to human readable form is prohibited by the
# license agreement under which this code is provided to the user or company
# in possession of this copy.
#
# RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the Government
# is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the
# Rights in Technical Data and Computer Software clause at DFARS 52.227-7013
# and in similar clauses in the FAR and NASA FAR Supplement.
#
# NOTE:	run as the runlevel 234 process; invoked from the inittab; invokes
#	sysconfig with all necessary environment setup
#

SHELL=/sbin/sh
TEXTDOMAIN=SUNW_INSTALL_SCRIPTS
PATH=/sbin:/usr/sbin/install.d:${PATH}

PLATFORM=`/sbin/uname -p`

# make home dir to a writeable place
HOME=/tmp/root
export SHELL TEXTDOMAIN PATH PLATFORM HOME

# Local Variables
KDMCONFIG_NOGUI=/tmp/root/var/tmp/kdmconfig.nogui
OWCONFIG_FILE=/tmp/root/etc/openwin/server/etc/OWconfig
RUN_WIN=1
RUN_KDM=0

#
# Search for the sysid configuration file on the tape drive.  Save everything
# we find for use by the Custom Jumpstart code later. 
#
# Arguments:	${1}	- String specifying tape device and position of files
#			  on said device.  The format of the string is:
#
#			  tape[=<device>[:position]]
#
tape ()
{
	METHOD="${1}"
	MOUNT_CONFIG_DIR=/tmp/cjtapeconfig.$$

	# Find the tape device
	case "$METHOD" in
	    tape)
		TAPEDEVICE=/dev/rmt/0n
		TAPEPOSN=0
		;;

	    tape=*)
		TAPEDEVICE=`expr "$METHOD" : \
			    '^tape=\([^:][^:]*\)\(:[0-9][0-9]*\)\{0,1\}'`
		if [ $? != 0 ] ; then
			MESSAGE=`gettext "Invalid tape device specification"`
			ESTATUS=1
			return
		fi

		TAPEPOSN=`expr "$METHOD" : \
			    '^tape=[^:][^:]*:\([0-9][0-9]*\)'`
		if [ $? != 0 ] ; then
			TAPEPOSN=0
		fi
		;;
	esac

	# Position the tape device
	mt -f $TAPEDEVICE asf $TAPEPOSN
	if [ $? != 0 ] ; then
		MESSAGE=`gettext "Unable to position tape device"`
		ESTATUS=1
		return
	fi

	# Extract the files from the tape
	old_dir=`pwd`
	mkdir ${MOUNT_CONFIG_DIR}
	cd ${MOUNT_CONFIG_DIR}
	tar xf $TAPEDEVICE >/dev/null 2>&1
	status=$?
	cd $old_dir
	if [ $status != 0 ] ; then
		MESSAGE=`gettext "Unable to extract files from tape using tar"`
		ESTATUS=1
		return
	fi

	echo ${MOUNT_CONFIG_DIR} >/tmp/.cjfiles_dir

	# If we just extracted a sysidcfg file, use it.
	if [ -f ${MOUNT_CONFIG_DIR}/sysidcfg ] ; then
		cp ${MOUNT_CONFIG_DIR}/sysidcfg /etc
		chmod 0600 /etc/sysidcfg
		echo "Using sysid configuration file from ${TAPEDEVICE}" \
		    "position ${TAPEPOSN}"
		return 0
	fi

	return 1
}


#
# Search for the sysid configuration file
# on the bootparams.
#
bootparams_sysid_config()
{
	MOUNT_CONFIG_DIR=/tmp/sysid_config.$$
	mkdir ${MOUNT_CONFIG_DIR}

	#
	# Check for a 'sysid_config' bootparams entry
	#
	set -- `/sbin/bpgetfile -retries 1 sysid_config`
	if [ $1"X" != "X" ]; then
		mount -o ro -F nfs $2:$3  \
			${MOUNT_CONFIG_DIR} >/dev/null 2>&1
					 
		if [ $? -eq 0 ]; then
			if [ -f ${MOUNT_CONFIG_DIR}/sysidcfg ]; then
				cp ${MOUNT_CONFIG_DIR}/sysidcfg /etc
				chmod 0600 /etc/sysidcfg
				echo "Using sysid configuration file ${2}:${3}/sysidcfg"
				return 0
			fi
			umount ${MOUNT_CONFIG_DIR}
		fi
	fi
	rmdir ${MOUNT_CONFIG_DIR}

	return 1
}

#
# Search for the sysid configuration file
# in DHCP.
#
dhcp_sysid_config()
{
	MOUNT_CONFIG_DIR=/tmp/sysid_config.$$
	mkdir ${MOUNT_CONFIG_DIR}

	#
	# Check for a 'sysid_config' bootparams entry
	#
	set -- `/sbin/dhcpinfo SsysidCF`
	if [ $1"X" != "X" ]; then
		mount -o ro -F nfs $1  \
			${MOUNT_CONFIG_DIR} >/dev/null 2>&1
					 
		if [ $? -eq 0 ]; then
			if [ -f ${MOUNT_CONFIG_DIR}/sysidcfg ]; then
				cp ${MOUNT_CONFIG_DIR}/sysidcfg /etc
				chmod 0600 /etc/sysidcfg
				echo "Using sysid configuration file ${1}/sysidcfg"
				return 0
			fi
			umount ${MOUNT_CONFIG_DIR}
		fi
	fi
	rmdir ${MOUNT_CONFIG_DIR}

	return 1
}

#
# Search for the sysid configuration file
# on the local floppy drive.  Try to mount
# PCFS first and then UFS
#
floppy_sysid_config()
{
	MOUNT_CONFIG_DIR=/tmp/sysid_config.$$

    # Check to see if there is a floppy in the drive (silently)
    #
    /usr/bin/eject -q floppy >/dev/null 2>&1

    if [ $? -eq 0 ]; then
        # Make the mount point directory used in searching
        # for the profile
        #
        if [ ! -d ${MOUNT_CONFIG_DIR} ]; then
            mkdir ${MOUNT_CONFIG_DIR} 2>/dev/null
        fi

        # Try to mount the floppy first as PCFS, then as UFS
        #
        mount -o ro,foldcase -F pcfs /dev/diskette ${MOUNT_CONFIG_DIR} \
                            >/dev/null 2>&1
        status=$?
        if [ ${status} -ne 0 ]; then
            mount -o ro -F ufs  /dev/diskette ${MOUNT_CONFIG_DIR} \
                            >/dev/null 2>&1
            status=$?
        fi

	if [ ${status} -eq 0 ]; then
		if [ -f ${MOUNT_CONFIG_DIR}/sysidcfg ]; then
			cp ${MOUNT_CONFIG_DIR}/sysidcfg /etc
			chmod 0600 /etc/sysidcfg
			echo "Using sysid configuration file from local floppy"
			# since the sysidcfg file was copied to /etc/sysidcfg
			# we can unmount the floppy and remove the
			# mount point before returning
			umount ${MOUNT_CONFIG_DIR}
			rmdir ${MOUNT_CONFIG_DIR}
			return 0
		fi
		umount ${MOUNT_CONFIG_DIR}
	fi

	rmdir ${MOUNT_CONFIG_DIR}
	fi

	return 1
}

#
# Read the LANG and LC_MESSAGES from /etc/default/init and use it
#
locale_from_init()
{
	#
	# Source in all LANG, LC_*, and TZ settings and export them
	# Make sure LANG doesn't already have a value (it is initially C).
	#
	LANG=""
	. /etc/default/init
	export TZ
	export LANG LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME

	#
	# If LANG was set, make sure to explicitly set all LC_* values
	#
	if [ "${LANG}" ]; then
		LC_COLLATE=${LANG}
		LC_CTYPE=${LANG}
		LC_MESSAGES=${LANG}
		LC_MONETARY=${LANG}
		LC_NUMERIC=${LANG}
		LC_TIME=${LANG}
	fi
}

# Export net boot configuration strategy. _INIT_NET_IF is set to the
# interface name of the netbooted interface if this is a net boot.
# _INIT_NET_STRATEGY is set to the network configuration strategy.
set -- `/sbin/netstrategy`
if [ $? -eq 0 ]; then
	if [ "$1" = "nfs" -o "$1" = "cachefs" ]; then
		_INIT_NET_IF="$2"
	fi
	_INIT_NET_STRATEGY="$3"
	export _INIT_NET_IF _INIT_NET_STRATEGY 
fi

cd ${HOME}

#
# If the run level is changed after invocation, shell should
# be run
#
if [ -f /tmp/.sh ]; then
	exec ${SHELL}
else
	touch /tmp/.sh
fi

##########
# Make sure all configuration necessary is completed in order
# to run the window system

#
# If the `tape' boot option was specified, search for the sysidcfg file on
# an attached tape drive.  Otherwise, search for it in the following order:
#	floppy (PCFS)
#	floppy (UFS)
#	network (bootparams or DHCP)
#
if [ -f /tmp/.cjfiles_method ] ; then
	echo "Searching for sysid configuration file..."
	METHOD=`head -1 /tmp/.cjfiles_method`
	case "$METHOD" in
	    tape*)
		tape "$METHOD"
		;;
	    *)
		MESSAGE=`gettext "Invalid retrieval method"`" $METHOD"
		ESTATUS=1
		;;
	esac
else
	floppy_sysid_config
	if [ $? -ne 0 ]; then
		# Look for sysidcfg via DHCP only if the network is using DHCP
		if [ "X${_INIT_NET_STRATEGY}" = "Xdhcp" ]; then
			dhcp_sysid_config
		else
			bootparams_sysid_config
		fi
	fi
fi

#
# Configure the frame buffer links
#
fbdev=`ls /devices\`/usr/sbin/prtconf -F 2>&1\`* 2>/dev/null`

if [ $? -ne 0 ]; then
	RUN_WIN=0
else
	set `echo ${fbdev}`
	rm -f /dev/fb
	ln -s $1 /dev/fb

	# XXX temporary
	# NOTE: Why is this temporary and what is its purpose?
	#
	cd /dev/fbs
	for nm in *
	do
		if [ ! -h /dev/$nm ]; then
			ln -s /dev/fbs/$nm /dev/$nm
		fi
	done

	# The code below for handling leo framebuffer configuration
	# should be generalized into a callout which can be
	# used for any framebuffer

	echo ${fbdev} | grep "SUNW\,leo" >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		if [ -x /etc/rc2.d/S91leoconfig ]; then
			/etc/rc2.d/S91leoconfig
		fi
	fi

	echo ${fbdev} | grep "PFU\,aga" >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		if [ -x /etc/rc2.d/S91agaconfig ]; then
			/etc/rc2.d/S91agaconfig start
		fi
	fi

	echo ${fbdev} | grep "SUNW\,afb" >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		if [ -x /etc/rc2.d/S91afbinit ]; then
			/etc/rc2.d/S91afbinit
		fi
	fi

	echo ${fbdev} | grep "SUNW\,Expert3D" >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		if [ -x /etc/rc2.d/S91ifbinit ]; then
			/etc/rc2.d/S91ifbinit start
		fi
	fi

	cd ${HOME}

	case "${PLATFORM}" in
	ppc|i386)
		RUN_KDM=1
		;;
	esac
fi


#
# Initialize the locale information in /tmp/root/etc/default/init,
# and set the LANG variable accordingly. From this point on all
# messages and executable should be running internationalized.
SYSIDNET="/usr/sbin/sysidnet -l -y"
if [ ! -f /tmp/.manual-sysid ] ; then
	eval "$SYSIDNET"
else
	echo "Would have run $SYSIDNET"
	/sbin/sh
fi

#
# If they just picked a multibyte locale, we don't want to start using
# it until the window system has started.
#
LOC=`grep LC_MESSAGES /etc/default/init 2>/dev/null \
			| sed -e '/^#/d' -e 's/.*=//'`
if [ -z "${LOC}" ] ; then
	LOC=`grep LANG /etc/default/init 2>/dev/null \
			| sed -e '/^#/d' -e 's/.*=//'`
fi

MBLOC=`(cd /usr/lib/locale; ls */LC_MESSAGES/openwin-defaultfont |
           sed -e 's:^\([^/]*\)/.*$:\1:') | nawk -v "LOC=$LOC" '
		{
			if (substr(LOC, 1, length($0)) == $1) { 
				if (length(foundloc) < length($0)) { 
					foundloc=$0; 
				} 
			} 
		} 

		END {print foundloc;}'`

if [ -n "${MBLOC}" ] ; then
	# They picked a multibyte locale.  Save it, but stay in C for now.
	echo "${MBLOC}" >/tmp/.mb_locale
else
	# They picked a single-byte locale.  Use it.
	locale_from_init
fi

#
# non-SPARC systems require the keyboard/mouse/display hardware be configured
# for the sake of creating the OWconfig file.
# To do this, we try to set the correct locale (the Intel and PPC console
# display's are 8-bit clean so this may work.
# Run kdmconfig to configure the OWconfig file.
#
# In 2.6, the existence of the OWconfig file is not enough to
# guarantee that we want to try and bring up a GUI environment.
# kdmconfig may write out an OWconfig file with values of "Unknown"
# for some of the attributes.  So, the OWconfig file check has been
# enhanced with a check for the KDMCONFIG_NOGUI file in the case that
# the OWconfig exists.
# sysidconfig runs kdmconfig, and kdmconfig will create this file
# in the case that the GUI environment should not be set up.
#
if [ "${RUN_KDM}" -eq 1 ]; then
	#
	# If we're doing a jumpstart, see if there is a terminal type available
	# to us from the net.  We do a similar piece of logic in the sysconfig
	# script to catch the case of sparc systems (which don't run
	# kdmconfig).
	# Note: This is a private interface and may change at any time.
	#
	# sysidcfg should be used to provide the terminal type over the network
	#
	#if [ -z "${TERM}" ]; then
	#	if [ -f ${PREINSTALL} -o -f ${INSTALLBOOT} ]; then
	#		if [ $USING_DHCP -eq 1 ] ; then
	#			set  -- `/sbin/dhcpinfo VTerm`
	#		else
	#			set -- `/sbin/bpgetfile term`
	#		fi
	#		if [ $# -eq 3 ]; then
	#			if [ ! -z "$3" ]; then
	#				TERM="$3"
	#			fi
	#		elif [ $# -eq 2 ]; then
	#			if [ ! -z "$2" ]; then
	#				TERM="$2"
	#			fi
	#		fi
	#		if [ ! -z "${TERM}" ]; then
	#			echo "TERM set to \"${TERM}\"."
	#			export TERM
	#		fi
	#	fi
	#fi

	#
	# This routine calls kdmconfig, which creates OWconfig
	# and KDMCONFIG_NOGUI.
	#
	/usr/sbin/sysidconfig

	#
	# Now decide, based on which files kdmconfig created
	# whether to bring up the GUI or CUI.
	#
	if [ ! -f ${OWCONFIG_FILE} ]; then
		RUN_WIN=0
	elif [ -f ${KDMCONFIG_NOGUI} ]; then
		RUN_WIN=0
	fi
fi

#
# Remove un-needed /dev symlinks, since each one uses a page in tmpfs.
#
rm -f /tmp/dev/pts/4? /tmp/dev/pts/3? /tmp/dev/pts/2? /tmp/dev/pts/1?
rm -f /tmp/dev/win1?? /tmp/dev/win[1-9]? /tmp/dev/win[5-9]
rm -f /tmp/dev/ptyp[5-9] /tmp/dev/ptyp[a-f]
rm -f /tmp/dev/ttyp[5-9] /tmp/dev/ttyp[a-f]
rm -f /tmp/dev/ptyq* /tmp/dev/ptyr* /tmp/dev/ttyq* /tmp/dev/ttyr*

TotalRAM=`/usr/sbin/prtconf | grep '^Memory size: ' | \
		sed -e 's/^Memory size: //' -e 's/ .*$//' `

MemUnit=`/usr/sbin/prtconf | grep '^Memory size: ' | \
		sed -e 's/^Memory size: [0-9][0-9]* //' `

case $MemUnit in
	Kilobytes) TotalRAM=`expr $TotalRAM / 1000` ;;
	Megabytes) ;;
	Gigabytes) TotalRAM=`expr $TotalRAM \* 1000` ;;
	*)	   TotalRAM=0 ;;
esac
if [ "$TotalRAM" -le "16" ]
then
	cat </dev/null >/tmp/.nowin
fi

MEMSIZE=`/sbin/mem`
echo "startup available memory: ${MEMSIZE}" \
	>> /tmp/root/var/sadm/system/logs/sysidtool.log
if [ "${MEMSIZE}" -lt 6000 ]; then 
	if [ ! -f /tmp/.nowin ]; then
	        touch /tmp/.nowin 
		echo "startup: insufficient memory for window system" \
			>> /tmp/root/var/sadm/system/logs/sysidtool.log
		echo "Warning: Insufficient memory to start window system."
	fi
fi

# Start up the window system unless the display device cannot be
# determined or the install process with explicitly booted with
# the "-nowin" option.
#
# The window system is necessary to display Internationalized messages.
#
# NOTE:	At this point localization may be set
#
if [ "${RUN_WIN}" -eq 0 -o -f /tmp/.nowin ]; then
	. /sbin/sysconfig
else
	# if the hostname is not yet configured we need a dummy entry
	# in /etc/hosts so the window system will work
	#
	name=`uname -n`
	if [ -z "${name}" ]; then
		uname -S localhost
	fi

	# Set up the customized install user's account directory (/tmp/root);
	# copy the menu file to a writeable area in case localization
	# updates are required by sysconfig; copy the customized openwin-init,
	# Xdefaults, openwin-defaultfont (optional), and Xinitrc files to
	# ${HOME}
	#
	cp -p /usr/lib/locale/C/LC_MESSAGES/install-openwin-menu.gui \
		${HOME}/.openwin-menu 2>/dev/console

	if [ -f /tmp/.mb_locale ]; then
		cp -p \
	/usr/lib/locale/`cat /tmp/.mb_locale`/LC_MESSAGES/openwin-defaultfont \
			${HOME}/.openwin-defaultfont 2>/dev/console
		chmod 755 ${HOME}/.openwin-defaultfont

		locale_from_init
	fi

	cp -p /usr/sbin/install.d/openwin-init \
		${HOME}/.openwin-init 2>/dev/console
	chmod 755 ${HOME}/.openwin-init
	cp -p /usr/sbin/install.d/Xdefaults \
		${HOME}/.Xdefaults 2>/dev/console
	cp -p /usr/sbin/install.d/Xinitrc \
		${HOME}/.xinitrc 2>/dev/console
	chmod 755 ${HOME}/.xinitrc

	echo "Starting OpenWindows..."

	# Start the window system without authentication
	#
	/usr/openwin/bin/openwin -noauth

	# If openwin fails for some reason, start sysconfig without the window
	# system as if the user had booted with the -nowin option
	#
	if [ $? -ne 0 ]; then
		touch /tmp/.nowin
		. /sbin/sysconfig
	fi
fi
