#!/bin/ksh

PATH=/usr/bin:/usr/sbin:$PATH; export PATH
PKGCOND=/usr/bin/pkgcond
LOGIN_ENTRY_NON_RE="/dev/console    0600    /dev/usb/\[0-9a-f\]\+\[.\]\[0-9a-f\]\+/\[0-9\]\+/\*"
export LOGIN_ENTRY_NON_RE
EXIT=0
no_user_aliases() {
        driver=$1
        grep "^${driver} " $ROOTDIR/etc/driver_aliases > /dev/null 2>&1

        return $?
}

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
}

load_mods() {

	## load modules during patch installation per 6349240
	## to prevent warnings from displaying on the console
	## before the system is rebooted.

	## Is OS 32 or 64 bit?
	ISA_INFO=`/usr/bin/isainfo -b`

	if [ ${ROOTDIR} = "/" ]; then
		##
		## Disable kernel module unloading
		##
		print "Disabling kernel module unloading ... \n"
		if [ -x /usr/bin/mdb ]; then
			if [ $ISA_INFO = 64 ]; then
				SAVED_ADDR=`echo '_kobj_printf/J' | mdb -k | cut -f2 -d ':'`
				echo '_kobj_printf/Z systrace_stub' | mdb -kw > /dev/null 2>&1
			else
				SAVED_ADDR=`echo '_kobj_printf/X' | mdb -k | cut -f2 -d ':'`
				echo '_kobj_printf/W systrace_stub' | mdb -kw > /dev/null 2>&1
			fi

			echo "moddebug/W20000" | mdb -kw > /dev/null 2>&1
		else
			echo "mdb not found: patchadd not safe."
		fi
		cd ${patchdir:-$PWD}

		## find all kernel driver modules in patch
		if [ -f /var/sadm/patch/$PatchNum/backoutmods ]; then
			while read line; do
			## preload each module
				[ -f /$line ] && {
				## echo "loading module $line"
				modload /$line > /dev/null 2>&1
			}
			done < /var/sadm/patch/$PatchNum/backoutmods
		fi

		if [ $ISA_INFO = 64 ]; then
			echo '_kobj_printf/Z '$SAVED_ADDR | mdb -kw > /dev/null 2>&1
		else
			echo '_kobj_printf/W '$SAVED_ADDR | mdb -kw  > /dev/null 2>&1
                fi
	fi
}


## umount_libc_psr () {
## 
## #
## # SUNWust1.v preremove script
## #
## 
## 	# If architecture is not sun4v, then do not unmount the libc_psr_hwcap1 library.
## 	ARCH=`uname -m`
## 	if [ $ARCH != "sun4v" ]
## 	then
## 		return 
## 	fi
## 
## 	# Unmount the specific mount point where libc_psr_hwcap1 library is
## 	# mounted. Presently this package delivers only one hwcap library. If
## 	# this package is updated to deliver more hwcap libraries, then script
## 	# will need to be modified to unmount mount points for those hwcap
## 	# libraries.
## 
## 	mount_points=`mount | grep libc_psr_hwcap1 | awk '{print $1}' | tr -s "\n" " "`
## 	for mount_point in $mount_points
## 	do
## 		echo "Unmounting $mount_point"
## 		umount $mount_point
## 	done
## 
## }

update_logindevperm(){
	egrep -v "$LOGIN_ENTRY_NON_RE" $ROOTDIR/etc/logindevperm > /tmp/logindevperm$$
	cp -p $ROOTDIR/etc/logindevperm $ROOTDIR/etc/logindevperm.backout-$PatchNum
	mv /tmp/logindevperm$$ $ROOTDIR/etc/logindevperm
}

Execute_commands() {
  ## if grep -w ugen ${ROOTDIR}/etc/name_to_major > /dev/null 2>&1
  ## then
  ## no_user_aliases ugen || /usr/sbin/rem_drv -b "${ROOTDIR}" ugen > /dev/null 2>&1
  ## fi

  load_mods
##  umount_libc_psr

##  egrep -v "$LOGIN_ENTRY_NON_RE" $ROOTDIR/etc/logindevperm > /tmp/logindevperm$$
##  cp -p $ROOTDIR/etc/logindevperm $ROOTDIR/etc/logindevperm.backout-$PatchNum
##  mv /tmp/logindevperm$$ $ROOTDIR/etc/logindevperm

  update_logindevperm

   return $EXIT
}


LocalZones () {
# commands specific to non-gloabl zones
return 0

}

ExecuteInProperEnvironment () {
   if $PKGCOND is_whole_root_nonglobal_zone > /dev/null 2>&1 ; then
       # Execute non-global whole root zone commands.
       update_logindevperm
       return 0
   fi

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

   if $PKGCOND is_netinstall_image > /dev/null 2>&1 ; then
       # Execute commands applicable to patching the mini-root.
       update_logindevperm
       return 0
   fi

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

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

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

   if $PKGCOND is_global_zone > /dev/null 2>&1 ; then
       # In a global zone and system is mounted on /.
       Execute_commands
       return $?
   fi
   return 1
}

AlternateRoot()
# returns 0 if $PKG_INSTALL_ROOT -
{
	if [ -n "$ROOTDIR" ]; then
		if  [ "/" = "`echo $ROOTDIR |nawk '{gsub(/\/+/,"/"); print}'`" ]; then
			return 1
		else
			return 0
		fi
	else
		return 1
	fi
}

Check_miniroot()
{
	if [ ! -z "$PKGDBARG" ]; then
		echo $PKGDBARG | grep "^\-C" > /dev/null 2>&1
		if [ $? -eq 0 ] ; then
				if [ X"$PKG_NONABI_SYMLINKS" != X"true" ]; then
				return 1
			fi
		fi
	fi
	return 0
}

CheckLOFI()
{
	LOFITESTF1=/tmp/.lofitestf1.$$.$PatchNum
	LOFITESTF2=/tmp/.lofitestf2.$$.$PatchNum
	mkdir -p /tmp
	echo "1" >$LOFITESTF1
	echo "2" >$LOFITESTF2
	if  mount -F lofs $LOFITESTF1 $LOFITESTF2 >/dev/null 2>&1; then
		if [ X"`cat $LOFITESTF2`" = X"1" ]; then
			# well lofs mount does work
			_LOFI=0
		else
			#It does not work :(
			_LOFI=1
		fi
	else
		_LOFI=1
	fi
	umount $LOFITESTF2 >/dev/null 2>&1
	rm -f $LOFITESTF2 $LOFITESTF1
	return $_LOFI
}


# Main

/bin/rm -f /tmp/$PatchNum.log


if AlternateRoot; then
	: # well no lofs mounts are needed
else
	if CheckLOFI; then
		: # we are ok to proceed
	else
		cat <<EOM
ERROR: lofs mount test failed. It can be caused by "exclude: lofs" entry in /etc/system.
       Please be sure that lofs mount is working before this patch removal.
EOM
		exit 1
	fi
fi

if Check_miniroot; then
	: # we are ok, PKG_NONABI_SYMLINKS is set up
else
	echo "ERROR: PKG_NONABI_SYMLINKS must be set to true for patchrm -C"
	exit 1
fi

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

exit 0
