#!/bin/sh5
#
#     fisprep       ULTRIX/FIS Preparation/Control Script
#
#               Copyright (c) 1989, 1990 by
#          Digital Equipment Corporation, Maynard, MA
#               All rights reserved.
#
#     This software is furnished under a license and may be used and
#     copied  only  in accordance with the terms of such license and
#     with the  inclusion  of  the  above  copyright  notice.   This
#     software  or  any  other copies thereof may not be provided or
#     otherwise made available to any other person.  No title to and
#     ownership of the software is hereby transferred.          
#
#     The information in this software is subject to change  without
#     notice  and should not be construed as a commitment by Digital
#     Equipment Corporation.                         
#
#     Digital assumes no responsibility for the use  or  reliability
#     of its software on equipment which is not supplied by Digital.
#
#     @(#)fisprep	7.1	(ULTRIX)	7/22/92
#
#     Modification History:
#     ~~~~~~~~~~~~~~~~~~~~
#
#     V1.0 Jon Wallace                      28-Jun-1990
#
#          Created.
#
#     V1.1 James C. Overman                 02-Aug-1990
#
#          Added notification via mail when client is finished.
#
#     V1.2 George A. Withers, Jr.           17-Oct-1990
#
#          Various modifications made to bring script up to ULTRIX/FIS
#          V2.0 criteria.  Included was, invokation of fissizer, fisconfig,
#          and fiscleanup.
#
#     Code Description:
#     ~~~~~~~~~~~~~~~~
#
#          This shell script is executed by the /etc/rc file as the 
#          ULTRIX/FIS client is being booted.  It serves as the main
#          controlling script of the ULTRIX/FIS process.  From here,
#          the tifis information is read in and the various config
#          and sizer scripts are called.
#
#          This script takes thirty seconds to execute on a VAXstation
#          2000 with 6Mb of memory.  
#
#     Inputs:
#     ~~~~~~
#
#          The FISINIT file generated by the tifis software.  This info
#          includes server, ethernet address, image to be loaded, serial
#          number, and information on if the system is a Sidecar or not.
#          If so, we also include the target systems memory size.
#
#     Outputs:
#     ~~~~~~~
#
#          The primary output of this script is a complete logfile of the
#          ULTRIX/FIS process stored in the LOGS directory on the server.
#          The script is the overall controller in the ULTRIX/FIS process
#          and calls several subordinate scripts to perform the actual work.
#
#     Usage:
#     ~~~~~
#
#          fisprep [-d] [-q] [-x] [-test]
#
#          This script is virtually never called manually, but when it
#          is desired to be so, the -d switch enables debug messages,
#          -q disables them, and -x enables the set -x functionality.
#
#          To execute the script in debug to receive tracing 
#          messages during execution, set the environment variable
#          DEBUG to TRUE.  From /bin/csh, this is:
#
#               csh> setenv DEBUG TRUE
#
#          To disable DEBUG, simply set the DEBUG variable to
#          FALSE.  Optionally, you can perform the same function by
#          specifying a -d option to fissizer.  To specify no debug
#          messages, specify -q.  
#
#          set -x tracing is enabled by utilizing the -x switch.  The
#          -test switch will force -test execution of the fisld
#          script.  This is used during early fisprep debug.
#
##############################################################################

##############################################################################
#     --     Assign various values and get some information
##############################################################################

REVINFO='Version 1.2'
HOME=/usr/users/fis
USER=`/usr/ucb/whoami`
MACHINE=`/bin/machine`
HOST=`/bin/hostname`
CWD=`/bin/pwd`
PROG="$0"
INVOKE_FLAG=""
MINIMUM_RUN="FALSE"

##############################################################################
#     --     Trap user interrupts during processing
##############################################################################

trap '
while :
do
     echo "$PROG: Do you really want to quit? (y/n) []: \c"
     read trap_answer
     case $trap_answer
     in
          [yY]* )
               echo "$PROG: Operation aborted."
               if [ "$DEBUG" = "TRUE" ]
               then
                    echo "$PROG: Stopped: `date` ($REVINFO)"
               fi
               exit 1;;
          [nN]* )
               break;;
          * )
               continue;;
     esac
done ' 1 2 3 18

# Parse thru command line arguments.  They are minimal.  Only a -d will
# do and that will enable debug messages.

while [ "$#" -gt 0 ]
do
     case $1
     in
          -d )     
               DEBUG=TRUE
               shift;;
          -q )     
               DEBUG=FALSE
               INVOKE_FLAG="-q"
               shift;;
          -x )     
               set -x
               shift;;
          -test )
               MINIMUM_RUN="TRUE"
               shift;;
          * )      
               echo "Usage: fisprep [-d] [-q] [-x]"
               echo "  -d  enable debug trace messages"
               echo "  -q  disable debug trace messages"
               echo "  -x  enable \"set -x\" functionality"
               exit 1;;
     esac                  
done

# If DEBUG start message saying we've begun.

if [ "$DEBUG" = "TRUE" ]
then
     INVOKE_FLAG="-d"
     echo "$PROG: Started: `date` ($REVINFO)"
fi



##############################################################################
#     --     Initialize lots of environment variables
##############################################################################

# This function will initialize all of the environment variables needed for
# the ULTRIX/FIS process.

Initialize_Variables()
{

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Executing the Initialize_Variables() Function"
     fi

# Set up console environment for this process.

     if [ "$MINIMUM_RUN" = "FALSE" ]
     then
          exec </dev/console >/dev/console 2>&1
          stty ignbrk
     fi
     PATH=.:/etc:/bin:/usr/bin:/usr/ucb
     export PATH
     term=VT100
     export TERM
     /bin/stty crt

# Set up initial environment variables.

     DFS="$IFS"
     CLIENT=`/bin/hostname`               # client name
     FISINITPATH=$HOME/FISINIT            # client info lives here
     SERVER=`/etc/mount | /usr/ucb/head -1 | /usr/bin/cut -d":" -f1`
     MAIL_TO="fis@${SERVER}"

# Confirm existence of the fisinit file and fill various environment 
# variables with the information from it.  Finally, export them.

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Reading tifis information from fisinit file"
     fi

     [ -s $FISINITPATH/$CLIENT.fisinit ] ||
     {
          echo "$PROG: Cannot read $CLIENT initialization file."
          echo "$PROG: Operation aborted."
          if [ "$DEBUG" = "TRUE" ]
          then
               echo "$PROG: Stopped: `date` ($REVINFO)"
          fi
          exit 1
     }

# Read in the tifis (FISINIT) data

     FISDATA=`cat $FISINITPATH/$CLIENT.fisinit`
     IFS=:
     set $FISDATA
     SERVER=$1                            # name of server
     SN=$2                                # machine serial number
     HWA=$3                               # machine hardware address
     IMAGEPATH=$4                         # FIS image to be loaded
     COW_SIDECAR=$5                       # Sidecar [TRUE|FALSE]
     COW_PM=$6                            # Memory of Sidecar
     DBGFLAG=$7                           # Debug status for tifis
     export CLIENT SERVER IMAGEPATH COW_SIDECAR COW_PM SN

# If tifis was run DEBUG then we will assume all else should be run in
# DEBUG unless the "-q" flag is up.

     if [ "$INVOKE_FLAG" != "-d" ] && [ "$DBGFLAG" = "TRUE" ]
     then
          if [ "$INVOKE_FLAG" != "-q" ]
          then
               DEBUG="TRUE"
               INVOKE_FLAG="-d"
               echo "$PROG: Started: `date` ($REVINFO)"
               echo "$PROG: Executing the Initialize_Variables() Function"
               echo "$PROG: Debug flag set from tifis control"
          fi
     fi

# Confirm existence of the Image Partition file and fill various environment 
# variables with the information from it.  Finally, export them.

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Reading image information from sizes file"
     fi

     [ -s $IMAGEPATH/Sizes.info ] ||
     {
          echo "$PROG: Cannot read $IMAGEPATH partition size info file."
          echo "$PROG: Operation aborted."
          if [ "$DEBUG" = "TRUE" ]
          then
               echo "$PROG: Stopped: `date` ($REVINFO)"
          fi
          exit 1
     }

# Read in the disk partition sizes

     PARTDATA=`cat $IMAGEPATH/Sizes.info`
     IFS=:
     set $PARTDATA
     ROOT_SIZE=$1
     USR_SIZE=$2
     USERS_SIZE=$3
     EXCESS_SIZE=$4
     export ROOT_SIZE USR_SIZE USERS_SIZE EXCESS_SIZE
     
# Assign and export various environment variables

     PID=$$                               # this process id
     ERRFLAG=0                            # flag that detects process errors
     LOGPATH=$HOME/LOGS                   # log directory
     LOGTOOL=$HOME/TOOLS/log              # file that does the logging
     LOGDATE=`date +%y_%m_%d-%T`          # date format used for log name
     LOGNAME="${SN}-${LOGDATE}.log"       # log file that tracks entire process
     ERRFILE="${SN}-${LOGDATE}.err"       # log file that tracks process errors
     STARTDATE=`date +%d-%h-19%y,%T`      # date format used to get system errs

     export LOGPATH LOGNAME ERRFILE

# Announce that the process has begun and display some initial information.

     IFS="$DFS"
     echo "
*** ULTRIX/FIS MANUFACTURING PROCESS ***" | tee ${LOGPATH}/${LOGNAME}
     echo "
Configuration data for this FIS manufacturing session:

SERIAL NUMBER         $SN
HARDWARE ADDRESS      $HWA
SERVER                $SERVER
CLIENT                $CLIENT
FIS IMAGE LOADED      $IMAGEPATH
LOG FILE NAME         $LOGNAME " | tee -a ${LOGPATH}/${LOGNAME}
}



##############################################################################
#     --     Execute the fissizer script
##############################################################################

# This function will call fissizer to generate information about the actual
# client system.

Execute_fissizer()
{

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Executing the Execute_fissizer() Function"
     fi

# Execute fissizer and report if any errors were found.

     cd $HOME
     if [ "$MINIMUM_RUN" != "TRUE" ]
     then
          fissizer $INVOKE_FLAG | tee -a ${LOGPATH}/${LOGNAME}
     else
          if [ -s /tmp/$HOST.fisdisks ] && [ -s /tmp/$HOST.fisconfig ]
          then
               if [ "$DEBUG" = "TRUE" ]
               then
                    echo "$PROG: Using existing sizer output"
               fi
               echo "0" >/tmp/$HOST.fiserror
          else
               fissizer $INVOKE_FLAG | tee -a ${LOGPATH}/${LOGNAME}
          fi
     fi
     RETSTATUS=`cat /tmp/$HOST.fiserror`
     case $RETSTATUS
     in
          0 )
               break;;
          * )
               echo "
$PROG: Errors found during fissizer script" | tee -a ${LOGPATH}/${LOGNAME}
               echo "$PROG: Operation Aborted." | tee -a ${LOGPATH}/${LOGNAME}
               ERRFLAG=1
               Check_For_Errors
               Mail_Completion_Status
               if [ "$DEBUG" = "TRUE" ]
               then
                    echo "$PROG: Stopped: `date` ($REVINFO)"
               fi
               exit 1;;
     esac

# Assign some variables from the fissizer run.

     FSSIZCFG=`cat /tmp/$CLIENT.fisconfig`
     set $FSSIZCFG
     MACHTYPE=$2
     CPUTYPE=$3
     if [ "$COW_SIDECAR" = "TRUE" ]
     then
          PHYSMEM=$COW_PM
     else
          PHYSMEM=$4
     fi
     export $MACHTYPE
}



##############################################################################
#     --     Execute the fisconfig script
##############################################################################

# This function will call fisconfig to determine the target system disk for
# the ULTRIX/FIS process.

Execute_fisconfig()
{

     if [ "$DEBUG" = "TRUE" ]
     then 
          echo "$PROG: Executing the Execute_fisconfig() Function"
     fi

# Execute fisconfig and report if any errors were found.

     cd $HOME
     fisconfig $INVOKE_FLAG | tee -a ${LOGPATH}/${LOGNAME}
     RETSTATUS=`cat /tmp/$HOST.fiserror`
     case $RETSTATUS
     in
          0 )
               break;;
          * )
               echo "
$PROG: Errors found during fisconfig script" | tee -a ${LOGPATH}/${LOGNAME}
               echo "$PROG: Operation Aborted." | tee -a ${LOGPATH}/${LOGNAME}
               ERRFLAG=1
               Check_For_Errors
               Mail_Completion_Status
               if [ "$DEBUG" = "TRUE" ]
               then
                    echo "$PROG: Stopped: `date` ($REVINFO)"
               fi
               exit 1;;
     esac
}



##############################################################################
#     --     Execute the fisld script
##############################################################################

# This function will call fisld to perform the actual transfer of information
# to the client from the server.

Execute_fisld()
{

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Executing the Execute_fisld() Function"
     fi

# Fill the TARGET_SYSTEM_DISK variable for ease of use by the operator.

     FISDISKS=`cat /tmp/$HOST.diskinfo`
     set $FISDISKS
     if [ "$1" = "1" ]
     then
          shift 1
          SYSDISK="$2($1)"
     else
          shift 1
          DISK1="$2($1)"
          shift 8
          SYSDISK="$DISK1/$2($1)"
     fi

# Add to the banner of client info by adding the target system disk
# and when the process started.

     echo "TARGET SYSTEM DISK    $SYSDISK
MACHINE TYPE          $MACHTYPE
CLIENT CPU TYPE       $CPUTYPE
PHYSICAL MEMORY       $PHYSMEM
DATE PROCESS STARTED  $STARTDATE " | tee -a ${LOGPATH}/${LOGNAME}

# Start fisld which will do the actual transfer of data bits.

     if [ "$MINIMUM_RUN" != "TRUE" ]
     then
          $HOME/fisld $INVOKE_FLAG | tee -a ${LOGPATH}/${LOGNAME}
     else
          $HOME/fisld $INVOKE_FLAG -test | tee -a ${LOGPATH}/${LOGNAME}
     fi

# We're back from fisld, so get a date stamp and write it to the log file.

     RETSTATUS=`cat /tmp/$HOST.fiserror`
     case $RETSTATUS
     in
          0 )
               break;;
          * )
               echo "
$PROG: Errors found during fisld script" | tee -a ${LOGPATH}/${LOGNAME}
               echo "$PROG: Operation Aborted." | tee -a ${LOGPATH}/${LOGNAME}
               ERRFLAG=1
               Check_For_Errors
               Mail_Completion_Status
               if [ "$DEBUG" = "TRUE" ]
               then
                    echo "$PROG: Stopped: `date` ($REVINFO)"
               fi
               exit 1;;
     esac
     ENDDATE=`date +%d-%h-19%y,%T`
     echo "\nDATE PROCESS ENDED    $ENDDATE" | tee -a ${LOGPATH}/${LOGNAME}
}



##############################################################################
#     --     Check for errors from either uerf or fisld
##############################################################################

# Grep thru the logfile to ensure that no errors were reported by fisld
# during the process.  Then, run uerf to confirm that there are no system
# errors recorded during the testing period.

Check_For_Errors()
{

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Executing the Check_For_Errors() Function"
     fi

# First, we check the logfile for any fisld process errors.

     [ -s ${LOGPATH}/${ERRFILE} ] &&
     {
          if grep -v -s lost+found ${LOGPATH}/${ERRFILE}
          then

# An error was found so set the ERRFLAG to notify the technician and write
# an informative message to the console."

               ERRFLAG=1
               echo "\n$PROG: Unexpected 'fisld' process errors\c"
               echo " occured while installing FIS software onto $MACHTYPE\c"
               echo ", serial number $SN, from $SERVER.\n"
               echo "Check the following file to determine the type of error\c"
               echo " that occured:\n"
               echo "          ${LOGPATH}/${LOGNAME}"
          fi

# Now, write the errors from the error file into the logfile for permenant
# storage.

          echo "\n
#################### FIS Process Errors Recorded Here #########################
" >> ${LOGPATH}/${LOGNAME}
          cat ${LOGPATH}/${ERRFILE} >> ${LOGPATH}/${LOGNAME}
          case $? in
               0 )
                    rm -f ${LOGPATH}/${ERRFILE}
                    ;;
               * )
                    echo "
$PROG: Could not append process error file to FIS log file (WARNING)."
                    ;;
          esac
     }

# Now, we check the system error log file for any system errors.  This check
# does not affect the ERRFLAG as any errors should have been caught above.
# Also, note we do not check the success of the append.

     echo "\n
#################### System Error Logger Recorded Here ########################
" >> ${LOGPATH}/${LOGNAME}

     uerf -t s:$STARTDATE e:$ENDDATE >> ${LOGPATH}/${LOGNAME}
}



##############################################################################
#     --     Execute the fiscleanup script
##############################################################################

# This function will call fiscleanup to perform cleanup functions such as
# updating the /etc/fstab file and printing the customer letter.

Execute_fiscleanup()
{

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Executing the Execute_fiscleanup() Function"
     fi

# Execute fiscleanup and report if any errors were found.

     cd $HOME
     if [ "$MINIMUM_RUN" != "TRUE" ]
     then
          fiscleanup $INVOKE_FLAG | tee -a ${LOGPATH}/${LOGNAME}
     else
          fiscleanup $INVOKE_FLAG -test | tee -a ${LOGPATH}/${LOGNAME}
     fi
     RETSTATUS=`cat /tmp/$HOST.fiserror`
     case $RETSTATUS
     in
          0 )
               break;;
          * )
               echo "
$PROG: Errors found during fiscleanup script" | tee -a ${LOGPATH}/${LOGNAME}
               echo "$PROG: Operation Aborted." | tee -a ${LOGPATH}/${LOGNAME}
               ERRFLAG=1
               Check_For_Errors
               Mail_Completion_Status
               if [ "$DEBUG" = "TRUE" ]
               then
                    echo "$PROG: Stopped: `date` ($REVINFO)"
               fi
               exit 1;;
     esac
}



##############################################################################
#     --     Mail the logfile to the technician
##############################################################################

# Mail the logfile to the technician interface account on the server.

Mail_Completion_Status()
{

     if [ "$DEBUG" = "TRUE" ]
     then
          echo "$PROG: Executing the Mail_Completion_Status() Function"
     fi

# If the ERRFLAG is set, make the technician press [Return] to help ensure
# the error is noted.  Otherwise, simply mail the log to the server fis
# account.

     case $ERRFLAG 
     in
          1 )
               MESSAGE="${CLIENT} failed to FIS - please read message"
               if [ "$MINIMUM_RUN" = "FALSE" ]
               then 
                    /usr/ucb/mail -v -s "${MESSAGE}" ${MAIL_TO} < ${LOGPATH}/${LOGNAME}
                    echo "\nPlease Press [Return] to continue: \c"
                    read resp
               else
                    echo "$PROG: ${MESSAGE}"
               fi
               cp ${LOGPATH}/${LOGNAME} $HOME/ARCHIVE/${LOGNAME}
               ;;
          * )
               MESSAGE="${CLIENT} has completed FIS installation - please check system" 
               if [ "$MINIMUM_RUN" = "FALSE" ]
               then
                    rm -f $FISINITPATH/$CLIENT.fisinit
                    echo "\nNow sending status mail to: ${MAIL_TO}"
                    /usr/ucb/mail -v -s "${MESSAGE}" ${MAIL_TO} < ${LOGPATH}/${LOGNAME}
               else
                    echo "$PROG: ${MESSAGE}"
               fi
               ;;
     esac
     if [ "$MINIMUM_RUN" != "TRUE" ]
     then
          rm -f /tmp/$CLIENT.fisdisks
          rm -f /tmp/$CLIENT.fisconfig
          rm -f /tmp/$CLIENT.Letter
          rm -f /tmp/$CLIENT.Fstab
          rm -f /tmp/$CLIENT.warning_swap
     fi
     rm -f /tmp/$CLIENT.diskinfo
     rm -f /tmp/$CLIENT.partinfo
     rm -f /tmp/$CLIENT.fsinfo
     rm -f /tmp/$CLIENT.imginfo
     rm -f /tmp/$CLIENT.fiserror
}



##############################################################################
#     --     Main Program Execution Starts Here
##############################################################################

Initialize_Variables
Execute_fissizer
Execute_fisconfig
Execute_fisld
Check_For_Errors
Execute_fiscleanup
Mail_Completion_Status

if [ "$DEBUG" = "TRUE" ]
then
     echo "$PROG: Stopped: `date` ($REVINFO)"
fi

cd $CWD
if [ "$MINIMUM_RUN" = "FALSE" ]
then
     sleep 5
     /etc/halt
fi
exit 0
