# checkinstall script to control a patch installation.
# directory format options.
#
#       @(#)checkinstall 1.8 02/02/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.
#

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

#
# Since this script is called from the delivery medium and we may be using
# dot extensions to distinguish the different patch packages, this is the
# only place we can, with certainty, trace that source for our backout
# scripts. (Usually $INST_DATADIR would get us there).
#
echo "SCRIPTS_DIR=`dirname $0`" >> $1

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

#XXXSpecial_CommandsXXX#
#!/bin/sh
#
# xdent X(#)checkinstall        1.9     00/06/23 SMI
#
# Copyright 2000 by Sun Microsystems, Inc.
# All rights reserved.
#
OS=Solaris
sparc_VERSIONS="2.6 7 8"
i386_VERSIONS="7 8"
sparc_SUPPORT="$OS 2.6, 7 and 8"
i386_SUPPORT="$OS 7 and 8"

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

#
# Patch requirements, we refuse to install if these are not met.
#
# ssd(7d) patches are required on Solaris 2.6 thru 8 to resolve device id
# problems on T3 storage.
#
# Solaris 7 KU is required for taskq support.
#
# Future versions of AP may require qfe(7d) patches on Solaris 2.6
# and 7 to support automatic network failover.
#
#PATCHREQS_2_6="SUNWssadv:105356-15 SUNWqfed:106532-02"
#PATCHREQS_7="SUNWssad:107458-09 SUNWcsr:106541-02 SUNWqfed:107743-03"
PATCHREQS_2_6="SUNWssadv:105356-15"
PATCHREQS_7="SUNWssad:107458-09 SUNWcsr:106541-02"
PATCHREQS_8="SUNWssad:109524-01"

debug=yes

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

check_version()
{
        eval VERSIONS='" $'${ARCH}_VERSIONS' "'
        eval SUPPORT='"$'${ARCH}_SUPPORT'"'
        for v in $VERSIONS
        do
                if [ $VERSION = $v ]
                then
                        return
                fi
        done
        decho "This package only supports $SUPPORT on $ARCH platforms."
        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 , ' '`
                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`
        decho "Required patches not installed: $missing"
        if [ -f $OVERRIDE ]
        then
                decho "Ignoring requirements and proceeding anyway..."
                return 0
        fi
        apvers=`echo $SUNW_PRODVERS | cut -f1 -d/`
        decho "###"
        decho "### Patch verification failed."
        decho "### Alternate Pathing $apvers requires this package."
        decho "### You MUST apply the required patches before"
        decho "### proceeding."
        decho "###"
        decho "###  PACKAGE INSTALLATION FAILED."
        decho "###"
        exit 3
}

determine_version()
{
        VERSION=`uname -r`
        case "$VERSION" in
        5.[0-6]*)
            VERSION=`echo $VERSION | sed -e 's/^5./2./'`
            ;;

        5.*)
            VERSION=`echo $VERSION | sed -e 's/^5.//'`
            ;;
        esac

        # 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
            INST_RELEASE=${PKG_INSTALL_ROOT}/var/sadm/softinfo/INST_RELEASE
            if [ -f $INST_RELEASE ]
            then
                . $INST_RELEASE
                # INST_RELEASE didn't get drop the 2.x until Solaris 8
                if [ "$VERSION" = "2.7" ]
                then
                    VERSION=7
                fi
            else
                echo "WARNING: $INST_RELEASE file not found."
                echo "         Assuming install and target are the same."
            fi
        fi
        # 
        # We can't use "." in variable names
        #
        VERSION_SUFFIX=`echo $VERSION | sed -e 's/\./_/'`
}

if [ -n "${PKG_INSTALL_ROOT}" ]
then
        reloc="-R ${PKG_INSTALL_ROOT}"
fi

determine_version

decho "Determining patch requirements..."
eval PATCHREQS=\$PATCHREQS_${VERSION_SUFFIX}

check_version

# At this point, we know the target OS, so set up to install it.
case "$VERSION" in
2.6)    echo CLASSES=none sol6 >> $1
        echo S6DIR=$BASEDIR >> $1
        ;;
7)      echo CLASSES=none sol7 >> $1
        echo S7DIR=$BASEDIR >> $1
        ;;
8)      echo CLASSES=none sol8 >> $1
        echo S8DIR=$BASEDIR >> $1
        ;;

        # we should never get here
*)      echo "Internal version check inconsistency."
        exit 3
        ;;
esac

#check_patches $PATCHLIST
check_patches $PATCHREQS

echo "Installing $OS $VERSION package."
exit 0

