# 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#

#------------------------------------------------------------
# Make sure that there is a ksh or bash shell
#------------------------------------------------------------

if [ ! -x $PKG_INSTALL_ROOT/usr/bin/ksh ]; then
	if [ ! -x $PKG_INSTALL_ROOT/bin/ksh ]; then
		if [ ! -x $PKG_INSTALL_ROOT/usr/bin/bash ]; then
			echo "Error: Can't find an appropriate shell that will be needed to"
			echo "       execute the configure script. No ksh found in either"
			echo "       $PKG_INSTALL_ROOT/bin or"
			echo "       $PKG_INSTALL_ROOT/usr/bin,"
			echo "       and no bash found in"
			echo "       $PKG_INSTALL_ROOT/usr/bin."
			exit 3
		fi
	fi
fi


#------------------------------------------------------------
# Make sure that the dependant packages are correct versions
#------------------------------------------------------------

########## Package version definitions ##########

os_version=`uname -r | cut -d . -f 2`
arch_version=`uname -p`

nss_package="SUNWtls"
nss_version="3.9.5"
nss_base_version="3.3.2"

nspr_package="SUNWpr"
nspr_version="4.5.1"
nspr_base_version="4.1.2"

if [ $os_version = "8" ]; then
	if [ $arch_version = "sparc" ]; then
		nss_base_patch="117722-10"
		nspr_base_patch="117722-10"
	elif [ $arch_version = "i386" ]; then
		nss_base_patch="117725-10"
		nspr_base_patch="117725-10"
	else
		echo "Error: This $PKG package is only supported on sparc and i386 hardware."
		exit 3
	fi
elif [ $os_version = "9" ]; then
	if [ $arch_version = "sparc" ]; then
		nss_base_patch="117724-10"
		nspr_base_patch="117724-10"
	elif [ $arch_version = "i386" ]; then
		nss_base_patch="117725-10"
		nspr_base_patch="117725-10"
	else
		echo "Error: This $PKG package is only supported on sparc and i386 hardware."
		exit 3
	fi
elif [ $os_version -gt 9 ]; then
	# Solaris 10 ships with nss version 3.9.5 and nspr version 4.5.1
	nss_base_patch=""
	nspr_base_patch=""
else
	echo "Error: This $PKG package is only supported on versions of Solaris 8 or greater."
	exit 3
fi

nssutil_package="SUNWtlsu"

ldap_package="SUNWldk"
ldap_version="5.11"

sasl_package="SUNWsasl"

icu_package="SUNWicu"

nova_package="SUNWktse"

nsprdev_package="SUNWprd"

zlib_package="SUNWzlib"

package_list="$nss_package $nssutil_package $nspr_package $ldap_package $sasl_package $icu_package $nova_package $nsprdev_package $zlib_package"


########## First make sure the required packages have been installed ##########

missing_packages=""

for each_package in $package_list
do
	pkginfo -q $each_package
	if [ $? -ne 0 ]; then
		missing_packages="$missing_packages $each_package"
	fi
done

if [ -n "$missing_packages" ]; then
	echo "Error: The following packages could not be found. Please"
	echo "install these packages and try this installation again."
	for each_package in $missing_packages
	do
		echo "   ---> $each_package"
	done
	exit 3
fi


########## Function to compare version strings ##########

# return value: 0 on success (correct version string or greater), 1 otherwise
compare_versions()
{
	installed_version=$1
	required_version=$2

	i=1
	for req_ver_digit in $required_version
	do
		ins_ver_digit=`echo $installed_version | cut -d. -f $i`
		if [ -z "$ins_ver_digit" -a $req_ver_digit -ne 0 ]; then
			## 3.1 is not ok if 3.1.1 is required
			## but 3.1 is ok if 3.1.0 is required
			return 1
		elif [ $ins_ver_digit -lt $req_ver_digit ]; then
			## 2.9.9, 3.1.0, etc not ok if 3.1.1 is required
			return 1
		elif [ $ins_ver_digit -gt $req_ver_digit ]; then
			## 4 or 3.2 or 3.1.2 is ok if 3.1.1 is required
			return 0
		fi

		## otherwise continue on to check next digit
		i=`expr $i + 1`
	done

	## to get here, all digits matched, e.g. 3.1.1 for 3.1.1
	return 0
}


########## Function to check for patch levels ##########

# return value: 0 on success (correct version of package and patch), 1 otherwise
check_for_patch()
{
	pkgname=$1
	required_patch=$2

	patch_list=`pkgparam $pkgname PATCHLIST`
	if [ -z "$patch_list" ]; then
		# error - no patches applied to the package
		return 1;
	fi

	for each in $patch_list
	do
		patchnum=`echo $each | sed 's@-.*@@'`
		required_patchnum=`echo $required_patch | sed 's@-.*@@'`
		if [ "$patchnum" = "$required_patchnum" ]; then
			patchver=`echo $each | sed 's@.*-@@'`
			required_patchver=`echo $required_patch | sed 's@.*-@@'`
			if [ $patchver -ge $required_patchver ]; then
				return 0;
			fi
		fi
	done

	# Couldn't find the correct patch
	return 1
}


########## Function to check for correct installed version ##########

check_installed_version()
{
	pkgname=$1
	required_version=`echo $2 | sed 's/_/./g' | sed 's/\./ /g'`

	if [ -n "$3" ]; then
		base_version=$3
		required_base_version=`echo $3 | sed 's/_/./g' | sed 's/\./ /g'`
	else
		base_version=""
		required_base_version=""
	fi
	if [ -n "$4" ]; then
		patch=$4
	else
		patch=""
	fi


	# First try to use the SUNW_PRODVERS string if it exists.
	#    Rip off anything after numbers, periods or underscores,
	#    then convert underscores to periods.
	orig_installed_version=`pkgparam $pkgname SUNW_PRODVERS | sed 's@\([0-9._][0-9._]*\).*@\1@'`
	installed_version=`echo $orig_installed_version | sed 's@_@.@g'`
	if [ -z "$installed_version" ]; then
		# Ok, couldn't find SUNW_PRODVERS, use VERSION
		orig_installed_version=`pkgparam $pkgname VERSION | sed 's@\([0-9._][0-9._]*\).*@\1@'`
		installed_version=`echo $orig_installed_version | sed 's@_@.@g'`
		if [ -z "$installed_version" ]; then
			echo "Unable to determine the version number of the $pkgname package" 1>&2
			exit 3
		fi
	fi

	compare_versions $installed_version "$required_version"
	ret=$?
	if [ $ret -ne 0 ]; then
		# Ok, package appears to be wrong version. Is it patched up to the correct version?
		if [ -n "$patch" ]; then
			# Do we have the right base version or higher?
			compare_versions $installed_version "$required_base_version"
			ret=$?
			if [ $ret -ne 0 ]; then
				# the package is the wrong version
				echo "The $pkgname package appears to be the wrong version ($orig_installed_version)." 1>&2
				echo "$PKG requires version $2 or higher of the $pkgname package," 1>&2
				echo "or version $base_version or higher with patch $patch or higher." 1>&2
				exit 3
			fi
			# Ok now, does it have the right patch?
			check_for_patch $pkgname $patch
			ret=$?
			if [ $ret -ne 0 ]; then
				# the appropriate patch is not there
				echo "The $pkgname package appears to not be patched sufficiently." 1>&2
				echo "$PKG requires version $orig_installed_version of the $pkgname package" 1>&2
				echo "to have patch $patch or higher, or alternatively," 1>&2
				echo "version $2 or higher of the $pkgname package." 1>&2
				exit 3
			fi
		else
			# the package is the wrong version
			echo "The $pkgname package is the wrong version ($orig_installed_version)." 1>&2
			echo "$PKG requires version $2 or higher of the $pkgname package." 1>&2
			exit 3
		fi
	fi
}

# Check version of nspr package
echo "Verifying version of $nspr_package package..."
check_installed_version $nspr_package $nspr_version $nspr_base_version $nspr_base_patch

# Check version of nss package
echo "Verifying version of $nss_package package..."
check_installed_version $nss_package $nss_version $nss_base_version $nss_base_patch

# Check version of ldap package
echo "Verifying version of $ldap_package package..."
check_installed_version $ldap_package $ldap_version

exit 0

