#!/sbin/sh
#
# Copyright  (c)  Digital Equipment Corporation, 1996 All Rights Reserved.
# Unpublished rights reserved under the copyright  laws  of  the  United
# States.   The  software  contained on this media is proprietary to and
# embodies the confidential technology of Digital Equipment Corporation.
# Possession,  use,  duplication  or  dissemination  of the software and
# media is authorized only pursuant to  a  valid  written  license  from
# Digital   Equipment   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.
#

[ `./bin/machine` = "alpha" ] && . /usr/share/lib/shell/libscp
[ `./bin/machine` = "alpha" ] && . /usr/share/lib/shell/Lists

: -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$OS_SYSTEM_VERSION
      ValidateAndSynchronizeFile	\
	 ./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat AFAADVANCED \
	 ./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat OSFADVFS$OS_SYSTEM_VERSION
      ValidateAndSynchronizeFile	\
	 ./usr/man/man8/defragment.8.gz AFAADVMAN \
	 ./usr/share/man/man8/defragment.8.gz OSFMANOS$OS_SYSTEM_VERSION

      [ "$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
}


case $ACT in

M) case $1 in
	-l)	[ `./bin/machine` = "alpha" ] ||
		{
			STL_ScpInit
			Z_BP=`echo $_SUB | sed s/$_VCODE//`

			echo "$Z_BP installs on DEC OSF/1 AXP systems only."
			exit 1
		}
		;;
	esac
	exit 0
	;;

  PRE_[LA])
	STL_ScpInit
	Z_BP=`echo $_SUB | sed s/$_VCODE//`

	STL_DepInit

	if STL_DepEval OSFDCMT??? not
	then
	   echo "For $_SUB to be installed you must install OSFDCMT400 or greater."
	   exit 1
	fi

	if STL_DepEval $Z_BP???
	then
	   if STL_DepEval $_SUB not
	   then
	      #
	      # Fix problems caused by older Advanced AdvFS utility subset installations.
	      #
	      FixAFAInstallation

	      echo "You must remove the currently installed $Z_BP subset"
	      echo "before you can install the $_SUB subset."
	      echo "Use the command:"
	      echo "      setld -i | grep $Z_BP | grep installed"
	      echo "to determine the name of the subset to delete."
	      exit 1
	   fi
	fi

	;;

  POST_[AL])
	STL_ScpInit
	Z_BP=`echo $_SUB | sed s/$_VCODE//`

	STL_DepInit

	if STL_DepEval $_SUB
	then
	    echo " "
	    echo "Installation of the $_DESC succeeded."
	    echo " "
	else
	    echo " "
	    echo "***"
	    echo "*** Installation of the $_DESC failed."
	    echo "***"
	    echo " "
	fi
        ;;


  POST_D)
	STL_ScpInit

	echo " "
        echo "The $_DESC were successfully deleted."
        echo " "
	;;

  V)
	echo ""
	echo ""
	;;
esac

exit 0
