#!/bin/sh 
#
#ident	"@(#)sysidfind.sh	1.2	01/04/19 SMI"
#
# Copyright (c) 2001 by Sun Microsystems, Inc.
# All rights reserved.
#

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

PLATFORM=`/sbin/uname -p`
ESTATUS=0

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

#
# 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}"
		ESTATUS=0
		return 0
	fi

	ESTATUS=0
	return 1
}

#
# Search for the sysid configuration file on the network, according
# to the URL given.
#
# Arguments:	${1}	- URL specifying location of files.
#			  The format of the string is a URL
#                             with possible arguments. Arguments
#                             are separated from each other and from
#                             the operand by the standard & charcter.
#
#			  <standard http URL>[&proxy=host:port]
#
net ()
{
	MOUNT_CONFIG_DIR=/tmp/cjnetconfig.$$
  
	# the extended URL
	EURL="${1}"
  
	# parse the arguments from the giant url
	for ARG in `echo ${EURL}|sed 's/&/ /g` ; do
	    case $ARG in

		*:/*)
		    # the URL part
		    URL=${ARG}
		    ;;

		proxy=*)
		    PROXY=`expr "${ARG}" : 'proxy=\(.*\)'`
		    ;;

		*)
		    echo "Invalid URL argument ${ARG} : ignored."
		    ;;
	    esac
	done

	if [ -n "${PROXY}" ] ; then
	    PROFETCH_ARGS="-p ${PROXY}"
	fi

	# figure out what extraction method was used, with tar
	# being the default.  Each extractor has it's stderr piped
	# into tar, so that if it fails and generates some textual
	# error output on stderr, the subsequent tar command will
	# also fail, thereby failing the whole operation.  If we
	# didn't do this, tar would receive 0 bytes to untar, which
	# it considers a success.
	EXTRACTOR="tar xf -"
	if [ `echo "${URL}" | egrep -i '.tar$'` ] ; then
	    EXTRACTOR="tar xf -"
	elif [ `echo "${URL}" | egrep -i '.tar.Z$|.tz$'` ] ; then
	    EXTRACTOR="zcat 2>&1 | tar xf -"
	elif [ `echo "${URL}" | egrep -i '.tar.bz2$|.tar.bzip2$|.tbz2$'` ] ; then
	    EXTRACTOR="bzcat 2>&1 | tar xf -"
	elif [ `echo "${URL}" | egrep -i '.zip$'` ] ; then
	    EXTRACTOR="cat > /tmp/sysidfind.$$ ; unzip /tmp/sysidfind.$$"
	else
	    BN=`basename "${URL}"`
	    echo `gettext "Unable to determine file type for $BN, attempting .tar"`
	fi

	# Extract the files from the net
	old_dir=`pwd`
	if [ ! -d ${MOUNT_CONFIG_DIR} ] ; then
	    mkdir ${MOUNT_CONFIG_DIR}
	fi
	cd ${MOUNT_CONFIG_DIR}
	echo "`gettext 'Downloading configuration file(s) from'` $URL"
	eval "profetch ${PROFETCH_ARGS} ${URL} 2>&1 | ${EXTRACTOR} >/dev/null 2>&1"
	status=$?
	if [ $status != 0 ] ; then
		# that failed.  Try again with the default file
		echo "`gettext 'Downloading failed.  Looking for jumpstart.tar'`"
		NEWURL="`echo ${URL}|sed s'/\/\{1,\}$//'`/jumpstart.tar"
		eval "profetch ${PROFETCH_ARGS} ${NEWURL} 2>&1 | tar xf - > /dev/null 2>&1"
		status=$?
	fi
	cd $old_dir
	if [ $status != 0 ] ; then
		MESSAGE=`gettext "Unable to extract files from net using"`" ${URL}."
		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 "Found sysid configuration file at ${1}"
		ESTATUS=0
		return 0
	fi

	ESTATUS=0
	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
}


find_files()
{
    # If the `tape' boot option was specified, search for the sysidcfg file on
    # an attached tape drive.  If a URL was provided, try and get the files
    # via profetch.  Otherwise, search for it in the following order:
    #	floppy (PCFS)
    #	floppy (UFS)
    #	network (bootparams or DHCP)
    #
    if [ -f /tmp/.cjfiles_method ] ; then
	    METHOD=`head -1 /tmp/.cjfiles_method|nawk '{print $2}'`
	    case "$METHOD" in
		tape*)
		    tape "$METHOD"
		    ;;
		*:/*)
		    # a URL.  Must be a cjboot.
		    net "$METHOD"
		    ;;
		*)
		    MESSAGE=`gettext "Invalid retrieval method"`" $METHOD"
		    ESTATUS=1
		    ;;
	    esac
	    return $ESTATUS
    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

}

# execution starts here
#

# ask the user, if they want to be asked
if [ -f /tmp/.cjfiles_ask ] ; then
    # interactive.  We insist that a valid URL is given before continuing.
    ESTATUS=1
    while [ "$ESTATUS" != 0 ] ; do
	echo "`gettext 'Please enter the URL of configuration files(s).'`"
	echo "`gettext 'Press ENTER to bypass this question.'`"
	echo "`gettext 'URL: '`\c"
	read ans
	echo "`gettext 'Please Wait...'`"
	rm -f /tmp/.cjfiles_method
	if [ "X${ans}" = "X" ] ; then
	    # they want to bypass. So lets do a single pass and ignore errors.
	    echo "`gettext 'Please Wait...'`"
	    find_files
	    if [ "$ESTATUS" != 0 ] ; then
		echo $MESSAGE
	    fi
	    ESTATUS=0
	else
	    echo "cj_location $ans" > /tmp/.cjfiles_method
	    find_files
	    if [ "$ESTATUS" != 0 ] ; then
		echo $MESSAGE
	    else
		# a good URL was given.  let's not ask again
		rm -f /tmp/.cjfiles_ask
	    fi
	fi
    done
else
    # non-interactive, just try the one that was given
    find_files
    if [ "$ESTATUS" != 0 ] ; then
	echo $MESSAGE
    fi
fi


exit ${ESTATUS}
