#! /bin/sh
#
# ident data/SCCS/s.install_cluster_patchadd 1.2 09/19/05:18:11:57 SMI
#
# Script to install a patch cluster supplement for Solaris 2.6 - 9
#
########################################################################

set -e

#
# Force the path to first look in certain directories
#
PATH=/sbin:/usr/sbin:/bin:$PATH
export PATH


#
# Supplement tag information
# (Tag needs to be convertible to a valid filename too...)
SUPPLEMENT_NAME="J2SE Solaris 7_x86 Recommended Patch Cluster"

# Broadcast what we are doing
#
echo
echo "Patch cluster install script for ${SUPPLEMENT_NAME}"
echo

logname=`echo ${SUPPLEMENT_NAME} | sed 's/ /_/g'`_log
LOGFILE=/var/sadm/install_data/${logname}

#
# Command line and environment option processing
#
# (Default is *not* to save base objects)
#
Usage()
{
	echo "usage: `basename $0` [-q] [-nosave] [target] [patchdir]"
	echo " [-q]       - quiet option, suppresses interactive warning"
	echo " [-nosave]  - do not save original objects"
        echo " [target]   - destination system to apply or query patches, can be one of:" 
        echo "              [-R client_root_path]  - apply/query patch on bootable client root"
	echo " [patchdir] - optional pathname to directory of patches"

}

cleanup()
{
	#
	# A little cleanup.
	#
	if [ "$finished" = "NO" ]; then
		failed_list="${failed_list} ${patch}"
	fi

	#
	# List the patches that failed installation (if any)
	#
	if [ " ${failed_list}" != " " ]
	then
		echo
		echo "The following patches were not able to be installed:"
		echo ${failed_list} | /usr/bin/tr ' ' '\012' | sed 's/^/	/g'
	fi

	echo
        echo "For more installation messages refer to the installation logfile:"
	echo "  ${LOGFILE}"
	echo 
	echo "Use '/usr/bin/showrev -p' to verify installed patch-ids."
	echo "Refer to individual patch README files for more patch detail."
        echo "Rebooting the system is usually necessary after installation."
}

uid=`id | sed 's/uid=\([0-9]*\)(.*/\1/'`
if [ "$uid" != "0" ] ; then
	echo "You must be root to execute this script."
	exit 1
fi

finished="NO"
saveold=''
quiet="NO"
target=""
while [ "$1" != "" ];
do
	case $1 in
	-nosave)	saveold='-d';;
	--nosave)	saveold='-d';;
	-n)	        saveold='-d';;
	-q)		quiet='YES';;
	-R)		shift
                        if [ $# -gt 0 ] && [ ! -d $1 ]; then
                            echo "$1 client root path not found?"
                            exit 1
                        else
                            target="-R $1" 
                        fi;;
	-*)		Usage; exit 2;;
	*)
		if [ "$finished" = "YES" ]; then
			Usage; exit 2
		fi
		#
		# Where do we find the list of patches to install
		# (we need an absolute pathname...)
		#
		# This is done to maintain the cwd to PATCHDIR to
		# suppress auto unmounts...
		if [ ! -d $1 ]; then
                  echo "$1 optional patch directory not found?"
                  exit 1
                else
		  cd $1
		  finished="YES"
                fi
		;;
	esac
	shift
done
PATCHDIR=`pwd`

if [ "$quiet" != "YES" ]; then
	cat << EOF

*WARNING* SYSTEMS WITH LIMITED DISK SPACE SHOULD *NOT* INSTALL PATCHES:
With or without using the save option, the patch installation process
will still require some amount of disk space for installation and
administrative tasks in the /, /usr, /var, or /opt partitions where
patches are typically installed.  The exact amount of space will
depend on the machine's architecture, software packages already 
installed, and the difference in the patched objects size.  To be
safe, it is not recommended that a patch cluster be installed on a
system with less than 4 MBytes of available space in each of these
partitions.  Running out of disk space during installation may result
in only partially loaded patches.  Check and be sure adequate disk space
is available before continuing.

EOF
	while .
	do
	  echo "Are you ready to continue with install? [y/n]: \c"
	  read reply
	  case $reply
	  in
	    y)	break;;
	    n)	exit;;
	    *)	echo invalid response, enter only 'y' for yes or 'n' for no;;	
	  esac
	done
fi

#
# The patch reference directory must exist
#
if [ ! -d /var/sadm/patch ]; then
        mkdir /var/sadm/patch
        chown bin /var/sadm/patch
        chgrp bin /var/sadm/patch
        chmod 555 /var/sadm/patch
fi

#
# If using save feature:
# Approximate and set cluster save size value.  The maximum save space
# needed should be about no more than half of the actual patch cluster size
# since the patch installation procedure will use compression to save files, and
# patches with multiple architecture packages will only have appropriate
# packages installed on the system.
#
if [ "${saveold}" != -d ]; then
	echo "Determining if sufficient save space exists..."
	BASESIZE=`du -sk $PATCHDIR | cut -f1`
	SUPPLEMENT_SIZE=`expr $BASESIZE / 2`
	bytes_avail=`df -b /var/sadm/patch | tail -1`
	bytes_avail=`echo $bytes_avail | sed 's/.*\ //'`
	if [ ${SUPPLEMENT_SIZE} -gt ${bytes_avail} ]; then
		echo "Insufficient space in /var/sadm/patch to save old files."
		echo "Space required in kilobytes:  ${SUPPLEMENT_SIZE}"
		echo "Space available in kilobytes:  ${bytes_avail}"
		exit 1
	else
		echo "Sufficient save space exists, continuing..."
	fi
else
	echo "The nosave option was used.  Objects will not be saved."
fi


#
# Install all the patches in PATCHDIR
#
# Simply go down the list of existing patches and apply them one at a time
#
echo "Installing patches located in ${PATCHDIR}"
echo "" >> ${LOGFILE}
echo "" >> ${LOGFILE}
echo "*** Install ${SUPPLEMENT_NAME} begins `date` ***" >> ${LOGFILE}
echo "*** PATCHDIR = ${PATCHDIR} ***" >> ${LOGFILE}
echo "" >> ${LOGFILE}

set +e

finished="YES"
failed_list=
trap 'echo; echo Interrupted ... Please wait; cleanup; exit 1' 1 2 3 15

#
# First check for the patch_order file.  If it exists use it for patch
# installation sequence.  If no patch_order file exists then assume
# all directories that begin with 1 in the current directory are the
# patches we want to install and assume the shell coallating sequence
# is the desired install order...
#

if [ -f patch_order ]; then
	patchlist=`cat patch_order`
	echo "Using patch_order file for patch installation sequence"
fi

for patch in ${patchlist} ; do
	if [ -d $patch ]; then
		echo "Installing ${patch}..." | tee -a ${LOGFILE}
		finished="NO"
		( /usr/sbin/patchadd ${saveold} ${target} ${patch} ) >> ${LOGFILE} 2>&1
		result=$?
		if [ ${result} -ne 0 ]; then
			echo "  Installation of ${patch} failed. Return code ${result}."
			failed_list="${failed_list} ${patch}"
		fi
		finished="YES"
	fi
done
cleanup

if [ " ${failed_list}" != " " ]; then
        exit 1
else
        exit 0
fi 
