# This script deletes the used backout data for a patch package
# and removes the deletes file entries.
#
# directory format options.
#
#       @(#)patch_postinstall 1.3 98/07/29 SMI
#
# Copyright (c) 1995 by Sun Microsystems, Inc.
# All rights reserved
#

PATH=/usr/sadm/bin:$PATH
THIS_DIR=`dirname $0`

Our_Deletes=$THIS_DIR/deletes

#
# Delete the used backout data
#
if [ -f $Our_Deletes ]; then
	cat $Our_Deletes | while read path; do
		if valpath -l $path; then
			Client_Path=`echo "$CLIENT_BASEDIR/$path" | sed "s|//|/|"`
		else	# It's an absolute path
			Client_Path=$path
		fi
		rm `removef $PKGINST $Client_Path`
	done
	removef -f $PKGINST

	rm $Our_Deletes
fi

#
# Remove the deletes file, checkinstall and the postinstall
#
rm -r $PKGSAV/$ACTIVE_PATCH
rm -f $THIS_DIR/checkinstall $THIS_DIR/postinstall

#!/usr/bin/sh
set -x
#
# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# pragma ident "%W% %E% Sun Microsystems"
#
# This file is not part of this package but is to be integrated into
# the patch_postinstall script for this package when this package is
# contained in a patch. This script is invoked when a patch is rolled
# back.  This addition to that script manipulates the same /usr/java and
# /usr/jdk/jdk<version> symbolic links as the package scripts.
# It needs to be delivered whenever it changes to the patch production
# folk and needs to be first delivered when the 1.5.0_01 Update Release
# is produced as a Solaris style patch.
#
# Don't be confused by the name.  This script is to be run at the time
# a patch is rolled back (which sounds more like remove than install),
# but it mimics the actions of the installation script for the version
# being rolled back to.
#
# The script reverts the version number of the /usr/jdk/jdk<version>
# symbolic link to correctly identify the version being reverted to
# should the patch be rolled back. It also keeps the /usr/java
# symbolic link consistent if the link in /usr/jdk being modified
# was the target of the /usr/java symbolic link.
#
# This script assumes BASEDIR and SUNW_PRODVERS are in the environment...
#

#
# The following commands are defined as shell variable so that they can
# be redefined (as below) to place this script in a mode such that it
# will tell you what it would do, without actually modifying the system.
# Only commands which modify the system should be so aliased.
#
LN="ln"
RM="rm"

#
# For development purposes, one might consider uncommenting the following
# lines.  The result is a script which will tell you what it would do
# without actually doing anything.
#
# LN="echo ln"
# RM="echo rm"

#
# Locations and name definitions:
#
PRODVERS=`echo ${SUNW_PRODVERS} | sed -e "s/\/.*//"`
PRODVERS_NP=`echo ${PRODVERS} | sed -e "s/_.*//"`

PREFIX="jdk"

REGISTRY_DIR="jdk"
REGISTRY_PATH="${BASEDIR}/${REGISTRY_DIR}"
REGISTRY_ENTRY="${PREFIX}${PRODVERS}"
REGISTRY_NAME="${REGISTRY_PATH}/${REGISTRY_ENTRY}"

INSTALL_DIR="instances"
INSTALL_PATH="${REGISTRY_PATH}/${INSTALL_DIR}"
INSTALL_ENTRY="${PREFIX}${PRODVERS_NP}"
INSTALL_NAME="${INSTALL_PATH}/${INSTALL_ENTRY}"

JAVA_PATH="${BASEDIR}/java"
LATEST_PATH="${REGISTRY_PATH}/latest"

#
# ExpandPrefix ( release )
#
# These two shell routines expand JVM release identifier prefixes to the
# full, four element tuple.  ExpandPrefix zero extends as per JSR 56.
# ExpandPrefixInfinity extends with essentially infinite values.
#
# Parameters:
#   $1	release		Partial or complete release name tuple.
#
ExpandPrefix() {
    echo $1 | sed -e "s/_/\./g" | \
      awk '{FS="."; printf "%d.%d.%d_%.2d\n", $1, $2, $3, $4}'
}

#
# GetRel ( filename )
#
# A little utility routine to strip viable prefixes from release names.
# Note that this only works for release names by Sun convention, not the
# whole, generalized JSR 56 name set.
#
# The current and legacy prefixes are:
#	jdk (default for these packages)
#	jre
#	j2re
#	j2sdk
#
# Parameters:
#   $1	filename	Filesystem filename
#
# Returns:
#	Version portion of the file name.
#
GetRel() {
    if [ "`echo $1 | cut -c 1-3`" = "jdk" ]; then
	echo $1 | cut -c 4-
    elif [ "`echo $1 | cut -c 1-3`" = "jre" ]; then
	echo $1 | cut -c 4-
    elif [ "`echo $1 | cut -c 1-4`" = "j2re" ]; then
	echo $1 | cut -c 5-
    elif [ "`echo $1 | cut -c 1-5`" = "j2sdk" ]; then
	echo $1 | cut -c 6-
    else
	echo $1
    fi
}

#
# RelCmp ( rel1 rel2 )
#
# Styled as much as possible after strcmp, this routine returns one of the
# strings "lt", "eq", or "gt" based on the relationship of the two release
# version identifier strings passed as parameters. The sort is done only
# on the first four fields (Major, Minor, Micro, Patch).  Internal identifiers
# beyond that are ignored and releases differing only in the internal
# identifier will compare as equal.
#
# Parameters:
#   $1	rel1		Release identifier
#   $2	rel2		Release identifier
#
# Returns:
#	"lt", "eq", or "gt" based on the relationship of the two releases
#
RelCmp() {
    r1=`echo $1 | sed -e "s/-.*//" -e "s/_/\./g"`
    r2=`echo $2 | sed -e "s/-.*//" -e "s/_/\./g"`
    if [ "$r1" = "$r2" ]; then
	echo "eq"
    else
	lrel=`printf "%s\n%s\n" ${r1} ${r2} | \
	      sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n | \
	      head -1`

	if [ "$r1" = "$lrel" ]; then
	    echo "lt"
	else
	    echo "gt"
	fi
    fi
}

#
# Select ( "least"|"greatest" list )
#
# From the list of file system objects passed in, return the "greatest"
# or "least" depending upon the text flag passed in $1.  The ordering
# is determined by the rules documented in JSR 56 (Appendix A).
# However, this implementation is limited to identifiers which follow the
# Sun conventions for release and directory naming.
#
# Parameters:
#   $1	flag		"least"|"greatest" to control the selection.
#   $2	list		List of potential file system identifiers.
#
# Returns:
#	The selected file system identifier.
#
Select() {
    if [ "$2" = "" ]; then
	return
    fi

    tlist=
    for dir in $2; do
	rel=`GetRel $dir`
	rel=`ExpandPrefix $rel | sed -e "s/[\._-]/ /g"`
	tlist=`printf "%s %s\n%s" "${rel}" "${dir}" "${tlist}"`
    done
    if [ "$1" = "least" ]; then
	printf "%s\n" "${tlist}" | \
	    sort -k 1,1n -k 2,2n -k 3,3n -k 4,4n | \
	    head -1 | \
	    cut -d " " -f 5
    else
	printf "%s\n" "${tlist}" | \
	    sort -k 1,1n -k 2,2n -k 3,3n -k 4,4n | \
	    tail -1 | \
	    cut -d " " -f 5
    fi
}

#
# NewLatest
#
# Determining the correct algorithm to apply for setting the "latest"
# link isn't as obvious as it might seem. The complication is due to
# package removal.  If the "latest" is being removed, you want to set
# the "latest" link to something else.  The trouble is, if that something
# else wasn't put there via pkgadd (a tar ball for example) or simply
# predates the creation of this interface, absolutely nothing will
# happen on that removal and the link will be left dangling.
#
# There is no complete solution for this, but following algorithm
# limits the problem area to systems where some installs happened
# via packages and other installs by tar archives - in other words,
# an edge condition in a rare senario.
#
# On installation:
#
#	if <"latest" doesn't exist, or points to something older> then
#		set latest to point at the instance being installed
#
# On removal:
#
#	scan the registry for the most recent of the remaining JVMs
#	if <the most recent remaining is >= 1.5.0_01> then
#		set the link to point to the most recent remaining
#	else
#		remove the link
#	fi
#
# 1.5.0_01 is significant, because that is the first jvm which will
# manipulate this link, and hence, won't leave it dangling should it
# be removed.  The algorithm could be modified to carry back as far
# as 1.4.2_05, with the only downside being the potential for dangling
# links.  Carrying it back beyond this would be a nightmare, because
# a not-so-obvious part of the semantic of "latest", is that it is
# Multiple JRE enabled.
#
NewLatest() {

    #
    # We know the old link will be removed.  Let's do that first.
    #
    ${RM} -f ${LATEST_PATH}

    #
    # Begin by generating the list of possible JREs from the system
    # repository (/usr/jdk).
    #
    list=""
    for path in `ls -d ${REGISTRY_PATH}/jdk* ${REGISTRY_PATH}/jre* \
      ${REGISTRY_PATH}/j2sdk* ${REGISTRY_PATH}/j2re*  2>/dev/null`; do
	if [ ! -d $path -a ! -h $path ]; then
	    continue
	fi
	if [ ! -x ${path}/bin/java ]; then
	    continue
	fi
	entry=`basename $path`
#	if [ "$entry" = "${REGISTRY_ENTRY}" ]; then
#	    continue
#	fi
	list="$list $entry"
    done

    #
    # If there are alternatives, find the most advanced (dare I say
    # "latest"?) JVM from among the possibilities.  As per the algorithm
    # description above, set the "latest" link to point the the JVM
    # selected above, iff that JVM is 1.5.0_01 or later.
    #
    if [ "$list" != "" ]; then
	latest=`Select "greatest" "$list"`
	latest_tuple=`GetRel $latest`
	latest_tuple=`ExpandPrefix $latest_tuple`
	if [ "`RelCmp $latest_tuple 1.5.0_01`" != "lt" ]; then
	    ${LN} -s $latest ${LATEST_PATH}
        fi
    fi
    return 0
}

#
# Main processing starts here.
#
# Determine the target of the /usr/java symbolic link.  If its either
# non-existant or not a symbolic link, ignore it.
#
if [ -h ${JAVA_PATH} ]; then
    ls=`ls -l ${JAVA_PATH}`
    java_target=`echo $ls | cut -f 11 -d " "`
else
    java_target=""
fi

#
# Workaround for 6257396, installing patches on zones
# 
# If ${REGISTRY_PATH} isn't writeable, there's nothing to
# be done by this script, exit.
#

/usr/bin/touch ${REGISTRY_PATH}/.path.$$ > /dev/null 2>&1
if [ $? !=  0 ]; then
	exit 0
fi
${RM} -f ${REGISTRY_PATH}/.path.$$

#
# Find all symbolic links of the expected jdk<version> form which point
# to the actual instance of the JVM being "rolled back".  Remove them
# (all but one was a lie anyway). If you find one which was the target
# of the /usr/java symbolic link, set it to the "correct" link which
# will be created later.
#
for path in `ls -d ${REGISTRY_PATH}/${PREFIX}${PRODVERS_NP}*`; do
    ls=`ls -l $path`
    if [ -h $path ]; then
	entry=`basename $path`
	ls=`ls -l $path`
	target=`echo $ls | cut -f 11 -d " "`
	if [ "$target" = "${INSTALL_DIR}/${INSTALL_ENTRY}" ]; then
	    ${RM} $path
	    if [ "$java_target" = "${REGISTRY_DIR}/$entry" ]; then
		${RM} ${JAVA_PATH}
		${LN} -s ${REGISTRY_DIR}/${REGISTRY_ENTRY} ${JAVA_PATH}
	    fi
	fi
    fi
done

#
# This is later.  Create a symbolic link in /usr/jdk which correctly
# identifies the version which now resides in the instances directory.
#
if [ ! -h ${REGISTRY_NAME} ]; then
    ${LN} -s ${INSTALL_DIR}/${INSTALL_ENTRY} ${REGISTRY_NAME}
fi

#
# Unconditionally reset the "latest" symbolic link.  It may end up being
# reset to the value it used to have.
#
NewLatest

exit 0
