#!/bin/sh

#-------------------------------------------------------------------------------
# restore.sh
# 
# This shell script is invoked to perform a restore of the HSC backup data.
# This script should be executed every time the system reboots.  If no
# "indicator" file is present, the script exits and no file restoration is done.
# 
# Usage: 'restore'
#
# Return Codes:
# 1 - Error mounting the upgrade partition
# 2 - Error Copying from the media
# 3 - Archive not present
# 4 - Error unmounting the media
# 5 - Other Errors
# 6 - DVD drive failure
# 7 - No media inserted
# 8 - Unformatted media
# 9 - Incorrect label on media
# 10 - tar error extracting relative to working directory
# 11 - unable to create staging directory
# 12 - no need to run a restore
# 13 - unable to generate the excluded shared object file list
# 14 - tar error extracting non-*.so files relative to / dir
# 15 - staged file move/copy error
# 16 - HmcBase file miscompare (incompatible archive)
# 18 - unable to query the archive file (tar -tzvf failure)
# 20 - no USB flash memory device detected
# 21 - not enough space on the local fs to rebuild split archive from USB media

#-------------------------------------------------------------------------------
# directory and filename which records the backup actions.
#-------------------------------------------------------------------------------
LOGDIR=/var/hsc/log
LOG=$LOGDIR/restore.log

LOG_ERROR_LOG=/tmp/restore.log
ARCHIVE_LOG=/tmp/archive.log

# stdout of 'mount' command directed to /tmp/mount_output+PID
MOUNT_OUTPUT=/tmp/mount_output$$

#-------------------------------------------------------------------------------
# the HMC mount point for DVD-RAM media
#-------------------------------------------------------------------------------
DVD_MOUNTPOINT=/media/cdrom

#-------------------------------------------------------------------------------
# location on the HMC where a remote archive file can be found
#-------------------------------------------------------------------------------
REM_ARCHIVE_LOCATION=/dump

#-------------------------------------------------------------------------------
# the filename of the backup archive when on media
#-------------------------------------------------------------------------------
ARCHIVENAME=backuphdr.tgz

#-------------------------------------------------------------------------------
# the (hard drive) media mount point where the indicator file, created by the
# CD re-install process, is stored.  There should be an entry for this
# mountpoint in /etc/fstab.  Also set the Linux kernel mount point location
#-------------------------------------------------------------------------------
UPGRADE_MOUNTPOINT=/mnt/upgrade

#-------------------------------------------------------------------------------
# the indicator file. If it exists, execute 'tar' cmd to restore the backup data
#-------------------------------------------------------------------------------
INDFILE=iqybcrit.dat
REMOTE_INDFILE=rmtbcrit.dat
IQYBCRIT=$UPGRADE_MOUNTPOINT/$INDFILE
RMTBCRIT=$UPGRADE_MOUNTPOINT/$REMOTE_INDFILE

#-------------------------------------------------------------------------------
# Initialize internal script variables used for archive restore type
#-------------------------------------------------------------------------------
USE_REMOTE_BACKUP=0
USE_LOCAL_BACKUP=0

#-------------------------------------------------------------------------------
# Flag to indicate a critical error has occurred during 'tar' file processing
#-------------------------------------------------------------------------------
ARCHIVEFAIL=0

#-------------------------------------------------------------------------------
# Flags/variables used for error processing
#-------------------------------------------------------------------------------
let CP_INDICATOR=0
let MV_INDICATOR=0

# misc init flags
archiveOnDVD=0
archiveOnUsb=0
isDvdMounted=0
isUsbMounted=0
isArchiveSplit=0
let archiveSize=0


#-------------------------------------------------------------------------------
#
# common exit point for script
#
#-------------------------------------------------------------------------------
exit_cleanup() {
    rm -f $MOUNT_OUTPUT

    # Cleanup any staged *.so/misc files in the working area
    rm -fr $WORKING_DIR

    # misc cleanup before exiting
    if [ "$USE_LOCAL_BACKUP" = "1" ]; then
        # umount media, if already mounted
        if [ $isDvdMounted -eq 1 ]; then
            umount -v $DVD_MOUNTPOINT >> $LOG 2>&1
        fi
        if [ $isUsbMounted -eq 1 ]; then
            umount -v $USB_MOUNTPOINT >> $LOG 2>&1
        fi
        # if archive split remove rebuilt archive
        if [ $isArchiveSplit -eq 1 ]; then
            echo "removing rebuilt split archive file $LOCAL_DIR/$ARCHIVENAME" >> $LOG 
            rm $LOCAL_DIR/$ARCHIVENAME >> $LOG 2>&1
        fi

        /sbin/hdparm -d0 $DVD_DEV >/dev/null 2>&1
    else
        # remote archive path
        rm -f $RMTBCRIT
        rm -f $REM_ARCHIVE_LOCATION/HMCBackup*
        echo "remote archive indicator file and archive file have been removed from this HMC" >> $LOG
    fi
    
    umount $UPGRADE_MOUNTPOINT

    if [ $ARCHIVEFAIL -ne 0 ]; then
        echo "possible critical archive restore failure!" >> $LOG
        echo "archive failure error code is: $ARCHIVEFAIL" >> $LOG
        echo "task completed on `date`, return status = 99" >> $LOG
        exit 99
    else
        echo "task completed on `date`, return status = $1" >> $LOG
    fi

    exit $1
}  

#-------------------------------------------------------------------------------
# calculate the checksum of archive file and current file
#-------------------------------------------------------------------------------
function doChecksum {

    funcRC=0
        
    echo "calculating checksum of archive file, $1 ..." >> $ARCHIVE_LOG
    x=`/usr/bin/sum $1`
    echo "...archive file checksum complete, value is --> <$x>, timestamp is `date`." >> $ARCHIVE_LOG
    
    echo "calculating checksum of current file, $2 ..." >> $ARCHIVE_LOG
    y=`/usr/bin/sum $2`
    echo "...current file checksum complete, value is --> <$y>, timestamp is `date`." >> $ARCHIVE_LOG
    
    if [ "$x" == "$y" ]; then
        # all is well, files match
        funcRC=0;
    else
        # miscompare
        funcRC=9;
    fi
    
    echo "Exiting verifyChecksum, funcRC = $funcRC." >> $ARCHIVE_LOG
    return $funcRC
}  

#-------------------------------------------------------------------------------
# verify DVD-RAM "access" and look to see if we can detect an HMC archive file
# once the DVD-RAM media is mounted
#-------------------------------------------------------------------------------
function checkForArchiveOnDvdRam {

    funcRC=0
        
    # check first if the DVD-RAM is previously mounted (it should not be!). If
    # it is, un-mount and re-mount with specific options
    if grep -q "$DVD_MOUNTPOINT" /etc/mtab; then
        # DVD-RAM is already mounted, un-mount
        if ! umount -v $DVD_MOUNTPOINT >> $LOG 2>&1; then
            echo "Could not un-mount the DVD-RAM media..." >> $LOG
            funcRC=4
        fi
    fi

    # specifically attempt to re-mount the DVD-RAM media using UDF - do not rely
    # on filesystem "guessing" or /etc/fstab content when mounting that type of
    # media
    if [ $funcRC -eq 0 ]; then
        if mount -t udf -v /dev/cdrom $DVD_MOUNTPOINT > $MOUNT_OUTPUT 2>&1; then
            isDvdMounted=1
            echo "successfully mounted the DVD-RAM media, continuing..." >> $LOG

#            # leave this test out since the pSeries HMC does not label DVD-RAM media
#            # after formatting them
#            if !(chkudf /dev/hdc | grep -q -i "ACTBKP" 2>&1); then # udf/dvd specific
#            false=0
#            if false; then
#                echo "The media has an incorrect backup label." >> $LOG
#                funcRC=9
            if [ ! -f $DVD_MOUNTPOINT/$ARCHIVENAME ]; then
                # No HMC archive file detected on the DVD-RAM media, 
                echo "File, $ARCHIVENAME, was not found on the DVD-RAM media." >> $LOG
                funcRC=3
            else
                # archive file on DVD media check passed
                echo "The backup archive file was detected on DVD media." >> $LOG
            fi

        else
            # could not mount the media - see if there is a detected reason for this
            echo "Could NOT mount the DVD_RAM media. Attempting to resolve..." >> $LOG

            if grep -q -i "wrong major or minor number" $MOUNT_OUTPUT; then
                echo "Failure with major/minor signature on the DVD RAM drive." >> $LOG
                funcRC=6
            elif grep -q -i "No medium found" $MOUNT_OUTPUT; then
                echo "No DVD-RAM media inserted in the drive." >> $LOG

                # Here's one place where we'll remove the indicator file. This
                # will hopefully catch the manufacturing process issue whereby
                # they are installing the pHMCs from the recovery CD, which
                # contains the indicator file, during the initial HMC install.
                # That file should not initially be on the system.  The 'no media'
                # return code from 'mount' cmd is 32.
                rm -f $IQYBCRIT

                funcRC=7
            elif grep -q -i "wrong fs type" $MOUNT_OUTPUT; then
                echo "Wrong filesystem type, or unformatted media, or wrong media type." >> $LOG
                funcRC=8
            else
                echo "Unknown error while mounting the DVD-RAM media." >> $LOG

                echo "----- begin mount info -----" >> $LOG
                x=`cat $MOUNT_OUTPUT`
                echo "$x" >> $LOG
                echo "----- end mount info -----" >> $LOG
                funcRC=5
            fi
        fi
    fi

    echo "Exiting checkForArchiveOnDvdRam, funcRC = $funcRC." >> $LOG
    return $funcRC
}  

#-------------------------------------------------------------------------------
# verify USB "access" and look to see if we can detect an HMC archive file
# once the USB flash memory device is mounted
#-------------------------------------------------------------------------------
function checkForArchiveOnUsb {

    funcRC=0

    #-------------------------------------------------------------------------------
    # the HMC mount point for USB flash memory devices
    #-------------------------------------------------------------------------------
    x=`/opt/hsc/bin/discover_devices --all usbflashkey`
    if [ "$x" != "" ]; then
    # now find mount point
        device=`echo $x | cut -d';' -f1`
        l=`cat /etc/fstab | grep ^"$device"`
        for i in $l
        do
            d=`/usr/bin/dirname $i 2>/dev/null`
            if [ "$d" = "/media" ]; then
                USB_MOUNTPOINT="$i"
                break
            fi
        done
    else
        # no USB flash memory device detected
        USB_MOUNTPOINT=
    fi

    if [ "$USB_MOUNTPOINT" != "" ]; then
        # Check to see if media is already mounted - if so then unmount it
        if grep -q "$USB_MOUNTPOINT" /etc/mtab; then
            if ! umount -v $USB_MOUNTPOINT >> $LOG 2>&1; then
                echo "Could not un-mount the media, $USB_MOUNTPOINT." >> $LOG
                funcRC=4
            fi
        fi
    
        # Mount the media and check for write-protect
        if [ $funcRC -eq 0 ]; then
            mount -v $USB_MOUNTPOINT > $MOUNT_OUTPUT 2>&1
            if [ $? -eq 0 ]; then
                isUsbMounted=1
                echo "Mounted the USB flash memory device ok." >> $LOG   
                # check for the standard HMC archive file on USB media
                if [ ! -f $USB_MOUNTPOINT/$ARCHIVENAME ]; then
                    # stardard HMC archive does not exists, check if split files exist
                    ls -1 $USB_MOUNTPOINT/${ARCHIVENAME}* > /dev/null 2>&1
                    if [ $? -eq 0 ]; then
                        # archive file on USB media check passed
                        isArchiveSplit=1
                        echo "Split HMC backup archive files were detected on the USB flash memory device." >> $LOG
                        # tally split file sizes to total size needed to restore archive
                        for i in $( ls -l $USB_MOUNTPOINT/${ARCHIVENAME}* | awk '{print $5}'); do 
                            let archiveSize=archiveSize+$i; 
                        done
                        echo "Combined size of split HMC backup archive files is $archiveSize" >> $LOG
                    else
                        # No HMC archive file detected on the USB media,
                        echo "No HMC backup archive file was found on the USB flash memory device." >> $LOG
                        funcRC=3
                    fi
                else
                    # archive file found on USB media
                    echo "HMC backup archive file was detected on the USB flash memory device." >> $LOG
                fi
            else
                echo "Unexpected error while mounting the USB flash memory device." >> $LOG
    
                echo "----- begin mount info -----" >> $LOG
                x=`cat $MOUNT_OUTPUT`
                echo "$x" >> $LOG
                echo "----- end mount info -----" >> $LOG
                funcRC=5
            fi    
        fi
    else
        # no USB flash memory device detected
        funcRC=20
    fi
        
    echo "Exiting checkForArchiveOnUsb, funcRC = $funcRC." >> $LOG
    return $funcRC
}  


#-------------------------------------------------------------------------------
# verify USB "access" and look to see if we can detect an HMC archive file
# once the USB flash memory device is mounted
#-------------------------------------------------------------------------------
function rebuildSplitArchiveFromUsb {

    funcRC=0

    #-------------------------------------------------------------------------------
    # locate local filesystem that has enough space to hold archive

    # start with /extra
    localFreeSpace=`df --block-size=1 -l /extra | tail -1 | awk '{print $4}'`

    echo "available space for /extra is $localFreeSpace, archive size = $archiveSize" >> $LOG

    if [ "$localFreeSpace" -gt "$archiveSize" ]; then
        LOCAL_DIR=/extra
    else
        localFreeSpace=`df --block-size=1 -l /dump | tail -1 | awk '{print $4}'`
        
        echo "available space for /dump is $localFreeSpace, archive size = $archiveSize" >> $LOG
        if [ "$localFreeSpace" -gt "$archiveSize" ]; then
            LOCAL_DIR=/dump
        else
            localFreeSpace=`df --block-size=1 -l /tmp | tail -1 | awk '{print $4}'`

            echo "available space for /tmp is $localFreeSpace, archive size = $archiveSize" >> $LOG

            if [ "$localFreeSpace" -gt "$archiveSize" ]; then
                 LOCAL_DIR=/tmp
            else
                funcRC=21
                echo "Unable to locate enough space on the local filesystem to rebuild split archive from USB media." >> $LOG
            fi
        fi
    fi

    if [ $funcRC -eq 0 ]; then
        echo "Split archive file will be rebuilt and restored to $LOCAL_DIR" >> $LOG

        cat  $USB_MOUNTPOINT/${ARCHIVENAME}* > $LOCAL_DIR/$ARCHIVENAME
    fi

    echo "Exiting rebuildSplitArchiveFromUsb, funcRC = $funcRC." >> $LOG
    return $funcRC
}  



# Check if the directory for the log file exists.
if [ ! -d $LOGDIR ]; then
    echo "=================================================================" > $LOG_ERROR_LOG
    echo -e "Restore task log for `date`." >> $LOG_ERROR_LOG
    echo "Restore task log directory, <$LOGDIR>, does not exist. Program exiting" >> $LOG_ERROR_LOG
    exit 5
fi


# Just in case we have NLS troubles reading system information...
LANG=en_US
export LANG



#-------------------------------------------------------------------------------
# Start log to record restore actions. Keep a few archive copies since multiple
# reboots may be done and this current log file will be lost
#-------------------------------------------------------------------------------
if [ -f $LOG.2 ]; then
    mv $LOG.2 $LOG.3
fi
if [ -f $LOG.1 ]; then
    mv $LOG.1 $LOG.2
fi
if [ -f $LOG ]; then
    mv $LOG $LOG.1
fi
echo -e "Restore script program start - log for `date`\n" > $LOG

#-------------------------------------------------------------------------------
# Mount the media where the indicator file should be located
#-------------------------------------------------------------------------------
mount -v $UPGRADE_MOUNTPOINT > $MOUNT_OUTPUT 2>&1
mountRC=$?
if [ $mountRC -ne 0 ]; then

    #----------------------------------------------------------------------------
    # already mounted?  Not an error, but a non-zero return code. Continue...
    #----------------------------------------------------------------------------
    if grep "already mounted" $MOUNT_OUTPUT; then
        echo "The mountpoint, $UPGRADE_MOUNTPOINT, is already mounted, continuing..." >> $LOG

    #----------------------------------------------------------------------------
    # other mount error?  Game over.
    #----------------------------------------------------------------------------
    else
        echo "The mountpoint, $UPGRADE_MOUNTPOINT, cannot be mounted. Error is $mountRC" >> $LOG
        cat $MOUNT_OUTPUT >> $LOG
        exit_cleanup 1
    fi
fi

#-------------------------------------------------------------------------------
# good mount of upgrade partition where indicator file is located, continue...
#-------------------------------------------------------------------------------
echo "partition with indicator file, $INDFILE, successfully mounted at $UPGRADE_MOUNTPOINT..." >> $LOG


#-------------------------------------------------------------------------------
# The initial check is for the indicator file that a remote restore was was
# initiated. If this flag is set, then process the "HMCBackup_yyyymmdd.hhmmss"
# file which should now be located in the /dump directory.  Otherwise, check
# next for the HMC indicator file which says that a restore from DVD is to be
# done.
#-------------------------------------------------------------------------------
if [ ! -f $RMTBCRIT ]; then
    echo "$RMTBCRIT indicator file does not exist. Remote data restoration not requested, continuing..." >> $LOG
    
    # See if a restore from media (DVD-RAM or USB) is required. This flag should
    # only be set after an HMC clean install (F8/F1).
    if [ ! -e $IQYBCRIT ]; then
        echo "$IQYBCRIT indicator file does not exist. Data restoration not required" >> $LOG
        echo -e "restore script exiting.\n" >> $LOG
        
        # no HMC restore required.  Exit program
        exit_cleanup 12
    else
        # ok, let's mark that we want to restore the system using media
        USE_LOCAL_BACKUP=1

        # set up DVD_RAM device name
        DVD_DEV=/dev/hdc
        HD=`/opt/hsc/bin/GetHD`
        if [ "$HD" != "hda" ]; then
            DVD_DEV=/dev/hda
        fi
    fi
else
    # Ah ha! We will be restoring the system from a remote archive file
    USE_REMOTE_BACKUP=1      
fi

#-------------------------------------------------------------------------------
# Look for the HMC backup archive file now. If data supplied via local media,
# check first on the DVD-RAM, then check for it on a USB device
#-------------------------------------------------------------------------------
if [ "$USE_LOCAL_BACKUP" = "1" ]; then

    # look on DVD-RAM media first
    checkForArchiveOnDvdRam
    archiveCheck=$?

    if [ $archiveCheck -eq 0 ]; then
        # make a note the archive file was detected on the DVD. Log, set flag and
        # set the archive filename
        echo "HMC backup archive file detected on DVD-RAM media, continuing..." >> $LOG
        archiveOnDVD=1
        ARCHIVE=$DVD_MOUNTPOINT/$ARCHIVENAME
    else
        # no archive found on DVD-RAM media (or difficulties accessing that media),
        # so now check on the USB flash memory device for the HMC backup archive file
        checkForArchiveOnUsb
        archiveCheck=$?
        if [ $archiveCheck -eq 0 ]; then
            # make a note the archive file was detected on the USB. Log, set flag and
            # set the archive filename
            echo "HMC backup archive file detected on USB flash memory device, continuing..." >> $LOG
            if [ $isArchiveSplit -eq 1 ]; then
                rebuildSplitArchiveFromUsb
                rebuildCheck=$?
                if [ $rebuildCheck -eq 0 ]; then
                    ARCHIVE=$LOCAL_DIR/$ARCHIVENAME
                    echo "Split HMC backup archive files were rebuilt as $LOCAL_DIR/$ARCHIVENAME" >> $LOG
                else
                    echo "Unable to rebuild split HMC backup archive files from USB flash memory device." >> $LOG
                    exit_cleanup $rebuildCheck
                fi
            else
                archiveOnUsb=1
                ARCHIVE=$USB_MOUNTPOINT/$ARCHIVENAME
            fi
        else
            # no HMC archive file was found, or there were difficulties accessing the
            # local media
            echo "No HMC backup archive file was not found on any supported removeable media." >> $LOG
            exit_cleanup $archiveCheck
        fi
    fi

else
    #-------------------------------------------------------------------------------
    # Ensure there is a remote archive file to restore - there should be.
    # 
    # Note there should be one and only one HMCBackup_yyyyMMdd.HHmmss file in this
    # directory. If not, just use the "first" one we find. All archievs will be 
    # removed when the operation completes.
    #-------------------------------------------------------------------------------
    x=`ls -1 $REM_ARCHIVE_LOCATION/HMCBackup*`
    if [ $? -ne 0 ]; then
        echo "The remotely restored archive file is not present. Exiting now, rc=3" >> $LOG
        exit_cleanup 3
    else
        # Ok, remote archive file is present, ensure there is only one of them
        # and set the script variable to point to this file.
        #
        # Set $ARCHIVE to be the first listed file - there should be only one present
        echo "The remotely restored archive file, $x, is present..." >> $LOG
        ARCHIVE=`echo $x | cut -d " " -f 1 -`
    fi
fi

#-------------------------------------------------------------------------------
# Now do the actual restore from the archive
#-------------------------------------------------------------------------------
echo -e "starting the HMC restore processing using $ARCHIVE...\n" >> $LOG

#
# First thing to do is determine which files are shared objects that could 
# potentially be partially paged in the system.  Hence, a recurring read
# of that same library file could panic the system - in theory, of course.
# Rather than using the 'tar' command to restore those particular archive
# files, we'll be staging those files and using the 'mv' command.
#
# Construct a working/staging directory for pre/post processing. This working
# directory should not be present after a "clean" install.
#
WORKING_DIR=/tmp/restore/work
mkdir -p $WORKING_DIR
if [ $? -ne 0 ]; then
    echo "error creating the working directory for special file extraction. Exiting now, rc=11" >> $LOG
    exit_cleanup 11
fi
echo "working directory for special file extraction created successfully, continuing..." >> $LOG


#
# start with a clean extraction log, just in case...
#
rm -f $ARCHIVE_LOG
echo -e "Begin HMC file recovery log on `date`\n" > $ARCHIVE_LOG
if [ "$USE_LOCAL_BACKUP" = "1" ]; then
    /sbin/hdparm -d1 $DVD_DEV >/dev/null 2>&1
fi


#
# Script needs to query the contents of the tar archive file multiple times and this could be
# very "expensive". Redirect the output one time to a file now for all subsequent queries.
#
tar -tvzf $ARCHIVE > $WORKING_DIR/tar.list 2>> $ARCHIVE_LOG
tarRC=$?
if [ $tarRC -ne 0 ]; then
    # unable to query the archive file
    echo -e "unable to query/list the archive file, tarRC = $tarRC. Exiting now, rc=18 \n" >> $LOG
    echo -e "unable to query/list the archive file, tarRC = $tarRC. Exiting now, rc=18 \n" >> $ARCHIVE_LOG
    exit 18
fi
echo "HMC archive file query/list completed successfully, continuing..." >> $ARCHIVE_LOG

#
# Feature 587785 to prevent archive file from being unpacked on either a differnt
# HMC modle type or unpacked when starting with a different base HMC driver
#
echo "checking if restore allowed based on matching HMC driver versions..." >> $ARCHIVE_LOG
grep -w "/etc/HmcBase" $WORKING_DIR/tar.list > $WORKING_DIR/check.list 2>> $ARCHIVE_LOG
if [ $? -eq 0 ]; then
    echo "version check file exists in the archive, processing..." >> $ARCHIVE_LOG

    tar -xvzf $ARCHIVE --files-from=$WORKING_DIR/check.list --directory=$WORKING_DIR >> $ARCHIVE_LOG 2>&1
    if [ $? -eq 0 ]; then
        # unpack was ok in the $WORKING_DIR relative /etc dir, now check this file against freshly installed file
        echo "version check file unpacked ok, continuing..." >> $ARCHIVE_LOG

        if [ -f /etc/HmcBase ]; then
            # both files exist, compare them for version stamping info
            echo "now comparing archive file to recently installed file..." >> $ARCHIVE_LOG

            doChecksum $WORKING_DIR/etc/HmcBase /etc/HmcBase
            if [ $? -ne 0 ]; then
                # version miscompare
                echo "version miscompare detected, bypassing archive restoration. Exiting now, rc=16" >> $ARCHIVE_LOG
                echo "version miscompare detected, bypassing archive restoration. Exiting now, rc=16" >> $LOG

                rm -fr $WORKING_DIR
                exit_cleanup 16
            else
                echo "the archive file is compatible with the currently installed HMC version, continuing..." >> $ARCHIVE_LOG
                echo "the archive file is compatible with the currently installed HMC version, continuing..." >> $LOG
            fi
        else
            echo "version check file does not exist on the local HMC, continuing..." >> $ARCHIVE_LOG
        fi
    else
        echo "an error occurred unpacking the version check file, bypassing..." >> $ARCHIVE_LOG
    fi
else
    echo "no version check file exists in the archive, continue normal processing..." >> $ARCHIVE_LOG
fi

# This almost belongs with feature 587785 above, but do not put this guard in place quite yet since
# may have to migrate to different models and modify existing files on the HMC (XF86Config, etc)
#echo -e "checking if restore allowed based on matching HMC machine type/model...\n" >> $LOG
#tar -tvzf $ARCHIVE | grep "opt/hsc/data/hmcmodel.dat" | awk '{print $6}' > $WORKING_DIR/check.list 2>> $ARCHIVE_LOG
#if [ $? -eq 0 ]; then
#    tar -xvzf $ARCHIVE --files-from=$WORKING_DIR/check.list --directory=$WORKING_DIR >> $ARCHIVE_LOG 2>&1
#    if [ $? -eq 0 ]; then
#        # unpack was ok in the $WORKING_DIR relative /opt/hsc/data dir, check this file against freshly installed file
#        if [ -f /opt/hsc/data/hmcmodel.dat ]; then
#            # both files exist, compare them for version stamping info
#            doChecksum $WORKING_DIR/opt/hsc/data/hmcmodel.dat /opt/hsc/data/hmcmodel.dat
#            if [ $? -ne 0 ]; then
#                # machine type miscompare
#                echo -e "machine type/model miscompare detected, bypassing archive restoration...\n" >> $ARCHIVE_LOG
#                rm -fr $WORKING_DIR
#                exit_cleanup 16
#            fi
#        fi
#    fi
#fi







#
# build the list of all files that have a '.so' "extension" (except the library
# file search path cache, 'ld.so.cache' )
#
grep "\.so" $WORKING_DIR/tar.list | grep -v "ld.so.cache" | awk '{print $6}' > $WORKING_DIR/exclude.list 2>> $ARCHIVE_LOG
if [ $? -ne 0 ]; then
     # pointless - 'awk' will always rc=0...
     rm -fr $WORKING_DIR

     echo "unable to generate the exclude file list. Exiting now, rc=13" >> $ARCHIVE_LOG
     exit_cleanup 13
fi

#
# Add the 'tar' command itself here. We'll restore file this with a cp/mv sequence
# when the 'tar' command has completed executing
#
grep -w "/bin/tar" $WORKING_DIR/tar.list
if [ $? -eq 0 ]; then
    echo "/bin/tar" >> $WORKING_DIR/exclude.list 2>> $ARCHIVE_LOG
fi

#
# Another special case for Squadrons here - '/bin/bash' will also not un-tar as part of
# the main body of files to unpack.  Add to exclude processing list...
#
grep -w "/bin/bash" $WORKING_DIR/tar.list
if [ $? -eq 0 ]; then
    echo "/bin/bash" >> $WORKING_DIR/exclude.list 2>> $ARCHIVE_LOG
fi

#
# Yet more file exclusions - defect 639341. Here, the tester notes that files in the sysvinit RPM
# packages are 1) first being back'd up (due to user error with setting the HMC date/time) and 2)
# upon unpacking, they received the all to common 'tar' error -> tar: <file>: Cannot open: Text file busy
#
# Very interesting why this issue is now showing up with the following list of files:
#
# /sbin/syslogd
# /sbin/init
# /bin/gzip
# /sbin/klogd
# /sbin/udevd
#
# Odd why the OS never tripped on these files all these years prior to this...
SYSVINIT_FILES="/sbin/syslogd
/sbin/init
/bin/gzip
/sbin/klogd
/sbin/udevd
/sbin/dhclient"

for file in $SYSVINIT_FILES
do
    grep -wq $file $WORKING_DIR/tar.list
    if [ $? -eq 0 ]; then
        echo "special file, $file, detected in archive - process accordingly..." >> $ARCHIVE_LOG
        # file was backed up. Ensure the file goes through special processing...
        echo $file >> $WORKING_DIR/exclude.list 2>> $ARCHIVE_LOG
    fi
done

echo "exclude file processing list constructed, continuing..." >> $ARCHIVE_LOG


#
# Next step is to un-tar only the previously excluded files to the
# staging area.
#
# Bypass the cache file containg references to the prior list of libraries
# residing in the directories listed in /etc/ld.so.conf.  We will dynamically
# regenerate this file using 'ldconfig' at end of 'tar'  processing
#
tar -xvzf $ARCHIVE --files-from=$WORKING_DIR/exclude.list --directory=$WORKING_DIR >> $ARCHIVE_LOG 2>&1
tarRC=$?
if [ $tarRC -ne 0 ]; then
     ARCHIVEFAIL=$tarRC
     echo "shared object 'tar' processing to working directory failed (rc = $tarRC), continuing..." >> $ARCHIVE_LOG
     echo "shared object 'tar' processing to working directory failed (rc = $tarRC), continuing..." >> $LOG
else
     echo "'tar' extraction of shared objects/misc files to working directory was successful, continuing..." >> $ARCHIVE_LOG
     echo "'tar' extraction of shared objects/misc files to working directory was successful, continuing..." >> $LOG
fi

#
# Now un-tar all remaining files from the archive, with a few exceptions
# The file "/.journal" may exist in some archives. 'tar' cmd will throw an
# error if this file is attempted to be unpacked
#
#echo "/opt/hsc/bin/restore" >> $WORKING_DIR/special.list
#echo "/etc/init.d/hmcRestore" >> $WORKING_DIR/special.list
echo "/var/hsc/log/restore.log" > $WORKING_DIR/special.list
echo "/var/hsc/log/restore.log.1" >> $WORKING_DIR/special.list
echo "/var/hsc/log/restore.log.2" >> $WORKING_DIR/special.list
echo "/var/hsc/log/hmcRestore.log" >> $WORKING_DIR/special.list
echo "/tmp/archive.log" >> $WORKING_DIR/special.list
echo "/.journal" >> $WORKING_DIR/special.list
echo "/" >> $WORKING_DIR/special.list


#
# Now do the un-tar of the majority of the archive file.
#
tar -xvzPf $ARCHIVE --overwrite --exclude-from=$WORKING_DIR/exclude.list --exclude-from=$WORKING_DIR/special.list >> $ARCHIVE_LOG 2>&1
tarRC=$?
if [ $tarRC -ne 0 ]; then
     ARCHIVEFAIL=$tarRC
     echo "remaining 'tar' archive processing failed (rc = $tarRC), continuing..." >> $ARCHIVE_LOG
     echo "remaining 'tar' archive processing failed (rc = $tarRC), continuing..." >> $LOG
else
     echo "remaining 'tar' archive file processing completed successfully." >> $ARCHIVE_LOG
     echo "remaining 'tar' archive file processing completed successfully." >> $LOG
fi


#
# Flush to disk, just in case
#   
sync

#
# The theory is here that we should now be referncing the archived library
# shared objects. Do this so we don't reference a file that is about to be
# replaced.
#
export LD_LIBRARY_PATH=$WORKING_DIR/lib:$WORKING_DIR/usr/lib

#
# Assuming this far, hopefully all files have been restored from the archive.
# Next step is to (pseudo-atomically?) relocate the *.so files.  We do this
# by 1) 'cp' the archive file to the *same filesystem* as it's current
# existing, version, then 2) 'mv' archived version to current version
#
# example: if archive file is '/tmp/file1.ext'...
# 1) copy '/tmp/restore/work/tmp/file1.ext' to '/tmp/file1.ext.stage',
# 2) move 'tmp/file1.ext.stage' to '/tmp/file1.ext'
#
# Note: Many of the *.so files will most likely be symbolic links, so
#       be sure NOT to follow them when copying
#
for i in `cat $WORKING_DIR/exclude.list`
do
      d=`/usr/bin/dirname $i`
      mkdir -p $d
      cp -d -v -p $WORKING_DIR$i $i.stage >> $ARCHIVE_LOG 2>&1
      if [ $? -ne 0 ]; then
           let CP_INDICATOR=CP_INDICATOR+1
      else
           # Continue with 'mv' only if 'cp' worked
           mv -vf $i.stage $i >> $ARCHIVE_LOG 2>&1
           if [ $? -ne 0 ]; then
                let MV_INDICATOR=MV_INDICATOR+1
           fi
      fi
done

# End 'tar' processing log
echo -e "end file recovery error log on `date`\n" >> $ARCHIVE_LOG
echo -e "file extraction from archive completed on `date`\n" >> $LOG


#
# Rebuild the library search path based on the prior /etc/ld.so.conf
# information and then remove the temporary override path
#
/sbin/ldconfig -v >> $LOG 2>&1
/sbin/ldconfig /usr/X11R6/lib/
export LD_LIBRARY_PATH=


#
# Additional cleanup - there is the possibility that the directories under /home
# (all the users' dirs) may have been re-generated via this restore process.
# Unfortunately, if the directory itself was not part of the archive, it will
# have been created with uid/gid of root/root as part of un-taring the actual
# files in those directories. This is not good since the users will not be able
# to access their home dirs! Change ownership of those subdirectories to the
# corresponding userID.
#
cd /home/
for user in *
do
     if [ -d $user ]
     then
       g=`/usr/bin/id -g -n $user`
       chown $user.$g $user
       chmod 755 $user
       
       # add per new subdirectories in users' home directories
       find $user -name "*" -type d ! -path $user/.ssh -exec chown ${user##/home/} {} \;
       
       echo "chown/chmod of $user /home directory completed" >> $ARCHIVE_LOG
     fi
done
cd /


#
# New requirement for RMC/MegaMouth. Set an indicator file so the 'ctrestore'
# script can be executed later (*after* SRC is started, do in hmcpotscfg) to
# unpack their data saved away in /var/ct.backup directory
#
if [ -d /var/ct.backup ]; then
    touch /var/hsc/log/restoreRMC
    echo -e "\nRMC indicator file set for 'ctrestore' script execution." >> $LOG
fi


if [[ $CP_INDICATOR -eq 0 && $MV_INDICATOR -eq 0 ]]; then
     echo "Restore processing of excluded file list was successful, ARCHIVEFAIL is $ARCHIVEFAIL." >> $LOG
   
     rm -f $IQYBCRIT
     echo "restore indicator file removed from HMC" >> $LOG
else
     echo -e "Restore processing of excluded file list was not successful.\n" >> $LOG
     echo "cp indicator is: $CP_INDICATOR" >> $LOG
     echo -e "mv indicator is: $MV_INDICATOR\n" >> $LOG

     echo "----- begin exclude file list -----" >> $LOG
     x=`cat /tmp/restore/work/exclude.list`
     echo "$x" >> $LOG
     echo "----- end exclude file list -----" >> $LOG
   
     ARCHIVEFAIL=127
     exit_cleanup 15
fi

# all done!
exit_cleanup 0
