#!/sbin/sh
# 
# *****************************************************************
# *                                                               *
# *   Copyright 2002 Compaq Information Technologies Group, L.P.  *
# *                                                               *
# *   The software contained on this media  is  proprietary  to   *
# *   and  embodies  the  confidential  technology  of  Compaq    *
# *   Computer Corporation.  Possession, use,  duplication  or    *
# *   dissemination of the software and media is authorized only  *
# *   pursuant to a valid written license from Compaq Computer    *
# *   Corporation.                                                *
# *                                                               *
# *   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
# *   by the U.S. Government is subject to restrictions  as  set  *
# *   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
# *   or  in  FAR 52.227-19, as applicable.                       *
# *                                                               *
# *****************************************************************
#
# HISTORY
# 
# @(#)$RCSfile: patch_tools.scp,v $ $Revision: 1.1.2.11 $ (DEC) $Date: 2002/09/09 13:00:26 $
# 

. ./usr/share/lib/shell/libscp

:	- UpdateProdMap
#		dupatch with multi-product support requires a product map 
#		to display product/subset description. 
#		Since the info is not available on system with older
#		patches installed, we need to add the info before
# 		the new dupatch gets called.

UpdateProdMap ()
{
	__TMP=$_PRODMAP.tmp.$$
	cat $_KIT_PRODMAP > $__TMP
	[ -s $_PRODMAP ] && 
	{
		cat $_PRODMAP >> $__TMP
	}
	sort -u -o $__TMP $__TMP
	mv $__TMP $_PRODMAP
}


:	- HigherPatchInstalled
#		see if there is a higher patch already installed on
#		the system (both patch version and revision).
#	given:	global variables.
#	return: 0 - if there is a higher patch installed. 

HigherPatchInstalled () 
{
	# 1. check on the subset version, i.e. OSFPATrxxxxxyyVVV
	#						     ===
	SUBS=`SubsInstalled $_PCODE$_PNOREV`
	for K in $SUBS
	{
		VER=`expr $K : '.*\(...\)'`
		[ $VER -gt $_VCODE ] &&
		{
			echo "
A higher version of the patch tools, $K, is already installed.
"
			return 0
		}
	}

	# 2. check on the patch revision, i.e.  OSFPATrxxxxxyyVVV
	#						    ==
        SUBS=`(cd $_SMDB; echo OSFPAT?$_PID??$_VCODE.lk | sed 's/\.lk//g')`
        case "$SUBS" in
                *\?\?*)  return 1          # No match
        esac

        for K in $SUBS
        {
                REV=`echo $K | cut -b 13-14`
                [ $REV -gt $_PREV ] &&
                {
                      	echo "
A higher revision of the patch tools, $K, is already installed.
"
                        return 0
                }
        }

	return 1
}


:     - FixSelfLocked
#
#             fix the subsets X where X locks itself. (Bug in previous libpats/manufacturing tools)
#

FixSelfLocked ()
{
	# Find all the installed patches
	INSTALLED=`(cd $_SMDB; ls -1 | grep ...PAT.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\.lk | sed 's/\.lk//g' | sed 's/.*[\?\*].*//g')`

	for SUBSET in $INSTALLED
	{
		# Does SUBSET lock itself ?
		grep -q $SUBSET $_SMDB/$SUBSET.lk || continue
		# Fix the problem
		[ "$PATCH_DEBUG" ] &&
			echo "Fixing Lock file for $SUBSET"
		fgrep -v $SUBSET $_SMDB/$SUBSET.lk > $_SMDB/$SUBSET.lk.tmp
		mv $_SMDB/$SUBSET.lk.tmp $_SMDB/$SUBSET.lk
	}
}
:	-InvRecord
#		add an inventory record to an existing inventory file.
#	given:	a file to search for and a subset without version code to
#		search in.
#	does:	searches for a specific file in an existing inventory file and
#		adds an inventory record when the file is not found.

InvRecord()
{
	_INVRECFILE=`ls ./usr/.smdb./$2*.inv | line`

	_INVRECFOUND=`awk -v FILE=$1 '$10 ~ FILE {print $10}' $_INVRECFILE`
	[ -z "$_INVRECFOUND" ] &&
	{
		_INVRECSUB=`basename $_INVRECFILE .inv`
		_INVRECVER=`expr $_INVRECSUB : '^.*\(...\)$'`
		/usr/lbin/ils $1 | sed \
			-e "s/	010	/	$_INVRECVER	/" \
			-e "s/unknown	-\$/none	$_INVRECSUB/" \
				>> $_INVRECFILE
		sort -o $_INVRECFILE +9 $_INVRECFILE
	}
}

: -FixConfigFiles
#
# Fix V4.0E fis ./usr/sys/conf/alpha/files inventory entry
#
FixConfigFiles()
{
        # Set filename/subset and exact sum/size of file delivered from fis
        _FILE_NAME="./usr/sys/conf/alpha/files"
        _SUBSET_NAME="OSFBINCOM435"
        _FILE_SUM="38934 44 $_FILE_NAME"

        # Do nothing if V4.0E is not installed and the file is not from fis
        [ -f $_SMDB/$_SUBSET_NAME.lk ] || return 0
        _FILE_CHECK=`sum $_FILE_NAME | awk '{print $1 " " $2 " " $3}'`
        [ "$_FILE_CHECK" = "$_FILE_SUM" ] || return 0

        # Remove previous entry
        RemoveInventoryRecord $_FILE_NAME $_SUBSET_NAME

        # Add currently install file back into inventory
        echo "0 $_FILE_NAME $_SUBSET_NAME" | \
                ./usr/lbin/invcutter -v $_VERSION >> $_SMDB/$_SUBSET_NAME.inv
        sort -o $_SMDB/$_SUBSET_NAME.inv +9 $_SMDB/$_SUBSET_NAME.inv

}

: -FixMisskitFiles
#
# Fix miss kitted files in V4.0G
# Fix volatility flag in inventory for 
#
FixMisskitFiles()
{
	#
	# Fix hard linked file
	#
	[ -e $_SMDB/OSFTERM445.lk ] && {
		rm ./usr/share/lib/terminfo/w/wyse60-PC
		ln ./usr/share/lib/terminfo/i/ibmpc \
			./usr/share/lib/terminfo/w/wyse60-PC
	}

	#
	# Fix volatility flag in inventory for file
	# V4.0G
	#
	[ -e $_SMDB/OSFIMXE445.inv ] && {
		ed $_SMDB/OSFIMXE445.inv <<=EOD= >/dev/null 2>&1
/f	.*\/cpqhmmd.ini/
s/^0/2/
w
q
=EOD=
	}
	#
	# Fix volatility flag in inventory for file
	# V4.0F
	#
	[ -e $_SMDB/OSFIMXE440.inv ] && {
		ed $_SMDB/OSFIMXE440.inv <<=EOD= >/dev/null 2>&1
/f	.*\/cpqhmmd.ini/
s/^0/2/
w
q
=EOD=
	}
	#
	# Fix volatility flag in inventory for file
	# V4.0D
	#
	[ -e $_SMDB/OSFIMXE425.inv ] && {
		ed $_SMDB/OSFIMXE425.inv <<=EOD= >/dev/null 2>&1
/f	.*\/cpqhmmd.ini/
s/^0/2/
w
q
=EOD=
	}
}

: -Fixeemod
#
# Allow ee.mod in patch kit to install properly if previously installed
# via OSHHWBIN10{0-2} subset.
#
Fixeemod()
{
	#
	# Find ee.mod in OSHHWBIN10{0-2} inventory file
	# Remove it from OSHHWBIN subset and add it to OSFHWBIN440
	#
	EEREMOVED=1
	for i in 0 1 2
	do
		[ -e $_SMDB/OSHHWBIN10${i}.lk ] && {
		RemoveInventoryRecord	\
				./sys/BINARY/ee.mod OSHHWBIN10${i}
		RemoveInventoryRecord	\
				./usr/sys/BINARY/ee.mod OSHHWBIN10${i}
		EEREMOVED=$?
		}
	done
	[ $EEREMOVED = "0" ] && {
		SynchronizeInventoryRecord	\
			./sys/BINARY/ee.mod OSFHWBIN440
		SynchronizeInventoryRecord	\
			./usr/sys/BINARY/ee.mod OSFHWBIN440
	}
	# Check for ee.mod in /usr/sys/BINARY/files
	# If found remove it and make sure entry exists in 
	# /usr/sys/conf/alpha/files
	[ -e ./usr/sys/BINARY/files ] && {
	    grep -q "module ee" ./usr/sys/BINARY/files
	    RC=$?
	    [ $RC = "0" ] && {
	    # remove ee entries from /usr/sys/BINARY/files
	    egrep -v "optional ee|module ee" ./usr/sys/BINARY/files >./usr/sys/BINARY/files$$ && mv ./usr/sys/BINARY/files$$ ./usr/sys/BINARY/files

	        # check for ee entries and add if they are not present
	        grep -q "module ee" ./usr/sys/conf/alpha/files
	        RC=$?
	        [  $RC = "1" ] && {

		# ee entries not found so we add them
	echo "MODULE/STATIC/ee		optional ee device-driver Binary" \
		>>./usr/sys/conf/alpha/files
	echo "io/dec/netif/if_ee.c		module ee" \
		>>./usr/sys/conf/alpha/files

	       	# update inventory record 
	      	SynchronizeInventoryRecord	\
			./usr/sys/conf/alpha/files OSFBINCOM440
		
	      }

	  }
	}
	
}

: -Fixmcicap
#
# Change the file /etc/mcicap to /etc/.new..mcicap
#
Fixmcicap()
{
# If OSFHWBASE510 is installed then proceed.
#
# If /etc/.new..mcicap does not exist then add it to OSFHWBASE510
#
	[ -e $_SMDB/OSFHWBASE510.lk ] && {

		grep -q "/etc/.new..mcicap" $_SMDB/OSFHWBASE510.inv
		RC=$?
		[ $RC = "1" ] && {
			MCIREMOVED=1
			cp -p /etc/mcicap /etc/.new..mcicap
			echo "# " >> /etc/.new..mcicap
			RemoveInventoryRecord \
					./etc/mcicap OSFHWBASE510
			MCIREMOVED=$?
			[ $MCIREMOVED = "0" ] && {
				SynchronizeInventoryRecord \
						./etc/.new..mcicap OSFHWBASE510
			}
		}
	}
}
: -Fixmktemp
#
# Fix up the PK4 patch tools inventory for V51A.  Remove /usr/bin/mktemp from patch tools
# inventory record.
#
Fixmktemp()
{
	#
	# See if PK4 tools were installed
	# If PK4 tools are installed, then move /usr/bin/mktemp 
	# out of patch tools (patch) inventory file and add it to
	# OSFBASE inventory
	#
	NOMKTEMP=1
	[ -e $_SMDB/OSFPAT00000038520.lk ] && {
		RemoveInventoryRecord	\
			./usr/bin/mktemp OSFPAT00000038520
		NOMKTEMP=$?
		}
	[ $NOMKTEMP = "0" ] && {
		SynchronizeInventoryRecord	\
			./usr/bin/mktemp OSFBASE520
	}
	
}

: -FixSysman
FixSysman()
{
# Change owner and group of SYSMAN suitlet_help/html files to bin:bin
#
	if [ -e ./usr/.smdb./OSFSYSMAN???.lk ]; then
	 _AWK='/usr\/share\/sysman\/web\/suitlet_help\/html\/.*\.tar\.gz/ {print $10}'
 	for i in `awk "$_AWK" ./usr/.smdb./OSFSYSMAN???.inv`
 		do
   		  _TARGZDIR=`dirname $i`
   		  _TARGZFILE=`basename $i`
   		  _TARGZFILES=`basename $i .tar.gz`
   		   chown -Rh bin.bin $_TARGZDIR/$_TARGZFILES
 		done
	fi

}

: -FixPatchMember
#
# We want to ensure that the most recent /var/adm/patch/roll/patch_member
# is run on a clu_upgrade roll. In order to do this, we need to delete
# the .Old.. version of this file, if it exists (meaning the clu_upgrade
# setup was done prior to installing the patch tools).
#
# Contact: Tom Reu
#
FixPatchMember()
{
	# Look to see if a tagged version of patch_member exists
	# if it does, make it go away.
	[ -f /var/adm/patch/roll/.Old..patch_member ] &&
		rm -f /var/adm/patch/roll/.Old..patch_member
}

: -Geti2oInfo
#
# Run script to gather info for i2o
#
Geti2oInfo()
{
	#
	# Check for existence of i2o script and run it
	#
	if [ -x ./sbin/i2o/__i2o_fix ]
	then
		./sbin/i2o/__i2o_fix
	fi
}

: -Addlfa
#
# Fix atom symlinks up to receive kit
#
Addlfa()
{
        # Set subset to be modified
	_SUBSET_NAME=`basename $_SMDB/OSFHWBIN4[23]5.lk .lk`

        # Do nothing if V4.0D/V4.0E is not installed
	case $_SUBSET_NAME in
	OSFHWBIN425|OSFHWBIN435)
		;;
	*)
		return 0
		;;
	esac

	# Verify write access to ./usr directory
	touch ./usr/bin/dupatch$$ >/dev/null 2>&1 || return 0
	rm -f ./usr/bin/dupatch$$

	# Create symlinks for new atom driver
	ln -fs ../../../sys/BINARY/lfa.mod ./usr/sys/BINARY/lfa.mod >/dev/null 2>&1

}

: -FixTCRFiles
#
# Fix TCR kit to remove file that should not have shipped
#
FixTCRFiles()
{
        # Set filename and subset name
        _FILE="./usr/opt/TCR150/sys/config.file"
        _SUBSET_NAME="TCRCONF150"

        # Do nothing if TCR 1.5 config subset is not installed
        [ -f $_SMDB/$_SUBSET_NAME.lk ] || return 0

        # Remove previous inventory ./usr/opt/TCR150/sys/config.file entry
        RemoveInventoryRecord $_FILE $_SUBSET_NAME
}


: -FixAFAInstallation
#
# Fix problems caused by AFA installations.
#
# There are 3 types of behavior of the AFA subset:
# 
# A) 400, 401, 402, 404: Just install /usr/sbin/defragment.
# B) 425: Unpack defragment into /tmp/defragment. If defragment isn't on
# the system (it started shipping in the OSF name space starting V4.0D),
# it copies it in. - However the .smdb. inventory records do not reflect
# this.
# C) 435: Unpack defragment into /tmp/defragment. It then copies it into
# /usr/sbin/defragment without regard to whether it was there previously
# or not.. - Again the .smdb. inventory records do not reflect this.
# 
# Actions to be taken:
# b.1) For V4.0D/V4.0E: If the defragment on the system has been delivered
# directly (type A) or indirectly (B,C) fixup the OSF SSB inventory file
# with the correct checksum. If type A, remove ownership (not /tmp) from AFA.
# b.2) For V4.0-V4.0C: If the defragment on the system has been delivered
# directly (type A) - leave it alone.
# b.3) For V4.0-V4.0C: If the defragment on the system has been delivered
# indirectly (B,C) fixup the AFA* inventory file with the correct entry.
# b.4) If a type B or C subset has been delivered, remove the /tmp/*
# entries from the inventory files.
#
# The blocking will be done using scp extensions
#
FixAFAInstallation()
{
	AFA_TYPEA_VERSION_LIST="400 401 402 403 404"
	AFA_TYPEB_VERSION_LIST="425"
	AFA_TYPEC_VERSION_LIST="435"
	AFA_HIGHEST_PROBLEMATIC_VERSION="435"
	AFA_VERSION_LIST="$AFA_TYPEA_VERSION_LIST $AFA_TYPEB_VERSION_LIST $AFA_TYPEC_VERSION_LIST"
	AFA_SUBSET_LIST="ADVANCED ADVDAEMON ADVGUI ADVMAN"
	V40D_VERSION=425

	# Get rev of OS installed.
	OS_SYSTEM_VERSION=`GetHighestSubsetRev OSFBASE` || {
		# Something is REALLY wrong here
		return 1
	}

	# Get highest install rev of AFA. (Only 1 at a time in any case)
	AFA_HIGHEST_REV=`GetHighestSubsetRev AFAADVANCED` || {
		[ "$PATCH_DEBUG" ] && echo "AFA not installed"
		return 0
	}

	[ "$PATCH_DEBUG" ] && echo "AFA_HIGHEST_REV=$AFA_HIGHEST_REV"

	# No problem with the installed version of AFA
	[ "$AFA_HIGHEST_REV" -gt "$AFA_HIGHEST_PROBLEMATIC_VERSION" ] && {
		[ "$PATCH_DEBUG" ] &&
			echo "The version of AFA installed ($AFA_HIGHEST_REV) is OK"
		return 0
	}


	#
	# b.1) For V4.0D/V4.0E: If the defragment on the system has been delivered
	# directly (type A) or indirectly (B,C) fixup the OSF SSB inventory file
	# with the correct checksum. If type A, remove ownership (not /tmp) from AFA.
	#
	[ "$OS_SYSTEM_VERSION" -ge "$V40D_VERSION" ] && {
		[ "$PATCH_DEBUG" ] && echo "section b.1"
		ValidateAndSynchronizeFile	\
			./usr/sbin/defragment AFAADVANCED \
			./usr/sbin/defragment OSFADVFS$VER
		ValidateAndSynchronizeFile	\
			./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat AFAADVANCED \
			./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat OSFADVFS$VER
		ValidateAndSynchronizeFile	\
			./usr/man/man8/defragment.8.gz AFAADVMAN \
			./usr/share/man/man8/defragment.8.gz OSFMANOS$VER
	
		[ "$AFA_HIGHEST_REV" -lt "`Car $AFA_TYPEB_VERSION_LIST`" ] && {
			[ "$PATCH_DEBUG" ] && echo "Removing real entries from AFA"
			RemoveInventoryRecord	\
				./usr/sbin/defragment AFAADVANCED$AFA_HIGHEST_REV
			RemoveInventoryRecord	\
				./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat AFAADVANCED$AFA_HIGHEST_REV
			RemoveInventoryRecord	\
				./usr/man/man8/defragment.8.gz AFAADVMAN$AFA_HIGHEST_REV
		}
	}

	# b.2) For V4.0-V4.0C: If the defragment on the system has been delivered
	# directly (type A) - leave it alone.
	# b.3) For V4.0-V4.0C: If the defragment on the system has been delivered
	# indirectly (B,C) fixup the AFA* inventory file with the correct entry.
	[ "$OS_SYSTEM_VERSION" -lt "$V40D_VERSION" ] && {
		# Case b.3:
		[ "$AFA_HIGHEST_REV" -ge "`Car $AFA_TYPEB_VERSION_LIST`" ] && {
			[ "$PATCH_DEBUG" ] && echo "section b.3"
			ValidateAndSynchronizeFile	\
				./usr/sbin/defragment AFAADVANCED \
				./usr/sbin/defragment AFAADVANCED$AFA_HIGHEST_REV
			ValidateAndSynchronizeFile	\
				./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat AFAADVANCED \
				./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat AFAADVANCED$AFA_HIGHEST_REV
			ValidateAndSynchronizeFile	\
				./usr/man/man8/defragment.8.gz AFAADVMAN \
				./usr/man/man8/defragment.8.gz AFAADVMAN$AFA_HIGHEST_REV
		}
	}


	#
	# b.4) Remove /tmp entries
	#
	[ "$PATCH_DEBUG" ] && echo "Now removing /tmp entries"
	_TEMP=$_SMDB/AFA.$$
	for Version in $AFA_TYPEB_VERSION_LIST $AFA_TYPEC_VERSION_LIST
	{
		for Subset in $AFA_SUBSET_LIST
		{
			_SUBSET_NAME=AFA$Subset$Version
			[ -e $_SMDB/$_SUBSET_NAME.lk ] && {
				fgrep -q ./tmp/ $_SMDB/$_SUBSET_NAME.inv && {
					fgrep -v ./tmp/ $_SMDB/$_SUBSET_NAME.inv > $_TEMP
					mv $_TEMP $_SMDB/$_SUBSET_NAME.inv
					[ "$PATCH_DEBUG" ] &&
						echo "Removing /tmp entries from $_SUBSET_NAME"
				}
			}
		}
	}
	return 0
}
: -GetHighestSubsetRev
#
#	Get Highest Revision of Subset installed
#	For example: GHSR OSFBASE
#
GetHighestSubsetRev()
{
	_SUBSET_BASE_NAME=$1
	_ALL_INSTALLED=`(cd $_SMDB; ls -1 $_SUBSET_BASE_NAME???.lk 2>/dev/null | sed 's/\.lk//g' | sed 's/.*[\?\*].*//g')`
	[ "$_ALL_INSTALLED" ] || return 1
	_ALL_INSTALLED_REVERSED=`ListReverse $_ALL_INSTALLED`
	_LAST=`Car $_ALL_INSTALLED_REVERSED`
	echo "`expr $_LAST : '^.*\(...\)$'`"
	return 0
}
: - ValidateAndSynchronizeFile
#
#	Check that file on system matches entry in _SOURCE_SUBSET_NAME
#	If, it does, update entry in _TARGET_SUBSET_NAME
#
ValidateAndSynchronizeFile()
{
	_SOURCE_FILE_NAME=$1
	_SOURCE_SUBSET_NAME=$2
	_TARGET_FILE_NAME=$3
	_TARGET_SUBSET_NAME=$4

	[ "$PATCH_DEBUG" ] && echo "ValidateAndSynchronizeFile $*"

	[ "$#" = "4" ] || {
		echo "Internal Error - bad number of arguments"
		return 1
	}

	_HIGHEST_SOURCE_REV=`GetHighestSubsetRev $_SOURCE_SUBSET_NAME`


	# If we can match file to entry in _SOURCE SUBSET NAME
	ValidateSource $_SOURCE_FILE_NAME $_SOURCE_SUBSET_NAME$_HIGHEST_SOURCE_REV "./tmp/`basename $_SOURCE_FILE_NAME`" || {
		[ "$PATCH_DEBUG" ] && echo "Validation failed"
		return 1
	}

	# Put in correct entry into _TARGET_SUBSET_NAME
	SynchronizeInventoryRecord $_TARGET_FILE_NAME $_TARGET_SUBSET_NAME || {
		[ "$PATCH_DEBUG" ] && echo "Synchronization failed"
		return 1
	}
	[ "$PATCH_DEBUG" ] && echo "Synchronization succeeded"
	return 0
}
: - ValidateSource
#
#	Validate source of file possibly coming with a fake name.
#
ValidateSource()
{
	_FILE_NAME=$1
	_SOURCE_INVENTORY=$2
	_FAKE_FILE_NAME=$3

	[ "$PATCH_DEBUG" ] && echo "ValidateSource $*"

	# IF file isn't on system, nothing to validate
	[ -e $_FILE_NAME ] || {
		[ "$PATCH_DEBUG" ] && echo "$_FILE_NAME not found on system"
		return 1
	}

	# Look for file with real name
	_INVENTORY_CHECKSUM=`awk -v FILE=$_FILE_NAME '($10==FILE) { print $3 }' $_SMDB/$_SOURCE_INVENTORY.inv`

	# If not found with real name, look for fake name
	[ "$_INVENTORY_CHECKSUM" ] || {
		[ "$PATCH_DEBUG" ] && echo "$_FILE_NAME not found in $_SOURCE_INVENTORY, now looking for $_FAKE_FILE_NAME"
		_INVENTORY_CHECKSUM=`awk -v FILE=$_FAKE_FILE_NAME '($10==FILE) { print $3 }' $_SMDB/$_SOURCE_INVENTORY.inv`
	}

	# If not found, can't be validated.
	[ "$_INVENTORY_CHECKSUM" ] || {
		[ "$PATCH_DEBUG" ] && echo "Can't find fake file either"
		return 1
	}

	# Get checksum of file on system
	_SYSTEM_CHECKSUM=`sum < $_FILE_NAME | cut -d " " -f 1`

	# Is there a match ?
	[ "$_SYSTEM_CHECKSUM" = "$_INVENTORY_CHECKSUM" ] || {
		[ "$PATCH_DEBUG" ] && echo "System Checksum ($_SYSTEM_CHECKSUM) != Inventory ($_INVENTORY_CHECKSUM)"
		return 1
	}

	[ "$PATCH_DEBUG" ] && echo "Checksums ($_SYSTEM_CHECKSUM) match"
	return 0
}

: -SynchronizeInventoryRecord
#
#	Update (possibly add) the inventory record for a given file.
#
SynchronizeInventoryRecord()
{
	_FILE_NAME=$1
	_SUBSET_NAME=$2
	_VERSION=`expr $_SUBSET_NAME : '^.*\(...\)$'`

	[ "$PATCH_DEBUG" ] && echo "SynchronizeInventoryRecord $*"

	# Don't bother if not installed.
	[ -e $_SMDB/$_SUBSET_NAME.lk ] || {
		[ "$PATCH_DEBUG" ] && echo "Subset $_SUBSET_NAME not installed"
		return 1
	}
	[ -e $_FILE_NAME ] || {
		[ "$PATCH_DEBUG" ] && echo "File $_FILE_NAME not on system"
		return 1
	}

	# Remove previous entry
	RemoveInventoryRecord $_FILE_NAME $_SUBSET_NAME

	echo "0 $_FILE_NAME $_SUBSET_NAME" | ./usr/lbin/invcutter -v $_VERSION >> $_SMDB/$_SUBSET_NAME.inv
	sort -o $_SMDB/$_SUBSET_NAME.inv +9 $_SMDB/$_SUBSET_NAME.inv
}
: -RemoveInventoryRecord
#
#	Remove Inventory Record
#
RemoveInventoryRecord()
{
	_FILE_NAME=$1
	_SUBSET_NAME=$2

	fgrep -q $_FILE_NAME $_SMDB/$_SUBSET_NAME.inv && {
		[ "$PATCH_DEBUG" ] && echo "Removing previous entries of $_FILE_NAME from $_SUBSET_NAME"

		Temp=$_SUBSET_NAME.$$
		awk -v FILE=$_FILE_NAME '($10!=FILE) { print $0 }' $_SMDB/$_SUBSET_NAME.inv > $Temp
		mv $Temp $_SMDB/$_SUBSET_NAME.inv
		return 0
	}
	return 1
}
Main ()
{
	_SMDB="./usr/.smdb."
	_PRODMAP="./var/adm/patch/product_map"
	_TMP=/tmp/tmp_patchtool$$

	case $ACT in

	M) 	# do not offer in menu.
		return 1

		;;

	PRE_L)
		_SUB=`basename $0 .scp`			# subset identifier
        	_VCODE=`expr $_SUB : '^.*\(...\)$'`	# version code
        	_PCODE=`expr $_SUB : '^\(...\).*$'`	# product code
        	_BASE=`expr $_SUB : '^...\(.*\)...$'`	# w/o pcode vcode
        	_PID=`echo $_BASE | cut -b 5-9`		# patch id
        	_PREV=`echo $_BASE | cut -b 10-11`	# patch rev
        	_PNOREV=`expr $_BASE : '\(.*\)..'`	# base w/o patch rev
		
		# make sure oldest OSFBASE subset has ./sbin/Rsh
		InvRecord ./sbin/Rsh OSFBASE

		# Fix cases where X locks X.
		FixSelfLocked

		# make sure all mup subset inventories are sorted.
		SortMupInv

		# make sure all .upd.. are renamed/resorted in installed 
		# inventory.
		RenameUpdInv

		# get the highest version of OSFBASE installed.  	
		ALLBASE=`(cd $_SMDB; ls -r OSFBASE*.lk 2>/dev/null | sed 's/\.lk//g' | sed 's/OSFBASE.*[\?\*].*//g')`
		. /usr/share/lib/shell/Lists
		SYSBASE=`Car $ALLBASE`  
		VER=`expr "$SYSBASE" : '.*\(...\)$'`

    		#
    		# Fix problems caused by Advanced AdvFS utility subset installation.
    		#
    		FixAFAInstallation
		#
		FixConfigFiles
		#
		FixMisskitFiles
		#
		FixTCRFiles
		#
		Addlfa
		#
		Fixeemod
		#
		Fixmcicap
		#
		FixSysman
		#
		Fixmktemp

		# if there is a higher BASE installed, decline installation
		[ "$VER" -gt $_VCODE ] &&
		{
			echo "
Your system has \"Base System\" subset (OSFBASE$VER) installed.

This version of patch tools delivered on the patch distribution cannot 
be installed when the version of the \"Base System\" subset is higher 
than OSFBASE$_VCODE.
"
			return 1
		}
		
		# if the highest BASE is not the same version as self
		[ "$VER" -ne $_VCODE ] &&
		{
			echo "
This version of patch tools delivered on the patch distribution  
requires that \"Base System\" (OSFBASE$_VCODE) be installed first.
"
			return 1
		} 

		# decline if already installed unless UPDATE_DUPATCH is
		# defined.
		[ ! "$UPDATE_DUPATCH" ] &&
		{
			STL_DepInit
			STL_DepEval $_SUB &&
			{
				echo "
This version of the patch tools, $_SUB, is already installed.
"
				return 1
			}
		}

		# decline if higher ver/rev installed.
		HigherPatchInstalled && return 1

		;;

	POST_L)	_SUB=`basename $0 .scp`			# subset identifier
        	_VCODE=`expr $_SUB : '^.*\(...\)$'`	# version code


		# Get information for i2o
		Geti2oInfo
		
		# Fix patch_member
		FixPatchMember

		#
		# If old versions of the control files are currently
		# on the system, namely ones that are simply copies,
		# delete them no
		#
		for _OLDREV in 00 01 02 03 04 05 06 07 08 09 10 11
		{
			_OLD="OSFPAT000000$_OLDREV$_VCODE"		# old tool subset
			rm -f $_SMDB/$_OLD.ctrl
			rm -f $_SMDB/$_OLD.inv
			rm -f $_SMDB/$_OLD.scp
			rm -f $_SMDB/$_OLD.lk
	
		}
		# Update product map. We do it here so that on older 
		# installations where only the tools are installed,
		# we get the full set of new tools.
		UpdateProdMap
		;;


	esac

	return 0
}

:	- RenameUpdInv
#		fix the fact that inventories for installed OSF subsets
#		still contain .upd..
#

RenameUpdInv ()
{
	# get rid of those .lk with wildcards in them.
	INSTALLED=`(cd $_SMDB; ls -1 OSF*.lk | grep -v $_SUB | sed 's/\.lk//g' | sed 's/.*[\?\*].*//g')`
	for S in $INSTALLED
	{
		fgrep -q .upd.. $_SMDB/$S.inv &&
			sed 's/\.upd\.\.//g' $_SMDB/$S.inv | sort +9 -10 -o $_SMDB/$S.inv
	}
} 

:	- SortMupInv
#		fix the fact that some mup inventories are not in 
#		correct sort order.
#

SortMupInv ()
{
	for V in 360 361 365 366 370 375
	{
		SLIST=`(cd $_SMDB; ls OSF*$V.inv 2>/dev/null | sed 's/\.inv//')`
		[ "$SLIST" ] || continue

		for S in $SLIST
		{
			sort +9 -10 -o $_TMP $_SMDB/$S.inv
			cp -p $_TMP $_SMDB/$S.inv
		}	
	}
	rm -f $_TMP

	return 0
}

:       - SubsInstalled
#               given a version (yyVVV) free patch subset name, print a list 
#		of all other versions of that subset currently installed to 
#		the system.
#
#       given:  a version free patch.
#       does:   looks up version of $PN installed on the the system and 
#               output a list of subset identifiers in ascending version code 
#		order.

SubsInstalled()
{       PN=$1

        LIST=`(cd $_SMDB; echo $PN?????.lk | sed 's/\.lk//g' )`

        case "$LIST" in
        *\?\?\?)  return          # No match
        esac
        echo "$LIST"
}



[ "$CHECK_SYNTAX" ] || Main $@

