#!/sbin/sh
#------------------------------------------------------------------#
#
# HPUX_ID: @(#) $Revision: 11.4 $ generated on Tue Oct 26 13:07:19 EDT 1999
#
# (c)Copyright 1983-1999 Hewlett-Packard Co.,  All Rights Reserved.
#
#------------------------------------------------------------------#
# SD postinstall script template for 11.X patches.                 #
#------------------------------------------------------------------#
# This file is optional for all 11.X patches.  The purpose of this #
# script is to prepare for a kernel build when required by the     #
# install conditions.  The script can also drive events that must  #
# occur before a system reboot occurs.                             #
#------------------------------------------------------------------#

_PATCHID=PHKL_20169

UTILS="/usr/lbin/sw/control_utils"

if [ ! -f $UTILS ]; then
    echo "ERROR:   Cannot find $UTILS"
    exit 1
fi

. $UTILS
exitval=$SUCCESS

#####
##### Insert any code you may require at this point in the script.
##### Pay attention to the exitval variable and set appropriately
##### in your code.  If you are unsure as to what types of operations
##### are legal in this file and what types aren't, consult the 
##### "Guidelines for SD Control Scripts" document.
#####
##### START_CUSTOMIZATION_HERE

# START OF INSERTED PATCH CODE

# This section is intended to install the new hpux(1M) in the lif area of
# the boot disks on the system.

MONGOOSE_DEBUG="y"
MONGOOSE_DEBUG=""

SAVE_DIRECTORY="${SW_ROOT_DIRECTORY}var/adm/sw/save_custom/$_PATCHID/"
_SAVEFILE_PREFIX="p${_PATCHID#PHKL_}"

TEMP_FILE1=/tmp/sh1$$

# This patch continues at the routine Main code.

# NOTE: Main code is not really a function, it is where the code
#       continues after all the functions.  Search on "Main code".


#
# BEGIN_DESC
#
# Name:
#       ECHO_MSG1 - display the log file and the message
#
# Synopsis:
#       ECHO_MSG1 "the message"
#
# Description:
#       ECHO_MESG1() displays the log file specified in TEMP_FILE1
#       and if the variable MONGOOSE_DEBUG is not NULL will display
#       the message in the first parameter.
#
# Entry Parameters:
#       $1 - The message to display.
#
# Exit Parameters:
#       None.
#
# Return Value:
#       None.
#
# Globals Referenced:
#       MONGOOSE_DEBUG - Display debug messages if not null.
#
# Local Variables:
#       None.
#
# Algorithm:
#       1) Display any messages in the log file.
#       2) Display the message in $1 if MONGOOSE_DEBUG is not set to
#          NULL?
#
# END_DESC
#

ECHO_MSG1()
{
    if [[ -s ${TEMP_FILE1} ]]
    then
        echo "NOTE:    The log is:"

#       Display the information with 9 spaces in front of each line
#       to conform with control script specifications of messages
#       starting in column 10.

        awk '{ printf("         %s\n", $0) }' ${TEMP_FILE1}

        rm -f ${TEMP_FILE1}
    fi

    if [[ -n $MONGOOSE_DEBUG ]]
    then
        echo "$1"
    fi
}


#
# BEGIN_DESC
#
# Name:
#       build_preserves - builds a list of files to preserve
#
# Synopsis:
#       build_preserves disk_device
#
# Description:
#       build_preserves() builds a list of files to preserve in the
#       specified boot device.  The files FS, SWAP and HPUX are
#       excluded because HPUX is being updated and mkboot does not
#       preserve FS and SWAP because of their size.
#
# Entry Parameters:
#       $1 - The disk being updated.
#
# Exit Parameters:
#       None.
#
# Return Value:
#        0 - Success.
#       43 - No files in the lif on disk $1.
#
# Globals Referenced:
#       LIF_FILES - Holds the list of files to preserve.
#       PRESERVES - Holds the list of files to preserve with "-p"
#                   in front of each file name.
#
# Local Variables:
#       LIF_ENTRY - The name of a file being processed.
#
# Algorithm:
#       1) Copy each file name to the variable PRESERVES and prepend
#          -p to each name.  The names FS, SWAP and HPUX are not
#          copied because HPUX is going to be replaced and FS and
#          SWAP are not really files but are reserved areas of the
#          disk that should not be modified.
#
# END_DESC
#

build_preserves()
{
#   Remove the entries for FS, SWAP (if they exist) and HPUX.
#   Do not try to perserve FS and SWAP, you will get all the disk space
#   they specify, so mkboot is expected to not let you perserve them.

    PRESERVES=""
    for LIF_ENTRY in $LIF_FILES
    do
        case $LIF_ENTRY in
            FS|SWAP|HPUX)
                ;;
            *)
                PRESERVES="$PRESERVES -p $LIF_ENTRY"
                ;;
        esac
    done

    if [ -z "${PRESERVES}" ]
    then
        ECHO_MSG1 "WARNING: No files in the lif on disk $1 (43)."
        return 43
    fi

    return 0
}


#
# BEGIN_DESC
#
# Name:
#       update_disk - update the lif area of a boot disk with the
#                     specified version of hpux(1M).
#
# Synopsis:
#       update_disk device_file_path
#
# Description:
#       update_disk() updates the hpux(1M) command in the lif area
#       of a boot disk.
#
# Entry Parameters:
#       $1 - The disk to update.
#
# Exit Parameters:
#       None.
#
# Return Value:
#        0 - Success.
#       22 - Device is not a block device or character device.
#       23 - Cannot find a lif area on the disk.
#       24 - Unable to install hpux(1M) to the lif area of the disk.
#       ?? - Errors from find_create_lif() and build_preserves().
#
# Globals Referenced:
#       CMD_STATUS         - Holds the status of the last command.
#       MKBOOT             - Points to the mkboot command.
#       LIF_FILES          - Holds the name of the files in the lif
#                            on disk.
#       LIFLS              - Points to the lifls command.
#
# Local Variables:
#       None.
#
# Algorithm:
#       1) Check if this a block device or character device?
#       2) Check if there is a lif area on the disk.
#       3) Call find_create_lif() to save the existing lif.
#       4) Call build_preserves() to get a list of files to
#          preserve.
#       5) Update the disk.
#
# END_DESC
#

update_disk()
{
#   Is this a block device or character device?

    if [[ ! -b "$1" ]] && [[ ! -c "$1" ]]
    then
        ECHO_MSG1 "WARNING: $1 is not a block device or character device (22)."
        return 22
    fi

#   Is there a lif area on this disk?

    LIF_FILES=`${LIFLS} $1 2> ${TEMP_FILE1}`
    CMD_STATUS=$?
    if [[ ${CMD_STATUS} -ne 0 ]]
    then
        ECHO_MSG1 "WARNING: Cannot find a lif area on $1 (23)."
        return 23
    fi

#   Save existing lif.

    find_create_lif $1
    CMD_STATUS=$?
    if [[ ${CMD_STATUS} -ne 0 ]]
    then
        return ${CMD_STATUS}
    fi

#   Build a list of all the files to preserve.

    build_preserves $1
    CMD_STATUS=$?
    if [[ ${CMD_STATUS} -ne 0 ]]
    then
        rm -f ${LIF_NAME}
        return ${CMD_STATUS}
    fi

#   Update the boot disk with the new hpux(1M).

    if [[ ${BOOTDEV} = "$1" ]]
    then
        ${MKBOOT} \
                ${U_OPT} -i HPUX $PRESERVES $1 > ${TEMP_FILE1} 2>&1
    else
        ${MKBOOT} \
                         -i HPUX $PRESERVES $1 > ${TEMP_FILE1} 2>&1
    fi
    CMD_STATUS=$?

    if [[ ${CMD_STATUS} -ne 0 ]]
    then
        rm -f ${LIF_NAME}
        ECHO_MSG1 "WARNING: Unable to install hpux(1M) to the lif area of \c"
        ECHO_MSG1 "the disk (25)."
        return 25
    fi

    return 0
}


#
# BEGIN_DESC
#
# Name:
#       find_create_lif - copy the current hpux(1M) from the boot
#                         lif to a lif file
#
# Synopsis:
#       find_create_lif device_file_path
#
# Description:
#       find_create_lif() creates a lif and copies hpux(1M) from the
#       lif on the disk to the new lif.
#
# Entry Parameters:
#       $1 - The boot disk.
#
# Exit Parameters:
#       None.
#
# Return Value:
#        0 - Success.
#       63 - Could not create a lif to save the original hpux(1M).
#       64 - Could not save the original hpux(1M).
#
# Globals Referenced:
#       CMD_STATUS        - Holds the status from the lif command.
#       LIFCP             - Points to the lifcp command.
#       LIF_NAME          - The name of the lif to restore.
#       LIFINIT           - Points to the lifinit command.
#       SAVE_DIRECTORY    - The directory the lif files are saved in.
#       _SAVEFILE_PREFIX  - Prefix to start the file name with.
#       SW_ROOT_DIRECTORY - The root directory.  Expected to be "/".
#
# Local Variables:
#       TEMP1             - Holds the second part of the name of the
#                           file that the original hpux(1M) is saved
#                           in.  The name is the device name.  i.e.
#                           c0t4d0.
#       _PATCHID          - The ID number for this patch.
#
# Algorithm:
#       1) Create the name of the lif file.
#       2) Make the directory to hold the lif file if the directory
#          does not exist.
#       3) Create the lif file.
#       4) Copy hpux(1M) on the boot disk to the lif file.
#
# END_DESC
#

find_create_lif()
{
#   Create the name of the lif file.

    TEMP1=`basename $1`
    LIF_NAME="${SAVE_DIRECTORY}${_SAVEFILE_PREFIX}.${TEMP1}"

#   Make the directory to save the lif file in.

    if [[ ! -d ${SAVE_DIRECTORY} ]]
    then
        rm -f    ${SAVE_DIRECTORY}
        mkdir -p ${SAVE_DIRECTORY}
    fi

#   Create the lif to hold the original hpux(1M).

    ${LIFINIT} -e44584 -l61440 -s4096 -v5000000 -d16 -nISL10 -K2 ${LIF_NAME} \
                                                        > ${TEMP_FILE1} 2>&1 
    CMD_STATUS=$?
    if [ ${CMD_STATUS} -ne 0 ]
    then
        rm -f ${LIF_NAME}
        ECHO_MSG1 "WARNING: Could not create a lif to hold the original \c"
        ECHO_MSG1 "hpux(1M) (63)."
        return 63
    fi

#   Copy hpux(1M) from the boot lif to the lif file.

    ${LIFCP} -K2 $1:HPUX ${LIF_NAME}:HPUX > ${TEMP_FILE1} 2>&1
    CMD_STATUS=$?
    if [ ${CMD_STATUS} -ne 0 ]
    then
        rm -f ${LIF_NAME}
        ECHO_MSG1 "WARNING: Could not save hpux(1M) from the boot area \c"
        ECHO_MSG1 "of disk $1 (64)."
        return 64
    fi

    return 0
}


#
# BEGIN_DESC
#
# Name:
#       install_control - controls the installation of a new version
#                         of hpux(1M) into the lif area of boot disks.
#
# Synopsis:
#       None.  Just fall into the code.
#
# Description:
#       install_control() installs the hpux(1M) command from
#       uxbootlf (in the /usr/lib directory) into the lif area of
#       boot disks.  The list of boot disks is contained in the file
#       bootconf (in the stand directory) or obtained with
#       lvlnboot(1M).
#
#       The original hpux(1M) of each boot disk will be saved if
#       this is a update, not a cold install.  The boot lif area of
#       each boot disk will be updated with the new version of
#       hpux().
#
#       The bootconf file will be searched for boot disk entries.
#       Each entry will be checked to see if it is valid.  If the
#       entry is valid, the new version of the hpux(1M) program will
#       be installed in the boot lif area of the disk specified by
#       the entry.
#
# Globals Referenced:
#       BOOTCONF           - Points to the bootconf file.
#       ERROR_CHECK        - Holds various error values.
#       LIFCP              - Points to the lifcp command.
#       LIFINIT            - Points to the lifinit command.
#       LIFLS              - Points to the lifls command.
#       MKBOOT             - Points to the mkboot command.
#       SW_ROOT_DIRECTORY  - The root directory.  Expected to be "/".
#       SW_INITIAL_INSTALL - When this variable is set to "1", the
#                            swinstall session is being run as the
#                            back end of an initial system software
#                            installation ("cold" install).  This
#                            variable is unset at all other times.
#
# Local Variables:
#       BOOTDEV            - Holds the boot disk device path.
#       JUNK               - Holds anything on the line after the
#                            operation and device.
#       OPERATION          - Holds the operation.  Operations are l,
#                            p and w.
#
# Algorithm:
#       1) Verify that the following commands/files exist:
#               mkboot, bootconf, lifcp, lifinit and lifls.
#       2) Setup to read the bootconf file.
#       3) Setup a endless loop.
#               4) Read a line of the bootconf file.
#               5) If not a good read, assume a EOF and break out of
#                  the loop.
#               6a) If the operation is l, call lvlnboot(1M) to get
#                   a list of disks to update.  Call update_disk
#                   with each disk as the parameter.  Continue with
#                   the loop.
#               6b) If the operation is p or w, call update_disk
#                   with the disk as the parameter.  Continue with
#                   the loop.
#               6c) If the operation is not l, p or w, ignore it and
#                   continue with the loop.
#
# END_DESC


# This section of the file will control the updating the boot lif.

# Make sure the following commands/files exist.
#
#       mkboot
#       ${SW_ROOT_DIRECTORY}stand/bootconf
#       lifcp
#       lifinit
#       lifls

install_control()
{
    ERROR_CHECK=$SUCCESS

    MKBOOT=mkboot
    whence $MKBOOT > ${TEMP_FILE1} 2>&1
    if [[ $? -ne 0 ]]
    then
        ECHO_MSG1 "ERROR:   Cannot find the command $MKBOOT (90)."
        ERROR_CHECK=90
    fi

    BOOTCONF=${SW_ROOT_DIRECTORY}stand/bootconf
    if [[ ! -f $BOOTCONF ]]
    then
        ECHO_MSG1 "ERROR:   Cannot find the file $BOOTCONF (91)."
        ERROR_CHECK=91
    fi

    LIFCP=lifcp
    whence $LIFCP > ${TEMP_FILE1} 2>&1
    if [[ $? -ne 0 ]]
    then
        ECHO_MSG1 "ERROR:   Cannot find the command $LIFCP (92)."
        ERROR_CHECK=92
    fi

    LIFINIT=lifinit
    whence $LIFINIT > ${TEMP_FILE1} 2>&1
    if [[ $? -ne 0 ]]
    then
        ECHO_MSG1 "ERROR:   Cannot find the command $LIFINIT (93)."
        ERROR_CHECK=93
    fi

    LIFLS=lifls
    whence $LIFLS > ${TEMP_FILE1} 2>&1
    if [[ $? -ne 0 ]]
    then
        ECHO_MSG1 "ERROR:   Cannot find the command $LIFLS (94)."
        ERROR_CHECK=94
    fi

    if [[ ${ERROR_CHECK} -ne 0 ]]
    then
#
#       If this is a update, the existing hpux(1M) can still be used,
#       so, just issue a warning.
#
#       If this is a install, there is no existing hpux(1M) that can
#       be used, so issue a error.
#
        if [[ ${SW_INITIAL_INSTALL} -ne 1 ]]
        then
            echo "WARNING: Unable to process hpux(1M),"
            echo "         due to a missing command (${ERROR_CHECK})."
            exit $WARNING
        else
            echo "ERROR:   Unable to process hpux(1M),"
            echo "         due to a missing command (${ERROR_CHECK})."
            exit $FAILURE
        fi
    fi


# Search the bootconf file for boot disks entries.
# The entries should be specified by a l, p or w and be followed
# by a space and the device file path.
# e.g.
#
# l /dev/dsk/c0t2d0
# p /dev/dsk/c0t4d0
# w /dev/dsk/c0t6d0
#
# All other entries are ignored.

# Open the bootconf file.

    exec 9<${BOOTCONF}

    ERROR_CHECK=$SUCCESS

    while ( true )
    do
        read -u9 OPERATION BOOTDEV JUNK
        READ_STATUS=$?
        if [[ ${READ_STATUS} -ne 0 ]]
        then            # If the status is non zero, assume end of file and
            break       # quit searching.
        fi

        case ${OPERATION} in
            l)
                U_OPT=""        # Only use the -u option on non LVM disks.
                DEVICES=`/usr/sbin/lvlnboot -v | \
                            awk '$4 ~ "Boot" && $5 ~ "Disk" { print $1 }'`
                for LVMBOOTDEV in $DEVICES
                do
                    update_disk ${LVMBOOTDEV}
                    if [[ $? -eq 0 ]]
                    then
                        echo "NOTE:    Successfully updated disk ${LVMBOOTDEV}."
                    else
                        if [[ ${SW_INITIAL_INSTALL} -ne 1 ]]
                        then
#
#                           If a failure has not occured, set ERROR_CHECK to
#                           indicate a warning.
#
                            if [[ $ERROR_CHECK -ne $FAILURE ]]
                            then
                                ERROR_CHECK=$WARNING
                            fi
                            echo "WARNING: Unable to install the boot \c"
                            echo "on disk ${LVMBOOTDEV}."
                        else
#
#                           Set ERROR_CHECK to indicate a ERROR.
#
                            ERROR_CHECK=$FAILURE
                            echo "ERROR:   Unable to install the boot \c"
                            echo "on disk ${LVMBOOTDEV}."
                        fi
                    fi
                done
                ;;
            p|w)
                U_OPT="-u"      # Only use the -u option on non LVM disks.
                update_disk ${BOOTDEV}
                if [[ $? -eq 0 ]]
                then
                    echo "NOTE:    Successfully updated disk ${BOOTDEV}."
                else
                    if [[ ${SW_INITIAL_INSTALL} -ne 1 ]]
                    then
#
#                           If a failure has not occured, set ERROR_CHECK to
#                           indicate a warning.
#
                        if [[ $ERROR_CHECK -ne $FAILURE ]]
                        then
                            ERROR_CHECK=$WARNING
                        fi
                        echo "WARNING: Unable to install the boot \c"
                        echo "on disk ${BOOTDEV}."
                    else
#
#                           Set ERROR_CHECK to indicate a ERROR.
#
                        ERROR_CHECK=$FAILURE
                        echo "ERROR:   Unable to install the boot \c"
                        echo "on disk ${BOOTDEV}."
                    fi
                fi
                ;;
            *)
                ;;
            esac
    done
}

# Main code.

#
# This section of code is intended to prevent the execution
# of 11.X commands using a non 11.X kernel by just returning
# a zero, so it looks like the patch is installed, even 
# thought the patch is not install.
#
# The problem happens during an update, where the new commands
# have been installed, but the kernel has not been updated.
# The lvlnboot(1M) command fails in this situation.
#

RELEASE_IS=`uname -r`

case ${RELEASE_IS} in
	B.11.*)
		;;	# Continue, this is "B.11.*".
	*)
		return 0
		;;	# Do not continue, this is not "B.11.*".
esac

install_control

rm -f ${TEMP_FILE1}

# If this is an update, try to remove the directory with a rmdir(1M).
# If there are no files left in the directory, the directory will
# be removed.
#
if [[ "${SW_INITIAL_INSTALL}" -ne 1 ]]
then
    rmdir ${SW_ROOT_DIRECTORY}var/adm/sw/save_custom/$_PATCHID > /dev/null 2>&1
    rmdir ${SW_ROOT_DIRECTORY}var/adm/sw/save_custom > /dev/null 2>&1
fi

exitval=$ERROR_CHECK

# END OF INSERTED PATCH CODE

exit $exitval
