#!/bin/sh
#
# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# pragma ident "@(#)postcommon	1.4 04/06/03 Sun Microsystems"
#
# This file contains shell routines common to both the postinstall and
# postremove scripts for the core j2se package (rt).  The postinsall and
# postremove are built by concatinating the the specific portion to this
# common portion.
#
# Backported from Tiger (1.5) postcommon  1.7 04/03/02"
# Support for Gnome Icon installation removed.
#
# 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.
#
INSTALLF="installf"
RM="rm"
LN="ln"
CP="cp"
MKDIR="mkdir"

#
# 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.
#
# INSTALLF="echo installf"
# RM="echo rm"
# LN="echo ln"
# CP="echo cp"
# MKDIR="echo mkdir"
#

if [ "$PKG_INSTALL_ROOT" != "" ]; then
    INSTALLF="$INSTALLF -R ${PKG_INSTALL_ROOT}"
fi
PRODVERS=`echo $SUNW_PRODVERS | sed -e "s/\/.*//"`
PREFIX="j2sdk"

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

INSTALL_DIR=""
INSTALL_PATH="${BASEDIR}"
INSTALL_ENTRY="j2se"
INSTALL_NAME="${INSTALL_PATH}/${INSTALL_ENTRY}"

J2SE_PATH="${BASEDIR}/j2se"
JAVA_PATH="${BASEDIR}/java"
BIN_PATH="${BASEDIR}/bin"
BIN_JAVA="${BIN_PATH}/java"
BIN_JAVAWS="${BIN_PATH}/javaws"

JAVA_LINK_VALUE="${REGISTRY_DIR}/${REGISTRY_ENTRY}"

#
# This is the final desired (preferred) location.  1.4.2 doesn't have
# it.  It only has /jre/javaws/javaws.
#
REL_JAVAWS="bin/javaws"

#
# It should be the case that if you have this, you also have /bin/javaws.
# Unfortunately, a few internal builds only had this.  This can probably
# go away.  (See 495493)
#
REL_JAVAWS_GOOFY="jre/bin/javaws"

#
# See PSARC/2003/091: 1.4.2 shipped with this "official" location for
# javaws.  Until 1.4.2 is deader than a doornail, we need this extra
# location.
#
REL_JAVAWS_OLD="jre/javaws/javaws"

#
# "Global variables" which (if set) reflect the minimum and maximum j2se
# releases expected to be the default on the underlying host release of
# Solaris.  These are fully expanded tuples.
DEFAULT_MIN=
DEFAULT_MAX=

#
# FollowLink ( link )
#
# Given a symbolic link, follow that link until it doesn't point a symbolic
# link.  Sequences such as "/foo/../" and "/./" are simplified.
#
# Parameters:
#  $1	link		Link name
#
FollowLink() {
    link=$1
    while [ -h $link ]; do
        ls=`ls -l $link`
        link=`dirname $link`/`echo $ls | cut -f 11 -d " "`
        echo $link | grep "\/\.\/" 2>/dev/null >/dev/null
        while [ $? = 0 ]; do
            link=`echo $link | sed -e s"/\/\.\//\//g"`
            echo $link | grep "\/\.\/" 2>/dev/null >/dev/null
        done
        echo $link | grep "[^\/]*\/\.\.\/" 2>/dev/null >/dev/null
        while [ $? = 0 ]; do
            link=`echo $link | sed -e s"/[^\/]*\/\.\.\///g"`
            echo $link | grep "[^\/]*\/\.\." 2>/dev/null >/dev/null
        done
        link=`echo $link | sed -e "s/^\.\///g"`
    done
    echo "$link"
    return 0
}

#
# GetHostRelease ()
#
# The use of /var/sadm/system/admin/INST_RELEASE is allowed by PSARC/2001/472.
# We fallback to the use of uname should this file not exist, but that may
# give the wrong answer for diskless server installations.  Fortunately, the
# absence of the INST_RELEASE file is a "should never happen" situation,
# except for internal development where it happens all the time, but then
# uname does yield the right answer.
#
# Unfortunately, the format of the VERSION identifier has changed over time
# as "Solaris 2.X" became marketed as simply "Solaris X".  Hence we need
# to allow for both the "2.X" and simply "X" forms.
#
# This returns the simple "X" that is the Minor release by the taxonomy.
#
GetHostRelease() {
    if [ -f $PKG_INSTALL_ROOT/var/sadm/system/admin/INST_RELEASE ]; then
	ver=`grep '^VERSION=' \
	  $PKG_INSTALL_ROOT/var/sadm/system/admin/INST_RELEASE`
    else
	ver=`uname -r`
    fi
    ver=`echo $ver | sed -e "s/[^0-9]*//" -e "s/[^0-9\.].*//"`
    echo $ver | grep -s "[0-9]*\.[0-9]*" > /dev/null
    if [ $? = 0 ]; then
	ver=`echo $ver | sed -e "s/[0-9]*\.//"`
    fi
    echo $ver
}

#
# ExpandPrefix ( release )
# ExpandPrefixInfinity ( 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}'
}

ExpandPrefixInfinity() {
    echo $1 | sed -e "s/_/\./g" | \
      awk '{FS="."; \
	if ($1 == "") major=9999; else major=$1; \
	if ($2 == "") minor=9999; else minor=$2; \
	if ($3 == "") micro=9999; else micro=$3; \
	if ($4 == "") patch=9999; else patch=$4; \
	printf "%d.%d.%d_%.2d\n", major, minor, micro, patch}'
}

#
# GetDefaultRange ()
#
# Determines the range of J2se releases acceptable as the default on the
# host version of Solaris.
#
GetDefaultRange() {
    if [ -f $PKG_INSTALL_ROOT/etc/default/default_java ]; then
	. $PKG_INSTALL_ROOT/etc/default/default_java
    elif [ -f $PKG_INSTALL_ROOT/var/sadm/system/admin/default_java ]; then
    	. $PKG_INSTALL_ROOT/var/sadm/system/admin/default_java
    fi
    if [ "$DEFAULT_MIN" = "" ]; then
	release=`GetHostRelease`
	case $release in
	    5 | 6 | 7 )
		DEFAULT_MIN=1.1
		;;
	    8 )
		DEFAULT_MIN=1.2
		;;
	    9 )
		DEFAULT_MIN=1.4
		;;
	    10 )
		DEFAULT_MIN=1.5
		;;
	    * )
		;;
	esac
    fi
    if [ "$DEFAULT_MAX" = "" ]; then
	DEFAULT_MAX=$DEFAULT_MIN
    fi
    DEFAULT_MIN=`ExpandPrefix $DEFAULT_MIN`
    DEFAULT_MAX=`ExpandPrefixInfinity $DEFAULT_MAX`
    return 0
}

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

#
# GetMicro ( release )
#
# Extracts the Micro (dot-dot) version identifier from a Solaris JRE
# release identifier.  This is the entire release identifier ('X.Y.Z',
# not just 'Z'). Prefix specifications are zero extended.
#
# Parameters:
#   $1	release		release identifier
#
# Returns:
#	The Micro release portion of the release identifier.
#
GetMicro() {
    echo `echo $1 | sed -e "s/[-_].*//" | \
      awk '{FS="."; printf "%s.%s.%s", $1, $2, $3}'`
}

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

#
# InRange ( low_bound release high_bound )
#
# Determines if the release identifier ($2) lies between the low bound ($1)
# and the high bound ($3) inclusive.  The release identifiers must be full
# expanded tuples.
#
# Parameters:
#   $1	low_bound	Lowbound of the release range (inclusive).
#   $2	release		Release to be checked.
#   $3	high_bound	Highbound of the release range (inclusive).
#
# Returns:
#   0	(success) is the release identifier is in range.
#   1	(failure) is the release identifier is out of range.
#
InRange() {
    if [ "$2" = "" ]; then
	return 1
    fi

    low=`echo "$1" | sed -e "s/[\._-]/ /g"`
    rel=`echo "$2" | sed -e "s/[\._-]/ /g"`
    hi=`echo "$3" | sed -e "s/[\._-]/ /g"`
    mid=`echo "${low}\n${rel}\n${hi}" | \
        sort -k 1,1n -k 2,2n -k 3,3n -k 4,4n | \
        head -2 | \
        tail -1`
    mid=`echo $mid | awk '{FS=" "; printf "%d.%d.%d_%.2d\n", $1, $2, $3, $4}'`
    if [ "$2" = "$mid" ]; then
	return 0
    else
	return 1
    fi
}
#
# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# pragma ident "@(#)postinstall	1.49 04/06/03 Sun Microsystems"
#
# Backported from Tiger (1.5) postinstall 1.56 04/03/05
# Gnome and "Shared Classes" support removed.
#
# The JRE package installs links outside of its BASEDIR from "utilities"
# in /usr/bin, up to the /usr/java link which (in turn) points to the
# default JVM. This script installs these links which are independent
# of BASEDIR.
#
# The current system default is determined by the setting of the /usr/java
# symbolic link.
#
# In general, the newly installed jre/sdk should make itself the system
# default iff:
#
#	There is no current system default or it appears to be corrupt.
#
#	The current default is outside of the range of expected defaults
#	for the underlying release of Solaris and this package is within
#	that range.
#
# The single exception to this algorithm is if the version being installed
# is a more recent patch within the the same Micro release family as the
# current default, then the version being installed shall make itself the
# default. The rough translation of this is "patches are patches".
#

#
# InstallLinks ( default_flag )
#
# Shell routine to install the /usr/bin links. Note that we want to register
# these as part of each package which uses them, so that they won't be
# removed until the last Java is removed from the system (or the last Java
# which has that particular component.
#
# Parameters:
#   $1	default_flag	"true" if this package is being installed as the
#			Solaris system default, "false" otherwise.
#
InstallLinks() {

    $INSTALLF -c none $PKGINST $BIN_PATH d 0755 root bin

    BIN_FILES="java keytool policytool rmid rmiregistry tnameserv \
      orbd servertool"
    for file in $BIN_FILES; do
	$INSTALLF -c none $PKGINST "$BIN_PATH/${file}=../java/bin/${file}" s
    done

    JRE_BIN_FILES="ControlPanel"
    for file in $JRE_BIN_FILES; do
	$INSTALLF -c none $PKGINST "$BIN_PATH/${file}=../java/jre/bin/${file}" s
    done

    #
    # IMPORTANT NOTE: Special handling for the /usr/bin/javaws symbolic
    # link. See PSARC/2003/091.
    #
    # If this version is being made the default, force the link to the
    # "normal" form.  If not, see if the current setting of the link
    # points at a valid javaws executable. If it doesn't, point it at
    # this installation, but only if this is being installed in the
    # default /usr/jdk directory.
    #
    #	if ("the package being installed will be the default") then
    #	    [Re]Create the link through /usr/java.
    #	else if ("/usr/bin/javaws doesn't exist") then
    #	    Create the link to point directly to this package
    #	else if ("it is a link and is 'dangling'") then
    #	    Create the link to point directly to this package
    #	endif
    #
    # Note that it is not a bug that /usr/bin/javaws isn't registered with
    # the package data base (via installf).
    #
    if [ "$1" = "true" ]; then
	${RM} -f ${BIN_JAVAWS}
	${LN} -s ../java/${REL_JAVAWS_OLD} ${BIN_JAVAWS}
    elif [ ! -f ${BIN_JAVAWS} ] && [ ! -d ${BIN_JAVAWS} ] && \
	 [ ! -h ${BIN_JAVAWS} ]; then 
	${RM} -f ${BIN_JAVAWS}
	${LN} -s ../${REGISTRY_DIR}/${REGISTRY_ENTRY}/${REL_JAVAWS_OLD} \
	  ${BIN_JAVAWS}
    elif [ -h ${BIN_JAVAWS} ]; then
	target=`FollowLink ${BIN_JAVAWS}`
	if [ ! -x $target ]; then
	    ${RM} -f ${BIN_JAVAWS}
	    ${LN} -s ../${REGISTRY_DIR}/${REGISTRY_ENTRY}/${REL_JAVAWS_OLD} \
	      ${BIN_JAVAWS}
        fi
    fi
}

#
# Shell routine to install the /usr symbolic link of /usr/java.
#
# Note that it is not a bug that /usr/java isn't registered with
# the package database. Multiple instances will each have there own
# idea of what this link value should be, so (to avoid pkgchk warnings)
# all manipulation is done via postinstall and postremove scripts.
#
# Returns:
#	zero:		The link was created or altered.
#	non-zero:	The link was not altered
#
SetJavaLink() {

    #
    # If there is nothing there just create a link to this instance.
    #
    if [ ! -f ${JAVA_PATH} ] && [ ! -d ${JAVA_PATH} ] &&
       [ ! -h ${JAVA_PATH} ]; then
	${RM} -f ${JAVA_PATH}
	${LN} -s ${JAVA_LINK_VALUE} ${JAVA_PATH}
	return 0
    fi

    #
    # If there is something there but its not a symbolic link, leave it
    # alone.  Funky things have been done to this system which we had better
    # not muck with.
    #
    if [ ! -h ${JAVA_PATH} ]; then
	return 1
    fi

    #
    # It exists and is a symbolic link.  Possibly we want to do something
    # with it
    #
    # First, resolve what it (and any subsequent links) point to.
    path=`FollowLink ${JAVA_PATH}`

    #
    # If it is 'dangling' (points to something that is no longer a valid
    # JVM, or perhaps never was), take it over.  The simplistic test is for
    # an executable object called "java" at the expected path relative to
    # the final destination of this link.
    #
    if [ ! -x ${path}/bin/java ]; then
	${RM} -f ${JAVA_PATH}
	${LN} -s ${JAVA_LINK_VALUE} ${JAVA_PATH}
	return 0
    fi

    #
    # Getting this far, indicates that the symbolic link exists and points
    # to something which is very likely to be a valid JVM.
    #
    # SPECIAL CODE FOR 1.4.2_05 PATCH.  This is generally inappropriate,
    # but required to maintain the exact 1.4.x install semantics in a
    # patch.
    #
    # Since prior to 1.4.2_05, all instances installed in the /usr/j2se
    # directory, you always got the last 1.4.x version installed.  Hence,
    # always steal the link if it points to /usr/j2se.
    #
    if [ "${path}" = "${USR_J2SE}" ]; then
	${RM} -f ${JAVA_PATH}
	${LN} -s ${JAVA_LINK_VALUE} ${JAVA_PATH}
	return 0
    fi

    #
    # If the current default is out side of the default range for the
    # Solaris release and the release being installed is within the
    # default range, steal the link.
    #
    # Note that we can't tell the exact version of JVM release found
    # in the legacy directories of /usr/java1.1, /usr/java1.2, or
    # /usr/j2se.  We can only assume the Minor release family found there.
    # Be conservative and assume that the JVM installed there is the most
    # advanced within that family.
    #
    GetDefaultRange
    current_dir=`basename $path`
    if [ "$current_dir" = "j2se" ]; then
	current_tuple=`ExpandPrefixInfinity 1.4`
    elif [ "$current_dir" = "java1.2" ]; then
	current_tuple=`ExpandPrefixInfinity 1.2`
    elif [ "$current_dir" = "java1.1" ]; then
	current_tuple=`ExpandPrefixInfinity 1.1`
    else
	current_tuple=`GetRel $current_dir`
	current_tuple=`ExpandPrefix $current_tuple`
    fi
    prodver_tuple=`ExpandPrefix $PRODVERS`
    if [ \( "`RelCmp $current_tuple $DEFAULT_MIN`" = "lt" -o \
	    "`RelCmp $current_tuple $DEFAULT_MAX`" = "gt" \) -a \
	 \( "`RelCmp $prodver_tuple $DEFAULT_MIN`" != "lt" -a \
	    "`RelCmp $prodver_tuple $DEFAULT_MAX`" != "gt" \) ]; then
	${RM} -f ${JAVA_PATH}
	${LN} -s ${JAVA_LINK_VALUE} ${JAVA_PATH}
	return 0
    fi

    #
    # Subsequent tests for acquiring the link depend upon both the
    # current owner and this package being referenced through the
    # /usr/jdk directory. We know this is true for this package.
    # If this isn't true for the existing default, bail out.
    #
    ls=`ls -l ${JAVA_PATH}`
    target=`echo $ls | cut -f 11 -d " "`
    link=`dirname ${JAVA_PATH}`/`dirname $target`
    link=`echo $link | sed -e "s:/\./:/:g" -e "s:[^/]*/\.\./::g"`
    if [ "$link" != "${REGISTRY_PATH}" ]; then
	return 1
    fi
    target=`basename $target`
    current_tuple=`GetRel $target`

    #
    # Finally, if the link points to a release in the same Micro (dot-dot)
    # family, but of a lower patch level, take over the link.
    #
    if [ "`GetMicro $prodver_tuple`" = "`GetMicro $current_tuple`" ]; then
	if [ "`RelCmp $prodver_tuple $current_tuple`" = "gt" ]; then
	    ${RM} -f ${JAVA_PATH}
	    ${LN} -s ${JAVA_LINK_VALUE} ${JAVA_PATH}
	    return 0
	fi
    fi

    return 1
}

#
# Main Processing
#

#
# If this is being installed in its natural location (/usr/j2se),
# set this up as a player with the Multiple JRE framework.
#
# Add a link containing the full version from the "registry" directory to
# the "instances" directory.  Also, remove any other symbolic links from
# the "instances" directory which may now be lies.
#
if [ -d ${BIN_PATH} ]; then
    $INSTALLF -c none $PKGINST "${REGISTRY_PATH}" d 755 root bin
    for path in `ls -d ${REGISTRY_PATH}/jdk* ${REGISTRY_PATH}/jre* \
      ${REGISTRY_PATH}/${PREFIX}* ${REGISTRY_PATH}/j2re* 2>/dev/null`; do
	if [ -h $path ]; then
	    target=`FollowLink $path`
	    if [ "$target" = "../j2se" ]; then
		${RM} $path
	    fi
	fi
    done
    ${LN} -s ../j2se ${REGISTRY_NAME}
fi

#
# If this package should become the system default, make it so by
# creating/modifying the /usr/java symbolic link.
#
# Only consider establishing this link if this is being installed
# as a "system" JRE/JDK. Typically, this would be if BASEDIR has
# its default value of /usr.  However, diskless installations make
# this a bit more difficult to assertain, so hieristic of $BASEDIR
# containing a "bin" directory is applied.  This hieristic is ideal
# because even if it incorrectly identifies a "system" installation,
# it will generate a sensible and expected result.
#
if [ -d ${BIN_PATH} ]; then
    if `SetJavaLink`; then
	InstallLinks "true"
    else
	InstallLinks "false"
    fi
fi

#
# Commit
#
$INSTALLF -f $PKGINST
exit 0
