#!/bin/ksh

## Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
## Use is subject to license terms.

## Is it safe to proceed.
ARCH=`uname -p`
if [ $ARCH != i386 ]; then
	exit 0
fi

PATH="/usr/bin:/usr/sbin:${PATH}"; export PATH
PKGCOND=/usr/bin/pkgcond

CheckZones()
{
        if [ "$ROOTDIR" = "/" -a -x /usr/bin/zonename ]; then
                ZONENAME=`/usr/bin/zonename`
                if [ ${ZONENAME} = "global" ]; then
                        GLOBAL_ZONE=true
                else
                        GLOBAL_ZONE=false
                fi
        else
                # Unable to determine zone
                GLOBAL_ZONE=true
        fi
}


fix_cputrak() {
	################################################################################
	# Removal of cputrack object is to circumvent the stringent check ( attribute
	# checking ) in the local zone environment.
	# ERROR: attribute verification of </usr/bin/cputrac> failed.
	################################################################################
	Quiet() {
	        typeset -r cmd_n_args=$*
		 eval "$cmd_n_args" > /dev/null 2>&1
	}
	
	typeset -r cpu_dir=$ROOTDIR/usr/bin
	typeset -r cpu_track=$cpu_dir/cputrack
	typeset -r cpu_pkg=SUNWcpcu
	
	Quiet removef -R $ROOTDIR $cpu_pkg $cpu_track
	Quiet removef -R $ROOTDIR -f $cpu_pkg
	
	# Destroy the hardlink regardless of the zone type (global/local(sparse, blank))
	/usr/bin/rm -f $cpu_track
	################################################################################
}

##
## Move kbtrans to the correct pkg if needed.
##
fix_kbtrans() {

	rmpkg=SUNWusb
	addpkg=SUNWckr
	kbtrans=/kernel/misc/amd64/kbtrans
	
	relocate_kbtrans() {
	
	
	        if [ ! -f $ROOTDIR/$kbtrans ] ; then
	                return
	        fi
	
		## This patch will add kbtrans to SUNWckr.  Manually remove it from SUNWusb
		## if it exists
		##
		Pgk=`pkgchk -R $ROOTDIR -l -p $kbtrans | grep $rmpkg`
		if [ "$?" =  "0" ] ; then
			removef -R $ROOTDIR $rmpkg $ROOTDIR/$kbtrans 1>/dev/null 2>&1
			removef -R $ROOTDIR -f $rmpkg
			installf -R $ROOTDIR $addpkg $ROOTDIR/$kbtrans
			installf -R $ROOTDIR -f $addpkg
		fi
	}
	
   	relocate_kbtrans
	return 0
} 

##
## Save kbtrans entry
##
## Address 6343544 by using workaround 6312956 - removef doesn't update zones
## saved pkgmap files. We'll use cp -p to preserve permissions on the pkgmap
## file. Even though kbtrans may have moved from SUNWusb to SUNWckr, the
## pkgmap still needs to be cleaned up after the package switch is complete.
## 

save_kbtrans_pkgmap () {

	rmpkg=SUNWusb
	kbtrans_entry=kernel/misc/amd64/kbtrans
	mypatchid=${PatchNum}

	if [ ! -d $ROOTDIR/var/sadm/pkg/$rmpkg/save/pspool/$rmpkg ]; then
		return
	fi

	cd $ROOTDIR/var/sadm/pkg/$rmpkg/save/pspool/$rmpkg
	## Until removef/installf is fixed, we'll check if the entry is
	## still in the origin package's pkgmap

	if grep "$kbtrans_entry" pkgmap >/dev/null
	then
	    ## Save kbtrans entry in backoutpkgmap for postbackout restore
	    backoutpkgmap=/tmp/$rmpkg.pkgmap.$mypatchid
	    cp -p pkgmap $backoutpkgmap
       	    grep "$kbtrans_entry" pkgmap > $backoutpkgmap

	    ## Remove kbtrans entry in present SUNWusb pkgmap to clean up
            cp -p pkgmap pkgmap.tmp
            grep -v "$kbtrans_entry" pkgmap > pkgmap.tmp
            mv pkgmap.tmp pkgmap

    	fi

}


##
## newboot support
## 
newboot () {
	BASEDIR=$ROOTDIR
	MEMSIZE_MIN=250
	MDPATCH=117435-02


	#
	# Check for sufficient system memory
	#
	memsize=`prtconf | grep "Memory size:" | cut -d' ' -f3`
	if [ "$memsize" -lt "$MEMSIZE_MIN" ]; then
		echo "Not enough memory for GRUB based boot process."
		exit 1
	fi

	#
	# Check for biosdev and make sure it works
	#
	if [ -x /sbin/biosdev ]; then
		/sbin/biosdev 2> /dev/null | grep "^0x80" > /dev/null
		if [ $? = 0 ]; then
			return 0
		fi
	fi

	#
	# biosdev failed. We can still apply the patch if the rootdisk
	# is the same as the bootdisk
	#
	bootdev=`prtconf -v /devices | sed -n '/boot-device/{n;p;}' | grep pci | cut -f 2 -d \'`
	rootdev=`df -k ${BASEDIR:-/} | nawk 'NR > 1 { print $1 }'`
	if [ -n "$bootdev" ] ; then
		ls -l $rootdev | grep $bootdev > /dev/null
		if [ $? = 0 ]; then
			return 0
		fi
	fi

	#
	echo ""
	echo "ERROR: One of the following may need to be corrected prior to installing this patch."
	echo "ERROR:"
	echo "ERROR: The boot device may be different from the root device on `hostname`."
	echo "ERROR: If you have booted from a floppy disk, eject the disk and reboot `hostname` prior"
	echo "ERROR: to installing this patch."
	echo ""
	echo "ERROR: You may have forgotten to reboot `hostname` AFTER installing $MDPATCH."
	echo "ERROR: This configuration requires that $MDPATCH be installed first and the"
	echo "ERROR: system must then be rebooted prior to installing this patch."
	echo ""
	exit 1
} 

ExecuteALLCmds () {

	newboot
	fix_kbtrans
	save_kbtrans_pkgmap

	return 0
}


ExecuteInProperEnvironment () {

   ##  $PKGCOND is_path_writable $ROOTDIR/usr/bin && fix_cputrak
   /usr/bin/touch ${ROOTDIR}/usr/bin/.test.$$ > /dev/null 2>&1 && {
       fix_cputrak
       /usr/bin/rm /usr/bin/.test.$$ > /dev/null 2>&1
   }

   if $PKGCOND is_whole_root_nonglobal_zone > /dev/null 2>&1 ; then
       # Execute non-global whole root zone commands.
       # Should be same action as the default action.
       return 0
   fi

   if $PKGCOND is_nonglobal_zone > /dev/null 2>&1 ; then
       # Execute non-global zone commands. Should be no action here
       return 0
   fi

   if $PKGCOND is_netinstall_image > /dev/null 2>&1 ; then
       # Execute commands applicable to patching the mini-root.
       # There are usually no actions to take here since your patching
       # the mini-root on an install server.
       ExecuteALLCmds
       return 0
   fi

   if $PKGCOND is_mounted_miniroot > /dev/null 2>&1 ; then
       # Execute commands specific to the mini-root
       fix_kbtrans
       save_kbtrans_pkgmap
       return 0
   fi

   if $PKGCOND is_diskless_client > /dev/null 2>&1 ; then
       # Execute commands specific to diskless client
       fix_kbtrans
       save_kbtrans_pkgmap
       return 0
   fi

   if $PKGCOND is_alternative_root > /dev/null 2>&1 ; then
       # Execute commands specific to an alternate root
       ExecuteALLCmds
       return 0
   fi

   if $PKGCOND is_global_zone > /dev/null 2>&1 ; then
       # In a global zone and system is mounted on /.
       # Execute all commands.
       ExecuteALLCmds
       return 0
   fi

   return 1
} 


ZONENAME=global
[ -x /sbin/zonename ] && ZONENAME=`/sbin/zonename`

if [ -x "$PKGCOND" ] ; then
   ExecuteInProperEnvironment && exit 0 || exit 1
else
   fix_cputrak
   CheckZones
   if [ "${GLOBAL_ZONE}" = "true" ]; then
        ExecuteALLCmds  && exit 0 || exit 1
   fi
fi 

