#!/bin/sh # #pragma ident "@(#)sysidfind.sh 1.9 05/09/06 SMI" # # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # SHELL=/sbin/sh TEXTDOMAIN=SUNW_INSTALL_SCRIPTS PATH=/sbin:/usr/sbin/install.d:${PATH} SYSTEM_CONF=/etc/netboot/system.conf 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[=[: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. # # [&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,retry=2 -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 else echo "WARNING: Cannot find ${2}:${3}/sysidcfg; not using sysid configuration file" fi umount ${MOUNT_CONFIG_DIR} fi fi rmdir ${MOUNT_CONFIG_DIR} return 1 } # # Search for the sysid configuration file # in bootinfo. # dhcp_or_manual_sysid_config() { MOUNT_CONFIG_DIR=/tmp/sysid_config.$$ mkdir ${MOUNT_CONFIG_DIR} # # Check for a dhcp SsysidCF entry # if [ -f ${SYSTEM_CONF} ] ; then . ${SYSTEM_CONF} else SsysidCF=`/sbin/dhcpinfo SsysidCF` fi if [ ${SsysidCF}"X" != "X" ]; then case ${SsysidCF} in *://*) # It's a URL URL=${SsysidCF} PROXY="" if [ -n "${PROXY}" ] ; then PROFETCH_ARGS="-p ${PROXY}" fi profetch ${PROFETCH_ARGS} ${URL}/sysidcfg > /tmp/sysidcfg.$$ 2> /dev/null if [ $? -eq 0 ] ; then echo "Using sysid configuration file ${URL}/sysidcfg" cat /tmp/sysidcfg.$$ > /etc/sysidcfg 2> /dev/null return 0 else echo "Cannot find ${URL}/sysidcfg" fi ;; *) # it's not a URL mount -o ro,retry=2 -F nfs ${SsysidCF} \ ${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 ;; esac 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 } # # Search for sysid_config property (set via grub menu) # property_sysid_config() { SsysidCF=`prtconf -v /devices | sed -n '/sysid_config/{;n;p;}' | cut -f 2 -d \'` if [ ${SsysidCF}"X" = "X" ]; then return 1 fi case ${SsysidCF} in *://*) # It's a URL URL=${SsysidCF} PROXY="" if [ -n "${PROXY}" ] ; then PROFETCH_ARGS="-p ${PROXY}" fi profetch ${PROFETCH_ARGS} ${URL}/sysidcfg > /tmp/sysidcfg.$$ 2> /dev/null if [ $? -eq 0 ] ; then echo "Using sysid configuration file ${URL}/sysidcfg" cat /tmp/sysidcfg.$$ > /etc/sysidcfg 2> /dev/null return 0 else echo "Cannot find ${URL}/sysidcfg" fi ;; *) # it's not a URL MOUNT_CONFIG_DIR=/tmp/sysid_config.$$ mkdir ${MOUNT_CONFIG_DIR} mount -o ro,retry=2 -F nfs ${SsysidCF} \ ${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 ${SsysidCF}/sysidcfg" return 0 fi umount ${MOUNT_CONFIG_DIR} fi rmdir ${MOUNT_CONFIG_DIR} ;; esac 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 property_sysid_config if [ $? -ne 0 ]; then floppy_sysid_config fi if [ $? -ne 0 ]; then # Look for sysidcfg via DHCP only if the network is using DHCP if [ "X${_INIT_NET_STRATEGY}" = "Xdhcp" -o "X${_INIT_NET_STRATEGY}" = "Xmanual" ]; then dhcp_or_manual_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}