#!/sbin/sh
#
#       Subset Control Program for AFAADVANCED 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
}
: -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 OSFADVFS4?? not
	then
	   echo "For $_SUB to be installed you must install OSFADVFS400 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

	STL_DepInit
	if STL_DepEval $_SUB
	then
	    echo " "
	    echo "The $_DESC were installed successfully."
	    echo " "
	else
	    echo " "
	    echo "***"
	    echo "*** The $_DESC installation failed."
	    echo "***"
	    echo " "
	fi
        ;;

PRE_D)
	;;

POST_D)
	STL_ScpInit
	echo " "
        echo "The $_DESC were deleted successfully."
        echo " "
        ;;

C)
	STL_ScpInit
	case $1 in
	INSTALL)
                echo "
The $_DESC product includes support for the
License Management Facility (LMF).  A Product Authorization Key (PAK)
is required to use the file-system utilities. See the AdvFS Installation
Guide for information on registering and activating the PAK.
"
        ;;
        esac
        ;;
V)
        echo "
############################################################################
# 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.                   #
############################################################################


This Installation Verification Procedure (IVP) tests the file system
utilities.  You can run the Advanced File System IVP (OSFADVFS400) either
before or after running this IVP.

The IVP prompts you for two disks, which must be labeled.  The IVP 
initializes the disks as an Advanced File System.  Either can be a
disk or a partition and both must have at least 20,000 KB of available
disk space.
"

        while :
	do
	            echo "
                         WARNING
      ------------------------------------------------------
        The IVP overwrites any existing data on the disk.  
      ------------------------------------------------------

Enter a disk or partition to initialize, ? for help, or q to quit: \c"
		    read devname1
                    case "$devname1" in 
                    [qQ])      
                        exit 0
                        ;;
                    [?])
                        echo "
Enter a disk or partition that will be initialized as
an Advanced File System.  You must give a block device
(i.e. /dev/rz1g).
"
                    ;;

                    *)
        		    if [ -b $devname1 ]
	        	    then
			        break
                           else        
                                echo "Please enter a block device."
 	            fi
                            ;;
                    esac
	done

        echo "
*************************************************************
*                                                           *
*  Creating the domain advfsdmn using volume $devname1.     *
*                                                           *
*************************************************************
"

        if        /sbin/mkfdmn $devname1 advfsdmn
        then echo "Status:
        Succeeded. "
        else 
                echo "Status:
        Unable to create a domain."
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Creating the fileset advfsset for file domain advfsdmn.  *
*                                                           *
*************************************************************
"

        if      /sbin/mkfset advfsdmn advfsset
        then echo "Status:
        Succeeded. "
        else 
                echo "Status:
        Unable to create a fileset."
                /sbin/rmfdmn advfsdmn
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Mounting the fileset advfsdmn#advfsset on /advfs.        *
*                                                           *
*************************************************************

Output:
"
        mkdir /advfs
        if      mount -t advfs advfsdmn#advfsset /advfs
        then echo "
Status:
        Succeeded. "
        else 
                echo "
Status:
        Unable to mount the fileset."
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Using vdump and vrestore to copy /sbin to /advfs.        *
*                                                           *
*************************************************************

Output:
"
        if    /sbin/vdump -0 -f - -D /sbin | /sbin/vrestore -x -f - -D /advfs
        then echo "
Status:
        Succeeded. "
        else 
                echo "
Status:
        Unable to dump /sbin to the fileset."
                umount /advfs
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Using addvol to add another volume to the file domain    *
*  advfsdmn.                                                *
*                                                           *
*************************************************************
"
        while :
	do
	            echo "
                         WARNING
      ------------------------------------------------------
        The IVP overwrites any existing data on the disk.  
      ------------------------------------------------------

Enter a disk or partition to initialize, ? for help, or q to quit: \c"

		    read devname2
                    case "$devname2" in 
                    [qQ])      
                        echo "
Cleaning up by unmounting /advfs.
"
                        umount /advfs
                        rm -r /advfs
                        /sbin/rmfdmn advfsdmn
                        exit 0
                        ;;
                    [?])
                        echo "
Enter a disk or partition that will be initialized as
an Advanced File System.  You must give a block device
(i.e. /dev/rz1g).
"
                    ;;
                    *)
        		    if [ -b $devname2 ]
	        	    then
			        break
                            else        
                                echo "Please enter a block device."
		            fi
                            ;;
                    esac
	done

        if      /usr/sbin/addvol $devname2 advfsdmn
        then echo "Status:
        Succeeded. "
        else 
                echo "Status:
        Unable to add $devname2 to the domain advfsdmn."
                umount /advfs
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Using defragment on advfsdmn.                            *
*                                                           *
*************************************************************
"

        if      /usr/sbin/defragment -T 2 advfsdmn
        then echo " "
        else 
                echo "Status:
        Unable to defragment."
                umount /advfs
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Using balance on advfsdmn.                               *
*                                                           *
*************************************************************
"

        if      /usr/sbin/balance advfsdmn
        then echo " "
        else 
                echo "Status:
        Unable to balance."
                umount /advfs
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Using clonefset to take a snapshot of /advfs.            *
*                                                           *
*************************************************************
"

        if      /usr/sbin/clonefset advfsdmn advfsset advfsclone
        then echo " "
        else 
                echo "Status:
        Unable to create the clone advfsclone."
                umount /advfs
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
                exit 0
        fi

        mkdir /advfs_clone
        if      mount -t advfs advfsdmn#advfsclone /advfs_clone
        then echo "Status:
        Succeeded. "
        else 
                echo "Status:
        Unable to mount the fileset."
                umount /advfs
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
		rm -r /advfs_clone
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Using stripe to span a file across the two volumes in    *
*  the file domain advfsdmn.                                *
*                                                           *
*************************************************************
"
        touch /advfs/stripefile

        if      /usr/sbin/stripe -n 2 /advfs/stripefile
        then    cat /advfs/scu.hlp >> /advfs/stripefile
                echo "Status:
        Succeeded."
        else 
                echo "Status:
        Unable to stripe the file /advfs/stripefile."
                umount /advfs /advfs_clone
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
		rm -r /advfs_clone
                exit 0
        fi

        echo "
**************************************************************
*                                                            *
*  Using migrate to move the location of a file within the   *
*  file domain advfsdmn.                                     *
*                                                            *
**************************************************************
"

        if      /usr/sbin/migrate /advfs/who
        then echo "Status:
        Succeeded. "
        else 
                echo "Status:
        Unable to migrate the file /advfs/who."
                umount /advfs /advfs_clone
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
		rm -r /advfs_clone
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Using rmvol to remove the volume $devname2 from the      *
*  file domain advfsdmn.                                    *
*                                                           *
*************************************************************
"

        if      /usr/sbin/rmvol -f $devname2 advfsdmn
        then echo "Status:
        Succeeded.

NOTE:  It is normal for this striped file to be suboptimal as a
       result of performing the rmvol in this test.
"
        else 
                echo "Status:
        Unable to remove $devname2 from advfsdmn."
                umount /advfs /advfs_clone
                /sbin/rmfdmn advfsdmn
		rm -r /advfs
		rm -r /advfs_clone
                exit 0
        fi

        echo "
*************************************************************
*                                                           *
*  Unmounting the fileset advfsdmn#advfsset from /advfs     *
*  and advfsdmn#advfsclone from /advfs_clone.               *
*                                                           *
*************************************************************
"
        umount /advfs /advfs_clone

        echo "
*************************************************************
*                                                           *
*  Removing the /etc/fdmns/advfsdmn directory.              *
*                                                           *
*************************************************************
"
        rm -r /advfs /advfs_clone
        /sbin/rmfdmn advfsdmn

        echo "
Your system successfully executes the file-system utilities for
the Advanced File System.
"
        ;;
esac
exit 0
#	End of script
