# checkinstall script to control a patch installation.
# directory format options.
#
#       @(#)checkinstall 1.9 02/03/04 SMI
#
# Copyright (c) 2002 by Sun Microsystems, Inc.
# All rights reserved
#

PATH=/usr/sadm/bin:$PATH

NOVERS_MSG="PaTcH_MsG 8 Version $VERSION of $PKG is not installed on this system."
ALRDY_MSG="PaTcH_MsG 2 Patch number $SUNW_PATCHID is already applied."
TEMP_MSG="PaTcH_MsG 23 Patch number $SUNW_PATCHID cannot be applied until all \
restricted patches are backed out."

# Read the provided environment from what may have been a request script
. $1

# Old systems can't deal with checkinstall scripts anyway
if [ "$PATCH_PROGRESSIVE" = "true" ]; then
	exit 0
fi

#
# Confirm that the intended version is installed on the system.
#
if [ "${UPDATE}" != "yes" ]; then
	echo "$NOVERS_MSG"
	exit 3
fi

#
# Confirm that this patch hasn't already been applied and
# that no other mix-ups have occurred involving patch versions and
# the like.
#
Skip=0
active_base=`echo $SUNW_PATCHID | nawk '
	{ print substr($0, 1, match($0, "-")-1) } '`
active_inst=`echo $SUNW_PATCHID | nawk '
	{ print substr($0, match($0, "-")+1) } '`

# Is this a restricted patch?
if echo $active_base | egrep -s "R"; then
	is_restricted="true"
	# All restricted patches are backoutable
	echo "PATCH_NO_UNDO=" >> $1
else
	is_restricted="false"
fi

for patchappl in ${PATCHLIST}; do
	# Is this an ordinary patch applying over a restricted patch?
	if [ $is_restricted = "false" ]; then
		if echo $patchappl | egrep -s "R"; then
			echo "$TEMP_MSG"
			exit 3;
		fi
	fi

	# Is there a newer version of this patch?
	appl_base=`echo $patchappl | nawk '
		{ print substr($0, 1, match($0, "-")-1) } '`
	if [ $appl_base = $active_base ]; then
		appl_inst=`echo $patchappl | nawk '
			{ print substr($0, match($0, "-")+1) } '`
		result=`expr $appl_inst \> $active_inst`
		if [ $result -eq 1 ]; then
			echo "PaTcH_MsG 1 Patch number $SUNW_PATCHID is superceded by the already applied $patchappl."
			exit 3
		elif [ $appl_inst = $active_inst ]; then
			# Not newer, it's the same
			if [ "$PATCH_UNCONDITIONAL" = "true" ]; then
				if [ -d $PKGSAV/$SUNW_PATCHID ]; then
					echo "PATCH_NO_UNDO=true" >> $1
				fi
			else
				echo "$ALRDY_MSG"
				exit 3;
			fi
		fi
	fi
done

# Construct a list of applied patches in order
echo "PATCHLIST=${PATCHLIST} $SUNW_PATCHID" >> $1

#
# Construct the complete list of patches this one obsoletes
#
ACTIVE_OBSOLETES=$SUNW_OBSOLETES

if [ -n "$SUNW_OBSOLETES" ]; then
	# Clear the parameter since it has already been used.
	echo "SUNW_OBSOLETES=" >> $1

	# Pass it's value on to the preinstall under another name
	echo "ACTIVE_OBSOLETES=$ACTIVE_OBSOLETES" >> $1
fi

#
# Use the first found pkginfo file since all pkginfo files MUST contain
# the same patch meta data. This is done since we can never be guaranteed of
# where the checkinstall script is located. This will work for all Solaris
# releases.
#

for pkginfo in $INST_DATADIR/*/pkginfo; do
	tmpRequire=`nawk -F= ' $1 ~ /REQUIR/ { print $2 } ' $pkginfo`
	tmpIncompat=`nawk -F= ' $1 ~ /INCOMPAT/ { print $2 } ' $pkginfo`
	break
done

#
# Construct PATCH_INFO line for this package.
#

if [ -n "$tmpRequire" ] && [ -n "$tmpIncompat" ]
then
	echo "PATCH_INFO_$SUNW_PATCHID=Installed: `date` From: `uname -n` \
	  Obsoletes: $ACTIVE_OBSOLETES Requires: $tmpRequire \
	  Incompatibles: $tmpIncompat" >> $1
elif [ -n "$tmpRequire" ]
then
	echo "PATCH_INFO_$SUNW_PATCHID=Installed: `date` From: `uname -n` \
	  Obsoletes: $ACTIVE_OBSOLETES Requires: $tmpRequire Incompatibles: " >> $1
elif [ -n "$tmpIncompat" ]
then
	echo "PATCH_INFO_$SUNW_PATCHID=Installed: `date` From: `uname -n` \
	  Obsoletes: $ACTIVE_OBSOLETES Requires: Incompatibles: $tmpIncompat" >> $1
else
	echo "PATCH_INFO_$SUNW_PATCHID=Installed: `date` From: `uname -n` \
	  Obsoletes: $ACTIVE_OBSOLETES Requires: Incompatibles: " >> $1
fi

# There can be three conditions that exist for this or an older checkinstall
# script, listed in order of precedence:
#
# 1. The checkinstall script is located in $INST_DATADIR/<pkgabbrev>.[<ext>]
# 2. The checkinstall has been moved to /tmp
# 3. An old checkinstall script must handle both 1 and 2.

# Check to see if the script has been moved to /tmp by pkginstall.

EXECDIR=`dirname $0 | grep "^/tmp/install"`

if [ -n "$SUNW_PKG_DIR" ]; then
	SCRIPTS_DIR="$SUNW_PKG_DIR/install"
elif [ -z "$EXECDIR" ]; then
	SCRIPTS_DIR=`dirname $0`
else
	# The script has been moved to /tmp. This should never happen since S9
	# pkginstall only moves the checkinstall script if it detects that it is
	# not a patch installation.

	EXT=`echo $ARCH | sed \
		-e 's/all//' \
		-e 's/sparc\.sun4/\./' \
		-e 's/sparc//' \
		-e 's/sparcv9//' \
		-e 's/i386\.i86pc/\.i/' \
		-e 's/i386//'`
	SCRIPTS_DIR="$INST_DATADIR/$PKGINST$EXT/install"
fi

echo "SCRIPTS_DIR=$SCRIPTS_DIR" >> $1

# If additional operations are required for this package, place
# those package-specific commands here.

#XXXSpecial_CommandsXXX#
#
#checkinstall	1.4	02/06/20 SMI
#
# Copyright 2001 by Sun Microsystems, Inc.
# All rights reserved.
#

#
# Parseable OS requirement.  Package will not install on anything
# that doesn't meet this requirement.  (Major number must be the same,
# and the minor/micro numbers must indicate the same or higher version.)
#
OS=SunOS
REQUIRED_MAJOR=5
REQUIRED_MINOR=8
REQUIRED_MICRO=
#
# Human friendly version of OS, used for output.
#
REQUIRED_OS="Solaris 8 2/02"

#
# Default value of actual OS.
#
VERSION=`uname -r`

# if this file exists, then we ignore requirement checks
OVERRIDE=/tmp/SUNW_FORCE_PKGADD

#
# Patch requirements, we refuse to install if these are not met.
#
sparc_PATCHREQS_5_8="SUNWapchu:109234-02"
i386_PATCHREQS_5_8="SUNWapchu:109235-02"
#
# Package requirements.
#
sparc_PKGREQS="SUNWapchu"
i386_PKGREQS="SUNWapchu"

debug=yes

decho() {
	if [ -n "$debug" ]
	then
		echo "$@" 1>&2
	fi
}

check_uname()
{
	major=`echo ${VERSION} | cut -d. -f1`
	minor=`echo ${VERSION} | cut -d. -f2`
	micro=`echo ${VERSION} | cut -d. -f3`
	major=${major:-0}
	minor=${minor:-0}
	micro=${micro:-0}

	#
	# Solaris 8 requires "special" versions of mod_ssl.  This is because
	# S8 Apache isn't built with -D_LARGEFILE_SOURCE, whereas S9 and
	# later are.
	#
	if [ ${major} -eq 5 -a ${minor} -le 8 ]
	then
		SOLREL=8
	else
		SOLREL=9
	fi

	if [ ${major} -eq ${REQUIRED_MAJOR} ]
	then
		if [ ${minor} -gt ${REQUIRED_MINOR} ]
		then
			return 0
		elif [ ${minor} -eq ${REQUIRED_MINOR} ]
		then
			if [ ${micro} -ge ${REQUIRED_MICRO:-0} ]
			then
				return 0
			fi
		fi
	fi

	if [ -f $OVERRIDE ]
	then
		decho "This package requires ${REQUIRED_OS} or better."
		decho "Ignoring requirements and proceeding anyway..."
		return 0
	fi
	decho "###"
	decho "### Solaris release verification failed."
	decho "###"
	decho "### This product requires ${REQUIRED_OS} or better.  You can"
	decho "### obtain updated Solaris software from your service provider,"
	decho "### or on the web at http://www.sun.com/solaris"
	decho "###"
	decho "###  PACKAGE INSTALLATION FAILED."
	decho "###"
	exit 3
}

patch_meets_req()
{
	pkg=$1; shift
	patchid=$1; shift
	applied=$1; shift;
	patchnum=`echo $patchid | cut -d- -f1`
	patchrev=`echo $patchid | cut -d- -f2`
	num=`echo $applied | cut -d- -f1`
	rev=`echo $applied | cut -d- -f2`

	if [ \( $num = $patchnum \) -a \( $rev -ge $patchrev \) ]
	then
		return 0
	fi

	# iterate through applied patches
	for p in `obsolete_list $pkg $applied`
	do
		num=`echo $p | cut -d- -f1`
		rev=`echo $p | cut -d- -f2`

		if [ \( $num = $patchnum \) -a \( $rev -ge $patchrev \) ]
		then
			return 0
		fi
	done
	return 1
}

obsolete_list()
{
	pkgparam $reloc $1 PATCH_INFO_$2 | \
		sed -e 's/.*Obsoletes://' -e 's/Requires:.*//'
}

pkg_patches()
{
	pkgparam $reloc $1 PATCHLIST
}

check_patches()
{
	decho "Verifying required patches are installed..."

	for need in "$@"
	do
		pkg=`echo $need | cut -d : -f1`
		reqs=`echo $need | cut -d : -f2 | tr , ' '`
		pkginfo -q $reloc $pkg
		if [ $? -ne 0 ]
		then
			continue
		fi
		inst=`pkg_patches $pkg`
		for req in $reqs
		do
			notmet=$req
			for p in $inst
			do
				if patch_meets_req $pkg $req $p
				then
					decho "Requirement for $req met by $p."
					notmet=
					break
				fi
			done
			if [ -n "$notmet" ]
			then
				missing="$missing $notmet"
			fi
		done
	done

	if [ -z "$missing" ]
	then
		decho "All required patches installed."
		return 0
	fi
	# this collapses whitespaces, and trims leading and trailing
	# whitespace as well
	missing=`echo $missing`
	if [ -f $OVERRIDE ]
	then
		decho "Required patches not installed: $missing"
		decho "Ignoring requirements and proceeding anyway..."
		return 0
	fi
	decho "###"
	decho "### Patch verification failed."
	decho "###"
	decho "### Required patches not installed: $missing"
	decho "###"
	decho "### You MUST apply the required patches before installing"
	decho "### this product.  Patches can be obtained from your service"
	decho "### provider, or on the web at http://sunsolve.sun.com"
	decho "###"
	decho "###  PACKAGE INSTALLATION FAILED."
	decho "###"
	exit 3
}

check_pkgs()
{
	decho "Verifying required packages are installed..."

	missing=
	for need in "$@"
	do
		pkginfo ${reloc} -q ${need}
		if [ $? -ne 0 ]
		then
			missing="$missing $need"
		fi
	done

	if [ -z "$missing" ]
	then
		decho "All required packages installed."
		return 0
	fi
	# this collapses whitespaces, and trims leading and trailing
	# whitespace as well
	missing=`echo $missing`
	if [ -f $OVERRIDE ]
	then
		decho "Required packages not installed: $missing"
		decho "Ignoring requirements and proceeding anyway..."
		return 0
	fi
	decho "###"
	decho "### Package verification failed."
	decho "###"
	decho "### Required packages not installed: $missing"
	decho "###"
	decho "### You MUST install the required packages before installing"
	decho "### this package.  Packages can be found on your Solaris "
	decho "### installation media.  Contact your service provider if you"
	decho "### require further assistance."
	decho "###"
	decho "###  PACKAGE INSTALLATION FAILED."
	decho "###"
	exit 3
}

determine_version()
{
	# In order to better support relocated installation via the -R pkgadd
	# flag, we must check for /var/sadm/softinfo/INST_RELEASE if
	# PKG_INSTALL_ROOT is specified

	if [ -n "${PKG_INSTALL_ROOT}" ]
	then
	    ARCH=${ARCH:-`pkgparam $reloc SUNWcsr ARCH`}
	    rversion=`pkgparam $reloc SUNWcsr SUNW_PRODVERS | cut -d/ -f1`
	    if [ -z "$rversion" ]
	    then
		# 2.6 and earlier lack the SUNW_ prefix
		rversion=`pkgparam $reloc SUNWcsr PRODVERS | cut -d/ -f1`
	    fi
	    if [ -n $rversion ]
	    then
		VERSION=$rversion
	    else
		echo "WARNING: Unable to determine relocated OS version."
		echo "         Assuming install and target are the same."
	    fi
	fi
}

if [ -n "${PKG_INSTALL_ROOT}" ]
then
	reloc="-R ${PKG_INSTALL_ROOT}"
	determine_version
else
	ARCH=${ARCH:-`uname -p`}
fi

decho "Checking operating environment requirements..."
check_uname
if [ $SOLREL -eq 8 ]
then
	echo 'CLASSES="none s8"' >> $1
else
	echo 'CLASSES="none s9"' >> $1
fi

decho "Determining package requirements..."
eval PKGREQS=\$${ARCH}_PKGREQS
check_pkgs $PKGREQS

decho "Determining patch requirements..."
eval PATCHREQS=\$${ARCH}_PATCHREQS_`echo ${VERSION} | tr . _`
check_patches $PATCHREQS

exit 0
