#!/sbin/sh
#
#       Subset Control Program for AFADEFRAGMENT subset.

[ `./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
}


: -FixDefragmentInstallation
#
# NOTE:
#	This function is intended to be invoked in
#	the POST_L phase of this subset.
#
# Fix problems caused by the installation of the defragment 
# utility by this kit.
#
# This particular subset installs the defragment utility.
#
# If the operating system is V4.0D or later (but not V5.0), then
# defragment is supposed to belong to the OSFADVFS and OSFMANOS
# subsets.  The only reason this subset should have been loaded
# is if defragment somehow was accidentally removed from the
# system.  In this case, update the .smdb. database so that
# defragment is owned by the OS and not this subset.
# 
# This is similar to the code found in FixAFAInstallation.
#
FixDefragmentInstallation()
{
   V40D_VERSION=425

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

   #
   # For DIGITAL UNIX V4.0D, V4.0E, and later:
   #    Transfer ownership of the defragment components to the
   #    OSF inventory files.
   #
   [ "$OS_SYSTEM_VERSION" -ge "$V40D_VERSION" ] && {

      # Handle the defragment binary and catalog files.

      ValidateAndSynchronizeFile	\
	 ./usr/sbin/defragment AFADEFRAGMENT \
	 ./usr/sbin/defragment OSFADVFS$OS_SYSTEM_VERSION
      ValidateAndSynchronizeFile	\
	 ./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat AFADEFRAGMENT \
	 ./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat OSFADVFS$OS_SYSTEM_VERSION

      # Remove them from the AFADEFRAGMENT subset.

      RemoveInventoryRecord ./usr/sbin/defragment				$_SUB
      RemoveInventoryRecord ./usr/lib/nls/msg/en_US.ISO8859-1/defragment.cat	$_SUB


      # Now, if the user does NOT have the OSFMANOS subset loaded, then
      # remove the defragment man page, otherwise give it to OSFMANOS.

      if STL_DepEval OSFMANOS4?? not
      then
	 rm ./usr/share/man/man8/defragment.8.gz
      else
	 ValidateAndSynchronizeFile	\
	    ./usr/man/man8/defragment.8.gz AFADEFRAGMENT \
	    ./usr/share/man/man8/defragment.8.gz OSFMANOS$OS_SYSTEM_VERSION
      fi

      # Finally, remove the man page from the AFADEFRAGMENT inventory.

      RemoveInventoryRecord ./usr/man/man8/defragment.8.gz	$_SUB

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


[ $ACT = "M" ] || {
   STL_ScpInit
   Z_BP=`echo $_SUB | sed s/$_VCODE//`

   V40D_VERSION=425

   # Get rev of OS installed.
   OS_SYSTEM_VERSION=`GetHighestSubsetRev OSFBASE` || {
      # Something is REALLY wrong here
      echo "ERROR: Unable to determine the version of the Operating System!"
      exit 1
   }
}

case $ACT in

M) case $1 in
	-l)	[ `./bin/machine` = "alpha" ] ||
		{
			Z_BP="`basename $0 | sed s/.scp//`"
			echo "$Z_BP installs on DEC OSF/1 AXP systems only."
			exit 1
		}
		[ -x ./usr/sbin/defragment ] && exit 1
		;;
	esac
	exit 0
	;;

PRE_[LA])
	STL_DepInit

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


	if STL_DepEval AFAADVMAN???
	then
	   if STL_DepEval AFAADVMAN$_VCODE not
	   then
	      #
	      # Fix problems caused by older Advanced AdvFS utility subset installations.
	      #
	      FixAFAInstallation
	   fi
	fi


	if STL_DepEval AFAADVANCED???
	then
	   if STL_DepEval AFAADVANCED$_VCODE not
	   then
	      #
	      # Fix problems caused by older Advanced AdvFS utility subset installations.
	      #
	      FixAFAInstallation
	   fi
	fi


	if STL_DepEval $Z_BP???
	then
	   if STL_DepEval $_SUB not
	   then
	      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_DepInit

	if STL_DepEval $_SUB not
	then
	    echo " "
	    echo "***"
	    echo "*** The $_DESC installation failed."
	    echo "***"
	    echo " "
	else
	    #
	    # Fix problems caused by older Advanced AdvFS utility subset installations.
	    #
	    FixDefragmentInstallation

	    echo " "
	    echo "Successfully installed the $_DESC."
	    echo " "
	fi
	;;

PRE_D)
	;;

POST_D)
	echo " "
        echo "Successfully deleted the $_DESC."
        echo " "
        ;;

C)
	case $1 in
	INSTALL)
	;;
	esac
	;;
V)
	echo ""
	;;

esac

exit 0
