#!/bin/ksh

#################################################################################################
#
# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#	Copyright 1992-95 AT&T Global Information Solutions
#
#pragma ident	"@(#)luupgrade.sh	5.68	06/03/29 SMI"
# 
# luupgrade is used to perform a variety of software installation and
# upgrade functions to a target (inactive) boot environment:
# 
# --> Upgrade operating system.
# --> Install operating system from flash archive.
# --> Add, remove, check, and get information on packages.
# --> Add and remove patches.
# --> Check installation media and report contents found.
# --> Install applications.
# 
# It is intended to be called once an ABE is created and populated,
# allowing the system administrator to perform necessary operating
# system and application installation and upgrade operations.
#
# USAGE: luupgrade [-u | -f | -p | -r | -P | -R | -i | -c] [-l error_log] \
#		[-o outfile] [-N] [additional / optional / required parameters]:
# OS Upgrade:      luupgrade -u -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-D] -s source_os_image_path [-j profile_path]
# Flash Upgrade:   luupgrade -f -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-D] -s source_os_image_path (-a archives | -j profile_path | -J "profile")
# Add Packages:    luupgrade -p -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] ((-s | -d) source_packages_path) [-O "pkgadd_options"] [-a pkg_admin_file] \
#		[pkginst [pkginst...]]
# Remove Packages: luupgrade -P -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "pkgadd_options"] pkginst [pkginst...]
# Check Packages:  luupgrade -C -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "pkgchk_options"] [pkginst [pkginst...]]
# Package Info:    luupgrade -I -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "pkginfo_options"] [pkginst [pkginst...]]
# Add Patches:     luupgrade -t -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] -s source_patches_path  [-O "patchadd_options"] [patchname [patchname...]]
# Remove Patches:  luupgrade -T -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "patchrm_options"] patchname [patchname...]
# Run Installer:   luupgrade -i -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] -s install_image_path [-O "installer_options"]
# Check Media:     luupgrade -c [-l error_log] [-o outfile] -s image_path
#
# Returns: 	0 - operation successful.
#		1 - operation failed: failure to perform specific operation requested.
#		2 - operation failed: unexpected failure outside of requested operation.
#		3 - operation failed: command line / user request error.
#		4 - operation failed: script interrupted (by HUP INT QUIT KILL TERM).
#		5 - operation failed: live upgrade product installation problem.
#
# Note: performance testing has proven that "/sbin/sh" provides the best performance over
# /bin/sh and /bin/ksh - BUT THIS SCRIPT IS WRITTEN TO USE KSH FEATURES SO MUST REMAIN KSH.
#                        ------------------------------------------------------------------
#
################################################################################

################################################################################
# Operating System distribution media format expected by this script:
# 
# DIR:  media
#       	---> base directory for Solaris distribution
# FILE: media/.cdtoc 
#		---> table of contents for media (see cdtoc(4))
# DIR:  media/Solaris*/Product
#		---> product main directory (from .cdtoc file)
# DIR:  media/Solaris*/Patches
#		---> product patches directory
# DIR:  media/MU
#		---> multiple update main directory
# FILE: media/MU/install_mu
#		---> multiple update installer
# DIR:  media/.install_config
#		---> used to detect that installable os is located here
# DIR:  media/Solaris*/Tools
#		---> mini-root tools directory
# DIR:  media/Solaris*/Tools/Boot/usr/snadm/lib
#		---> library directory for pfinstall
# DIR:  media/Solaris*/Tools/Boot/usr/sbin/install.d
#		---> directory where pfinstall is located
# FILE: media/Solaris*/Tools/Boot/usr/sbin/install.d/pfinstall
#		---> pfinstall executable
# DIR:  media/Solaris*/Tools/Boot/usr/sbin/install.d/install_config
#		---> directory where installation scripts can be found
# DIR:  media/Solaris*/Tools/Boot/usr/sbin/install.d/install_config/patch_finish
#		---> post-os upgrade/install patch installation script
#
################################################################################

# disable error on unset variable reference in case set in global environment
set +o nounset

# Script global variables.

LU_PROG_FULL_PATH="$0"
LU_PROG_NAME="`basename ${LU_PROG_FULL_PATH}`"; export LU_PROG_NAME
MEDIAROOTMOUNTPOINT="/a"
UPGRADE_PROFILE="/etc/lu/solaris_profile"
FLASH_PROFILE="/etc/lu/solaris_flash_profile"
FLASH_UPDATE_PROFILE="/etc/lu/solaris_flash_update_profile"
COPYLOCK_CAN_BE_DELETED=""
AIM_BEBOOTMNT=""
MAIL_SUBJECT=""
MAIL_DISABLE=""
MAX_PATCHES_FROM_FILE="1000"
LU_BOOTENV="platform/i86pc/boot/solaris/bootenv.rc"
LU_MINIROOT_DIR="boot"
LU_MINIROOT_PATH=""
LU_MINIROOT_DEVICE=""
LU_MINIROOT_FSTYPE=""
LU_MINIROOT_MNTPT=""
INSTALL_FAILSAFE_ON=""
TMP_FAILSAFE_MULTIBOOT=""
TMP_FAILSAFE_ARCHIVE=""

# Locations of files created by pfinstall.

PFINSTALL_INSTALL_LOG="/var/sadm/system/logs/install_log"
PFINSTALL_UPGRADE_CLEANUP="/var/sadm/system/data/upgrade_cleanup"
PFINSTALL_UPGRADE_FAILED_PKGADDS="/var/sadm/system/data/upgrade_failed_pkgadds"
PFINSTALL_UPGRADE_LOG="/var/sadm/system/logs/upgrade_log"
PFINSTALL_PACKAGES_TO_BE_ADDED="/var/sadm/system/data/packages_to_be_added"

# Location of patch database.

PATCH_DATABASE_FILE="/var/sadm/patch/.patchDB"

# Used to remember how to backup and restore lu state.

BLUS_BACKUP_FILENAME=""
BLUS_BE_ICF=""
BLUS_BE_NAME=""
BLUS_BOOT_MNT=""
BLUS_RESTORE_FILE=""

# Used to remember how to backup and restore vfstab file.

VFST_BACKUP_FILENAME=""
VFST_BE_ICF=""
VFST_BE_NAME=""
VFST_BOOT_MNT=""
VFST_REAL_FILENAME=""
VFST_RESTORE_FILE=""

# profile keywords to disallow
PROFILE_DISALLOW_KEYWORDS="root_device boot_device filesys fdisk dontuse \
partitioning usedisk layout_constraint noreboot"

FLASH_INSTALL_PROFILE_DISALLOW_KEYWORDS="root_device boot_device filesys fdisk dontuse \
partitioning usedisk layout_constraint noreboot"

FLASH_UPDATE_PROFILE_DISALLOW_KEYWORDS="root_device boot_device filesys fdisk dontuse \
partitioning usedisk layout_constraint noreboot"

# All temporary files (that must be deleted when script starts and when it exits) 
# are defined below.

ABE_ICF="/tmp/.luupgrade.icf1.$$"
PBE_ICF="/tmp/.luupgrade.icf2.$$"
COMBINED_ICF="/tmp/.luupgrade.icf3.$$"
MOUNT_ERRLOG="/tmp/.luupgrade.mounterr.$$"
AT_ERRLOG="/tmp/.luupgrade.aterr.$$"
MAIL_LOGFILE="/tmp/.luupgrade.mail.$$"
MOUNT_SCAN_LOGFILE="/tmp/.luupgrade.mountscan.$$"
GREP_SCAN_LOGFILE="/tmp/.luupgrade.grepscan.$$"
GREP_SCAN2_LOGFILE="/tmp/.luupgrade.grepscan2.$$"
VOLMGT_SCAN_LOGFILE="/tmp/.luupgrade.volmgrscan.$$"
INSTPROG_LOGFILE="/tmp/.luupgrade.instprog.$$"
INSTPROG2_LOGFILE="/tmp/.luupgrade.instprog.$$"
BEICF_BACKUP="/tmp/.luupgrade.beicf.$$"
PFINSTALL_LOGFILE="/tmp/.luupgrade.pfinstall.log.$$"
PATCHFINISH_SCRIPT="/tmp/.luupgrade.patchfinish.$$"
PATCH_LOGFILE="/tmp/.luupgrade.patch.log.$$"
TMPFILE="/tmp/.luupgrade.tmp.$$"
TMPTRANS="/tmp/.luupgrade.translist.tmp.$$"
PROGRESS_REPORT_FILE="/tmp/.luupgrade.progrpt.tmp.$$"
TMP_RESULT_FILE="/tmp/.luupgrade.results.tmp.$$"
TMP_UPGRADE_PROFILE="/tmp/.luupgrade.profile.upgrade.$$"
TMP_FLASH_PROFILE="/tmp/.luupgrade.profile.flash.$$"
TMP_MENU_LST="/etc/lu/luupgrade.tmp.menu.lst.$$"

# This variable is used to remove all temp files when script starts and exits.
# ---> WHEN ADDING A TEMPORARY FILE ABOVE MAKE SURE YOU ADD IT TO THIS LIST!!!

ALL_TEMP_FILES="${PBE_ICF} ${ABE_ICF} ${COMBINED_ICF} ${MOUNT_ERRLOG} \
${AT_ERRLOG} ${MAIL_LOGFILE} ${MOUNT_SCAN_LOGFILE} ${GREP_SCAN_LOGFILE} \
${GREP_SCAN2_LOGFILE} ${VOLMGT_SCAN_LOGFILE} ${INSTPROG_LOGFILE} \
${TMP_UPGRADE_PROFILE} ${TMP_FLASH_PROFILE} \
${INSTPROG2_LOGFILE} ${BEICF_BACKUP} ${PATCHFINISH_SCRIPT} ${PFINSTALL_LOGFILE} \
${TMPFILE} ${PATCH_LOGFILE} ${TMPTRANS} ${PROGRESS_REPORT_FILE} ${TMP_RESULT_FILE} \
${TMP_MENU_LST}"

################################################################################
# Name:		usage
# Description:	output command line usage information; then call exit_script to terminate execution.
# Local Prefix:	<none>
# Arguments:	$1 = exit code for script ("" defaults to "3").
# Example:	usage 3
# Returns:	<none> 
################################################################################

usage()
{
  ${LUPRINTF} -p2 "`gettext 'USAGE: %s [ -u | -f | -p | -r | -P | -R | -i | -c ] \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ additional optional and required parameters ]:'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'OS Upgrade:      %s -u -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] [ -D ] \
-s source_os_image_path [ -j profile_path ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Flash Upgrade:   %s -f -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] [ -D ] \
-s source_os_image_path ( -a archives | -j \
 profile_path | -J profile )'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Add Packages:    %s -p -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
( ( -s|-d ) source_packages_path ) [ -a pkg_admin_file ] \
[ -O pkgadd_options ] [ pkginst [ pkginst... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Remove Packages: %s -P -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O pkgadd_options ] pkginst [ pkginst... ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Check Packages:  %s -C -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O pkgchk_options ] [ pkginst [ pkginst... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Package Info:    %s -I -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O pkginfo_options ] [ pkginst [ pkginst... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Add Patches:     %s -t -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] -s source_patches_path \
[ -O patchadd_options ] \
[ patchname [ patchname... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Remove Patches:  %s -T -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O patchrm_options ] patchname [ patchname... ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Run Installer:   %s -i -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] -s install_image_path \
[ -O installer_options ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Check Media:     %s -c \
[ -l error_log ] [ -o outfile ] [ -X ] -s image_path'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -Ip2 "`gettext 'Any BE_name or options should be enclosed in single quotes.'`"

  if [ -z "$1" ] ; then
    exit_script 3
  fi
  exit_script "$1"
}

################################################################################
# Name:		checkZoneSupport		
# Description:	Check if the ABE and CBE are compatible with respect to zones.
#		If the alternate boot enviornment supports zone and the
#		current boot environement does not support, then they are incompatible. 
# Local Prefix:	czs_
# Arguments:	$1 = Name of the alternate boot environment.
#		$2 = The absolute path where the ABE is mounted.
# Returns:	0 - In case ABE and CBE are compatible.
#		1 - ABE and CBE are incompatible.
################################################################################

checkZoneSupport()
{
	czs_beName="$1"
	czs_bootMnt="$2"

	# debugging information
	${LUPRINTF} -lp2D - "`gettext 'Check zone capability of boot environment <%s> mounted at <%s>.'`" "${czs_beName}" "${czs_bootMnt}"

	# If currently running Envrionment is S9 or earlier and target root environment is
	# S10 or later, then do not allow this operation. This is to ensure proper installation
	# of non-global zones.

	# return 0 if the current boot environment supports non-global zones
	[ -f /etc/zones/index ] && return 0
	${LUPRINTF} -lp2D 2 "`gettext 'Current system does not support non-global zones.'`"

	# return 0 if the target boot environment does not support non-global zones
	[ -f ${czs_bootMnt}/etc/zones/index ] || return 0
	${LUPRINTF} -lp2D 2 "`gettext 'Target system requires support for non-global zones.'`"

	# the current boot environment does not support non-global zones and the
	# target boot environment does support non-global zones - output error
	# message and return 1

	${LUPRINTF} -Eelp2 "`gettext 'The boot environment <%s> supports non-global zones.\
The current boot environment does not support non-global zones. Releases prior to \
Solaris 10 cannot be used to maintain Solaris 10 and later releases that include \
support for non-global zones. You may only execute the specified operation on a \
system with Solaris 10 (or later) installed.'`" "${czs_beName}"

	return 1
}

################################################################################
# Name:		interruptHandler
# Description:	Handle an armed shell "trap"
# Local Prefix:	<none>
# Arguments:	<none>
# Example:      trap "interruptHandler" 1 2 3 9 15
# Returns:	call script cleanup function with exit code "4"
################################################################################

interruptHandler()
{
  # Reset all traps to be ignored so that termination can take place
  # without further interrupts

  # 1- SIGHUP (hangup)
  # 2- SIGINT (user interrupt)
  # 3- SIGQUIT (user quit)
  # 9- SIGKILL (kill process - can not be caught or ignored :)
  # 15- SIGTERM (software termination request)
  trap "" 1 2 3 9 15

  # Output indication of interrupt processed
  ${LUPRINTF} -Ilp2 "`gettext 'Interrupted (Signal received): cleaning up...'`"

  # Cause script to cleanup and exit with exit code '4'
  exit_script 4
}

################################################################################
# Name:		exit_script
# Description:	Perform cleanup operations and exit this script.
# Local Prefix:	<none>
# Arguments:	$1 = optional exit value for script ("" or none is = "0")
# Example:      exit_script "0"
# Returns:	<none>
################################################################################

exit_script()
{
  # Restore the vfstab file.

  restore_vfstab_file

  # Umount the abe.

  abe_umount

  # unmount the miniroot
  umount_miniroot

  # Remove any temporary mount points that may have been placed in /tmp

  for dname in `/usr/sbin/mount | /bin/grep '^/tmp/.alt.' | /bin/awk ' { print $1 } '` ; do
    /usr/sbin/umount $dname 2>/dev/null 1>&2
    if [ "$?" = "0" ] ; then
      /bin/rmdir $dname 2>/dev/null 1>&2
    fi
  done

  # Remove the copy lock.

  copylock_delete

  # Send the mail log file.

  maillog_send ""

  # Remove all temporary files only if debugging is not enabled;
  # otherwise, leave them behind for possible debugging purposes.

  if [ "$LU_DEBUG" -eq "0" ] ; then
    /bin/rm -f ${ALL_TEMP_FILES}
  else
    tempnames=""
    for tempname in ${ALL_TEMP_FILES} ; do
      if [ -f "${tempname}" ] ; then
	tempnames="$tempname $tempnames"
      fi
    done
    if [ -n "${tempnames}" ] ; then
      ${LUPRINTF} -lp2D - "`gettext 'Because debugging is enabled, these \
temporary files were not removed: <%s>.'`" "${tempnames}"
    fi
  fi

  # Exit.

  if [ -z "$1" ] ; then
    exit 0
  fi
  exit $1
}

################################################################################
# Name:		add_auto_os_patches
# Description:	Execute the automatic operating system patch installation script 
#		from an install media
# Local Prefix:	aaop_
# Arguments:	$1 = boot environment name (e.g. "be1").
#		$2 = boot environment mount point (e.g. /.alt.01234).
#		$3 = media install configuration directory 
#			(e.g. latest/Solaris_x/Tools/Boot/usr/sbin/install.d/install_config).
#		$4 = media install patches directory (e.g. latest/Solaris_x/Patches).
#		$5 = upgrade log file on boot environment 
#			(e.g. /.alt.01234/var/sadm/system/logs/upgrade_log).
#		$6 = no execute mode flag ("" if not no execute mode).
#		$7 = file to hold contents of patch add log
#		$8 = install media directory.
# Example:      add_auto_os_patches "${beName}" "${boot_mnt}" "${toolsInstallConfig}" 
#		"${patchdir}" "${boot_mnt}/var/sadm/system/logs/upgrade_log" 
#		"${noExecuteMode}" "${installMediaPath}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

add_auto_os_patches()
{
  aaop_beName="$1"
  aaop_bootMnt="$2"
  aaop_installConfigDir="$3"
  aaop_patchesDir="$4"
  aaop_upgradeLogFile="$5"
  aaop_noExecuteMode="$6"
  aaop_autoPatchLogfile="$7"
  aaop_installMediaPath="$8"

  # Locate the patch_finish script.
  aaop_patchFinishScript="${aaop_installConfigDir}/patch_finish"

  # If an upgrade log file was specified, create an "-a file" option
  # to be used with luprintf. Leaving it blank causes no append to be done.
  aaop_aflg=""
  [ -n "${aaop_upgradeLogFile}" ] && aaop_aflg="-a ${aaop_upgradeLogFile}"

  # If no auto patch log file specified, direct results to /dev/null.
  aaop_autoPatchLogFile=${aaop_autoPatchLogFile:=/dev/null}

  aaop_ret=0
  if [ -f "${aaop_patchFinishScript}" -a -s "${aaop_patchFinishScript}" ] ; then
    ${LUPRINTF} -lp1 ${aaop_aflg} "`gettext 'Adding operating system patches to the BE <%s>.'`" "${aaop_beName}"

    # Determine if the patch_finish script accepts arguments (S9 and later); 
    # if so, then patch_finish can be called directly; otherwise it must be
    # edited to change references to "/cdrom" (S8U7 and earlier). Because the
    # previously released patch_finish scripts cannot be changed, must examine
    # existing patch_finish script. If it is a shell script and does not have
    # the getopts call, it is the old script without the command line interface.
    # If it is not a shell script, or if it is a shell script and it does have
    # the getopts call, it has the new command line interface.

    aaop_patchScriptOld=''
    /bin/fgrep 'getopts' ${aaop_patchFinishScript} 1>/dev/null 2>&1 || aaop_patchScriptOld='yes'
    /bin/head -1 ${aaop_patchFinishScript} | /bin/fgrep '#!/sbin/sh' 1>/dev/null 2>&1 || aaop_patchScriptOld=''

    if [ -n "${aaop_patchScriptOld}" ] ; then
      # Old patch script - must use sed to edit it and then run the modified copy.
      /bin/sed "s%SOL_PATCHDIR=.*%SOL_PATCHDIR=${aaop_patchesDir}%g;s%INSTALLROOT=.*%INSTALLROOT=${aaop_bootMnt}%g;s%SI_OSNAME=\(.*\)/cdrom/.cdtoc%SI_OSNAME=\1${aaop_installMediaPath}/.cdtoc%g" < ${aaop_patchFinishScript} > ${PATCHFINISH_SCRIPT}
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to modify the operating system patch installation script <%s>.'`" "${aaop_patchFinishScript}"
	return 1
      fi
      # patchadd does not work on an ABE /export/root. 
      # Must chroot. Exception: because an OS upgrade may use
      # volmgt, we can't do a chroot. A previous check
      # would have aborted the upgrade if a non-OS upgrade
      # attempted to use a device under volmgt.
      if [ -n "${aaop_noExecuteMode}" ] ; then
	${LUPRINTF} -lp1 "`gettext 'Execute Command <%s>.'`" "${aaop_patchFinishScript}"
	aaop_ret=0
      elif [ -n "${aaop_upgradeLogFile}" ] ; then
	/bin/sh ${PATCHFINISH_SCRIPT} 2>&1 | tee -a "${aaop_upgradeLogFile}" 1>${aaop_autoPatchLogFile}
	aaop_ret=$?
      else
	/bin/sh ${PATCHFINISH_SCRIPT} 1>${aaop_autoPatchLogFile} 2>&1
	aaop_ret=$?
      fi
    else
      # New patch script - call directly with command line arguments -R and -c.
      if [ -n "${aaop_noExecuteMode}" ] ; then
	${LUPRINTF} -lp1 "`gettext 'Execute Command <%s>.'`" "${aaop_patchFinishScript} -R \"${aaop_bootMnt}\" -c \"${aaop_installMediaPath}\""
      elif [ -n "${aaop_upgradeLogFile}" ] ; then
	${aaop_patchFinishScript} -R "${aaop_bootMnt}" -c "${aaop_installMediaPath}" 2>&1 | tee -a "${aaop_upgradeLogFile}" 1>${aaop_autoPatchLogFile}
	aaop_ret=$?
      else
	${aaop_patchFinishScript} -R "${aaop_bootMnt}" -c "${aaop_installMediaPath}" 1>${aaop_autoPatchLogFile} 2>&1
	aaop_ret=$?
      fi
    fi
  else
    ${LUPRINTF} -lp2D - ${aaop_aflg} "`gettext 'No default operating system patches present on media - no patches automatically applied to the BE.'`"
  fi

  return ${aaop_ret}
}

################################################################################
# Name:		make_at_command
# Description:	Construct a command line that will schedule an upgrade that can be given to 'at'.
# Local Prefix:	mac_
# Arguments:	$1 = boot environment name (e.g. "be1").
#		$2 = media mount point to upgrade operating system from.
# Example:      make_at_command "${beName}" "${media}" | /bin/at -m "$attime"
# Returns:	<none>
################################################################################

make_at_command()
{
  mac_beName="$1"
  mac_media="$2"

  if [ -n "$1" -a -d "${mac_media}" ] ; then
    echo "
	  if [ -s /etc/default/lu ]
	  then
		  . /etc/default/lu
	  else
		  LUBIN=/usr/lib/lu
		  COPYLOCK=/etc/lu/COPY_LOCK
	  fi
	  . \$LUBIN/lulib
	  # Avoid race with any scheduled copy
	  sleep 240
	  while [ 1 ]
	  do
		  if [ -f \${COPYLOCK} ]
		  then
			  . \${COPYLOCK}
			  if [ \"\$CL_STATUS\" = \"SCHEDULED\" ]
			  then
				  echo \"\`gettext 'ERROR: The Live Upgrade Copy did not start at the expected time. Upgrade aborted.'\`\" | tee -a /etc/lu/lu.log
				  exit 2
			  elif [ \"\$CL_STATUS\" = \"UPGRADING\" ]
			  then
				  echo \"\`gettext 'ERROR: It appears that another Live Upgrade upgrade is running.'\`\" >& 2
				  echo \"\`gettext 'This scheduled upgrade will be aborted.'\`\" | tee -a /etc/lu/lu.log
				  exit 2
			  elif [ \"\$CL_STATUS\" = \"ACTIVE\" ]
			  then
				  sleep 299
				  continue
			  else
				   echo \"\`gettext 'ERROR: Unknown Copy Lock status. The scheduled upgrade will be aborted.'\`\" | tee -a /etc/lu/lu.log
				  exit 2
			  fi
		  else
			  break
		  fi
	  done
	  status=\`${LUETCBIN}/ludo get_be_status_from_be_name \"${mac_beName}\"\`
	  if [ \"\$status\" != \"C\" ]
	  then
		  echo \"\`gettext 'ERROR: Target BE is not Complete.'\`\" >& 2
		  exit 1
	  fi
	  $LUBIN/luupgrade -u -n \"${mac_bename}\" -s ${mac_media} >> /etc/lu/lu.log 2>&1
	  "
    ${LUPRINTF} -lp2D - "`gettext 'Constructed command to upgrade the BE <%s> from media <%s>.'`" "${mac_beName}" "${mac_media}"
  else
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to construct command to upgrade the BE <%s> from media <%s>.'`" "${mac_beName}" "${mac_media}"
  fi
}

################################################################################
# Name:		abe_icfMount
# Description:	Mount a single ABE that can be automatically umounted when the script exits.
# Local Prefix:	aim_
# Arguments:	$1 = ICF file to use to mount the boot environment.
# Example:	abe_icfMount "${ICF_FILE}"
# Returns:	0 - successful.
#		1 - failure.
# Side Effects: AIM_BEBOOTMNT is set to the mount point of the just mounted BE (e.g. /.alt.1234)
################################################################################

abe_icfMount()
{
  aim_beIcf="$1"

  if [ -f "${BEICF_BACKUP}" -a -s "${BEICF_BACKUP}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (requested to mount BE from <%s> when BE already mounted).'`" "${aim_beIcf}"
    return 1
  fi
  AIM_BEBOOTMNT=""
  ERRMSG="`/bin/cp \"${aim_beIcf}\" \"${BEICF_BACKUP}\" 2>&1`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create backup copy of file <%s> on <%s>.'`" "${aim_beIcf}" "${BEICF_BACKUP}"
    return 1
  fi
  aim_beBootMnt="`LU_OUTPUT_FORMAT=text $LUBIN/lumount -i \"${BEICF_BACKUP}\" \"${MEDIAROOTMOUNTPOINT}\" 2>${TMP_RESULT_FILE}`"
  if [ "$?" -ne "0" ] ; then
    /bin/rm -f ${BEICF_BACKUP}
    [ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount ABE disk slices: <%s %s>.'`" "${aim_beBootMnt}" "`/bin/cat ${TMPFILE}`"
    return 1
  fi
  AIM_BEBOOTMNT=${aim_beBootMnt}
  ${LUPRINTF} -lp2D - "`gettext 'Mounting ABE from ICF file <%s> to mount point <%s>.'`" "${BEICF_BACKUP}" "${AIM_BEBOOTMNT}"
  return 0
}

################################################################################
# Name:		abe_checkMounted
# Description:	Check to see if a BEs root slice is mounted at an expected mount point. If it
#		is not, cause the BEs slices to be mounted.
# Local Prefix:	acm_
# Arguments:	$1 = ICF file to use for the boot environment to be mounted.
# Example:	abe_believeMounted "${ICF_FILE}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

abe_checkMounted()
{
  acm_beIcf="$1"

  # See if the root file system for the BE is mounted at the expected
  # media root mount point. If it is not, cause it to be mounted for
  # other operations that depend on it being available.
  ${LUETCBIN}/ludo get_root_slice_from_mntpt "${MEDIAROOTMOUNTPOINT}" 2>/dev/null 1>&2
  if [ "$?" -eq "0" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment mount check: still mounted at <%s>'`" \
"${MEDIAROOTMOUNTPOINT}"
    abe_believeMounted "${acm_beIcf}" "${MEDIAROOTMOUNTPOINT}"
  else
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment mount check: remounting at <%s>'`" \
"${MEDIAROOTMOUNTPOINT}"
    abe_icfMount "${acm_beIcf}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'ABE slices (re)mounted at <%s>.'`" "${MEDIAROOTMOUNTPOINT}"

  return "$?"
}

################################################################################
# Name:		abe_believeMounted
# Description:	Believe that the an ABE specified by an ICF file has been mounted (trust me).
# Local Prefix:	abm_
# Arguments:	$1 = ICF file to use to believe that the boot environment is mounted.
#		$2 = mount point to believe the BE is mounted on
# Example:	abe_believeMounted "${ICF_FILE}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

abe_believeMounted()
{
  abm_beIcf="$1"
  abm_beMntPt="$2"

  if [ -f "${BEICF_BACKUP}" -a -s "${BEICF_BACKUP}" ] ; then
    /bin/cmp -s "${BEICF_BACKUP}" "${abm_beIcf}"
    [ $? -eq 0 ] && return 0
    ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (requested to believe \
BE mounted from <%s> but BE already mounted from <%s>).'`" "${abm_beIcf}" "${BEICF_BACKUP}"
    return 1
  fi
  ERRMSG="`/bin/cp \"${abm_beIcf}\" \"${BEICF_BACKUP}\" 2>&1`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create backup copy of file <%s> on \
<%s>.'`" "${abm_beIcf}" "${BEICF_BACKUP}"
    return 1
  fi
  AIM_BEBOOTMNT="${abm_beMntPt}"
  ${LUPRINTF} -lp2D - "`gettext 'Believe that ABE mounted from ICF file <%s> to \
mount point <%s>.'`" "${BEICF_BACKUP}" "${AIM_BEBOOTMNT}"
  return 0
}

################################################################################
# Name:		abe_umount
# Description:	Unmount a single ABE that may have been previously mounted with abe_icfMount.
# Local Prefix:	abu_
# Arguments:	<none>
# Example:	abe_umount
# Returns:	From luumount:
#		0 - successful.
#		1 - failure.
#		2 - failure.
# Side Effects:	AIM_BEBOOTMNT is set to the null string
################################################################################

abe_umount()
{
  abu_ret="0"
  if [ -f "${BEICF_BACKUP}" -a -s "${BEICF_BACKUP}" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Unmounting ABE mount point <%s> from ICF file <%s>.'`" "${AIM_BEBOOTMNT}" "${BEICF_BACKUP}"
    ${LUBIN}/luumount -f -i ${BEICF_BACKUP}
    abu_ret="$?"
    /bin/rm -f ${BEICF_BACKUP}
  fi
  AIM_BEBOOTMNT=""
  return ${abu_ret}
}

################################################################################
# Name:		backup_vfstab_file
# Description:	Backup an BE's vfstab file so that it can be restored after upgrade operations.
# Local Prefix:	bvft_
# Arguments:	$1 = mount point for vfstab file (e.g. /.alt.01234).
#		$2 = boot environment name.
#		$3 = boot environment ICF file (for luumount/lumount on restore).
# Example:	backup_vfstab_file "${BOOT_MNT}" "${BE_NAME}" "${BE_ICF}"
# Returns:	0 - successful.
#		1 - failure to backup the original VFSTAB file.
#		2 - previous backup present - manual intervention required.
################################################################################

backup_vfstab_file()
{
  bvtf_bootMnt="$1"
  bvtf_beName="$2"
  bvtf_abeIcf="$3"

  if [ -f "${bvtf_bootMnt}/etc/vfstab.pf2" -a -s "${bvtf_bootMnt}/etc/vfstab.pf2" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Live upgrade has detected that a previous \
operating system upgrade operation may have been interrupted: a backup vfstab \
file exists on the BE to be upgraded. You must first manually use lumount to \
mount the BE (by executing the command <lumount %s>), then cd to the /etc \
directory on the BE just mounted, then examine the files vfstab and vfstab.pf2 \
and determine which file is the correct vfstab file for the BE. If vfstab.pf2 \
is the correct contents, execute the command </bin/mv vfstab.pf2 vfstab>. If \
vfstab is the correct contents, execute the command </bin/rm vfstab.pf2>. Then \
unmount the BE by executing the command <luumount %s> and run %s again.'`" \
"${bvtf_beName}" "${bvtf_beName}" "${LU_PROG_NAME}"
    return 2
  fi

  ERRMSG="`/bin/cp -p \"${bvtf_bootMnt}/etc/vfstab\" \"${bvtf_bootMnt}/etc/vfstab.pf2\" 2>&1`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to save backup copy of vfstab file <%s> on BE <%s>.'`" "${bvtf_bootMnt}/etc/vfstab" "${bvtf_bootMnt}/etc/vfstab.pf2"
    return 1
  fi

  VFST_BE_ICF="${bvtf_abeIcf}"
  VFST_BACKUP_FILENAME="/etc/vfstab.pf2"
  VFST_BE_NAME="${bvtf_beName}"
  VFST_BOOT_MNT="${bvtf_bootMnt}"
  VFST_REAL_FILENAME="/etc/vfstab"
  VFST_RESTORE_FILE="yes"
  return 0
}

################################################################################
# Name:		change_vfstab_bootmnt
# Description:	Change the mount point at which the backup vfstab file can be found - this is
#		done because pfinstall changes the mount point from where it was originally
#		mounted (from /.alt.* to /a).
# Local Prefix:	<none>
# Arguments:	<none>
# Example:	change_vfstab_bootmnt "${BOOT_MNT}"
# Returns:	<none>
################################################################################

change_vfstab_bootmnt()
{
  VFST_BOOT_MNT="$1"
}

################################################################################
# Name:		restore_vfstab_file
# Description:	Restore a BE's backup vfstab file.
# Local Prefix:	vfst_
# Arguments:	
# Example:	restore_vfstab_file
# Returns:	0 - successful.
#		1 - failure to restore backup of original VFSTAB file.
################################################################################

restore_vfstab_file()
{
  rvft_restore_errs="0"
  if [ -n "${VFST_RESTORE_FILE}" ] ; then
    # The vfstab file needs to be restored; algorithm:
    # 1. check to see if backup file found:
    #    --> if not: umount and remount BE as its mount point may have changed (pfinstall does this...).
    # 2. check to see if backup file found:
    #    --> if not: then remount failed or the backup copy could not be found.
    #    --> else: restore the backup file to the original vfstab file.

    if [ ! -f "${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}" ] ; then
      abe_umount
      $LUBIN/luumount -f -i ${VFST_BE_ICF} >/dev/null 2>&1
      abe_icfMount ${VFST_BE_ICF}
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to remount the target BE to restore vfstab file <%s>.'`" "${VFST_BE_NAME}"
	rvft_restore_errs="1"
      else
	VFST_BOOT_MNT="${AIM_BEBOOTMNT}"
      fi
    fi

    if [ ! -f "${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to locate backup copy of the target BEs /etc/vfstab file.'`"
      rvft_restore_errs="1"
    else
      ${LUPRINTF} -lp2D - "`gettext 'Restoring VFSTAB file <%s> to <%s>.'`" "${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}" "${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}"
      ERRMSG="`/bin/rm -f \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}.pf1\" 2>&1`"
      ERRMSG="${ERRMSG} `/bin/mv -f \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}\" \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}.pf1\" 2>&1`"
      ERRMSG="${ERRMSG} `/bin/mv -f \"${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}\" \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}\" 2>&1`"
      if [ "$?" -ne "0" ] ; then
	rvft_restore_errs="1"
	${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	${LUPRINTF} -Eelp2 "`gettext 'Problems restoring ABE vfstab file.'`"
      fi
      /bin/rm -f "${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}.pf1"
    fi

    if [ "${rvft_restore_errs}" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Live upgrade was unable to restore the \
/etc/vfstab file on the BE. You must manually use lumount to mount the BE (by \
executing the command <lumount %s>), then cd to the /etc directory on the BE \
just mounted, then examine the files vfstab and vfstab.pf2 and determine which \
file is the correct vfstab file for the BE. If vfstab.pf2 is the correct \
contents, execute the command </bin/mv vfstab.pf2 vfstab>. If vfstab is the \
correct contents, execute the command </bin/rm vfstab.pf2>. In most cases, \
vfstab.pf2 will be the correct vfstab file to use. Then unmount the BE by \
executing the command <luumount %s>.'`" "${VFST_BE_NAME}" "${VFST_BE_NAME}"
    fi

  fi
  VFST_BACKUP_FILENAME=""
  VFST_BE_NAME=""
  VFST_REAL_FILENAME=""
  VFST_RESTORE_FILE=""
  # DO NOT RESET VFST_BOOT_MNT - EXPECTED AS SIDE EFFECT OF CALLING RESTORE....

  return ${rvft_restore_errs}
}

################################################################################
# Name:		maillog_addFile
# Description:	Add the contents of a file to the mail log file.
# Local Prefix:	maf_
# Arguments:	$1 = name of text file to include in mail log file.
#		$2 = single comment line to be appended to the mail log file before the contents
#			of the text file is included.
# Example:      maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
# Returns:	<none>
################################################################################

maillog_addFile()
{
  maf_fileName="$1"
  maf_comments="$2"
  if [ -n "${MAILLOGTO}" -a -f "${maf_fileName}" -a -s "${maf_fileName}" ] ; then
    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "%s: %s\n" "`/bin/date`" "${maf_comments}" 1>${TMPFILE} 2>&1
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to append results for <%s> from file \
<%s> to mail log file <%s>: <%s>.'`" "${maf_comments}" "${maf_fileName}" \
"${MAIL_LOGFILE}" "`/bin/cat ${TMPFILE}`"
    else
      /bin/cat ${maf_fileName} >> ${MAIL_LOGFILE}
    fi
  fi
}

################################################################################
# Name:		maillog_setSubject
# Description:	Set the subject line to be used when the mail log file is sent.
# Local Prefix:	<none>
# Arguments:	$1 = text of subject line to be used when the mail log file is sent.
# Example:      maillog_setSubject "`gettext 'Upgrade Successful.'`"
# Returns:	<none>
################################################################################

maillog_setSubject()
{
  MAIL_SUBJECT="$1"
}

################################################################################
# Name:		maillog_send
# Description:	Send the mail log file if it exists, is non-zero in length, and the "MAILLOGTO"
#		global environment variable is set.
# Local Prefix:	<none>
# Arguments:	<none>
# Example:      maillog_send
# Returns:	<none>
################################################################################

maillog_send()
{
  if [ -n "${MAILLOGTO}" -a -f "${MAIL_LOGFILE}" -a -s "${MAIL_LOGFILE}" -a -z "${MAIL_DISABLE}" ] ; then
    if [ -z "${MAIL_SUBJECT}" ] ; then
      MAIL_SUBJECT="$*"
    fi
    ERRMSG=`/bin/mailx -s "`gettext 'Live Upgrade Log: '` ${MAIL_SUBJECT}" $MAILLOGTO < ${MAIL_LOGFILE} 2>&1`
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
      ${LUPRINTF} -Eelp2 "`gettext 'Warning: unable to send the maillog file to <%s>.'`" "${MAILLOGTO}"
    fi
    /bin/rm -f "${MAIL_LOGFILE}"
  fi
}

################################################################################
# Name:		checkUserUpgradeProfile
# Description:	check file to see if it can be used in an upgrade profile
# Local Prefix:	cpf_
# Arguments:	$1 = name of file to verify.
# Example:      checkUserUpgradeProfile "${dug_profilePath}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

checkUserUpgradeProfile()
{
  cpf_fileName="$1"

  # make sure file exists
  if [ ! -f "${cpf_fileName}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> does not exist or is not a file.'`" \
"${cpf_fileName}"
    return 1
  fi

  # make sure the file appears to be an upgrade profile
  ${LUBIN}/lucomm_del "${cpf_fileName}" | /bin/head -1 | \
/bin/egrep -s '^[ 	]*install_type[ 	]*upgrade[ 	]*$' 1>/dev/null
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The first line of file <%s> is not \
<install_type upgrade>'`" "${cpf_fileName}"
    return 1
  fi

  # make sure no incompatible keywords are present
  for KW in ${PROFILE_DISALLOW_KEYWORDS} ; do
    /bin/egrep -s "^[ 	]*${KW}" "${cpf_fileName}" 1>/dev/null
    if [ $? -eq 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> may not contain any \
<%s> keywords.'`" "${cpf_fileName}" "${KW}"
      return 1
    fi
  done

  return 0
}

################################################################################
# Name:		checkUserFlashProfile
# Description:	check file to see if it can be used in a flash profile
# Local Prefix:	cpf_
# Arguments:	$1 = name of file to verify.
# Example:      checkUserFlashProfile "${dfi_profilePath}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

checkUserFlashProfile()
{
  cuf_fileName="$1"

  # make sure file exists
  if [ ! -f "${cuf_fileName}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> does not exist or is not a file.'`" \
"${cuf_fileName}"
    return 1
  fi
  # make sure the file appears to be an flash profile
  ${LUBIN}/lucomm_del "${cuf_fileName}" | /bin/head -1 | \
    /bin/egrep -s '^[	]*install_type[ 	]*flash_install[ 	]*$' 1>/dev/null
  if [ $? -eq 0 ] ; then
    FLASH_TYPE="install"
    # make sure no incompatible keywords are present
    for KW in ${FLASH_INSTALL_PROFILE_DISALLOW_KEYWORDS} ; do
	/bin/egrep -s "^[ 	]*${KW}" "${cuf_fileName}" 1>/dev/null
	if [ $? -eq 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> may not contain any \
          <%s> keywords.'`" "${cuf_fileName}" "${KW}"
	return 1
	fi
    done
    return 0
 fi

  # make sure the file appears to be an flash profile
  ${LUBIN}/lucomm_del "${cuf_fileName}" | /bin/head -1 | \
    /bin/egrep -s '^[	]*install_type[ 	]*flash_update[ 	]*$' 1>/dev/null
  if [ $? -eq 0 ] ; then
    FLASH_TYPE="update"
    # make sure no incompatible keywords are present
    for KW in ${FLASH_UPDATE_PROFILE_DISALLOW_KEYWORDS} ; do
	/bin/egrep -s "^[ 	]*${KW}" "${cuf_fileName}" 1>/dev/null
	if [ $? -eq 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> may not contain any \
          <%s> keywords.'`" "${cuf_fileName}" "${KW}"
	return 1
	fi
    done
    return 0
 fi

 ${LUPRINTF} -Eelp2 "`gettext 'The first line of file <%s> is not \
	    <install_type flash_install or flash_update>'`" "${cuf_fileName}"
 return 1
}

################################################################################
# Name:		copylock_create
# Description:	Create a copy lock file; complain if it already exists or it can not be created.
# Local Prefix:	clc_
# Arguments:	$1 = variable name to set 
#		$2 = variable value to set variable name to
#		$3 = "yes" if ok to delete copylock when script exits; "" if not ok to delete
# Example:      copylock_create "CL_STATUS" "UPDATING" "yes"
# Returns:	0 - succeeded - copylock created.
#		1 - failed.
################################################################################

copylock_create()
{
  clc_variableName="$1"
  clc_variableValue="$2"
  clc_canDelete="$3"
  if [ -f "${COPYLOCK}" -a -s "${COPYLOCK}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create copy lock for operation; \
a copy lock already exists: <%s>.'`" "`/bin/cat ${COPYLOCK}`"
    return 1
  fi
  ${LUPRINTF} +X -a ${COPYLOCK} "%s=\"%s\"" "${clc_variableName}" "${clc_variableValue}"
  clc_ret="$?"
  COPYLOCK_CAN_BE_DELETED="${clc_canDelete}"
  return "${clc_ret}"
}

################################################################################
# Name:		copylock_append
# Description:	Append to a copy lock file; complain if it does not exist or it can not be updated.
# Local Prefix:	cla_
# Arguments:	$1 = variable name to set 
#		$2 = variable value to set variable name to
# Example:      copylock_append "CL_TARGET_BE" "${beName}"
# Returns:	0 - succeeded - copylock updated.
#		1 - failed.
################################################################################

copylock_append()
{
  cla_variableName="$1"
  cla_variableValue="$2"
  if [ ! -f "${COPYLOCK}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (copy lock file does not exist).'`"
    return 1
  fi
  ${LUPRINTF} +X -a ${COPYLOCK} "%s=\"%s\"" "${cla_variableName}" "${cla_variableValue}"
  cla_ret="$?"
  return "${cla_ret}"
}

################################################################################
# Name:		copylock_delete
# Description:	If the copylock file exists and can be deleted, delete it.
# Local Prefix:	<none>
# Arguments:	<none>
# Example:      copylock_delete
# Returns:	<none>
################################################################################

copylock_delete()
{
  if [ -n "${COPYLOCK_CAN_BE_DELETED}" -a -f "${COPYLOCK}" ] ; then
    /bin/rm -f ${COPYLOCK}
  fi
  COPYLOCK_CAN_BE_DELETED=""
}

################################################################################
# Name:		resolve_transfer_list
# Description:	Process the transfer list.  The transfer list
#                  contains two entries per line.  This routine
#                  reads each line.  If the first entry resolves
#                  to a number of entries, then multiple entries
#                  are output to the resulting file.
# Local Prefix:	rtl_
# Arguments:	$1 - The transfer list to process
# Example:         resolve_transfer_list /etc/lu/lu_transfer_list
# Returns:	0 on success, non-zero otherwise.  The new transferlist
#                  is output to stdout, for use in backquoted expressions.
################################################################################
resolve_transfer_list()
{
  rtl_list="$1"
  ${LUBIN}/lucomm_del ${rtl_list} | while read fpattern pkg type; do

    # if 'type' field is of type MERGE, parse out the mergescript
    # and prepend miniroot location.
    ttype=`echo ${type} | /bin/cut -d: -f1`
    if [ "${ttype}" = "MERGE" ] ; then
	mergescript=`echo ${type} | /bin/cut -d: -f2`
	type="${ttype}:${dfi_miniroot}/${mergescript}"
    fi

    flist=`/bin/ls ${fpattern} 2> /dev/null`
    # we don't include files that aren't on the system
    if [ $? = 0 ] ; then
	for i in ${flist} ; do
	  if [ "$dfi_tltcap" = "yes" ] ; then
	    echo "$i $pkg $type" >> ${TMPTRANS}
	  else
	    echo "$i $pkg" >> ${TMPTRANS}
	  fi
        done
    fi
  done

  # add the name_service.xml entry only if pfinstall
  # supports the transfer list types (tlt) capability
  if [ "$dfi_tltcap" = "yes" ]; then
    echo "/var/svc/profile/name_service.xml SUNWcsr MERGE:${dfi_miniroot}/usr/sbin/install.d/mergescripts/merge_name_service" >> ${TMPTRANS}
  fi

  # add some extra entries that can't be properly expressed
  # in a static list.  If no domain, ignore these entries.
  DN=`/bin/domainname 2> /dev/null`
  if [ $? = 0 -a -n "$DN" ] ; then
    if [ "$dfi_tltcap" = "yes" ] ; then
	echo "/var/yp/binding/$DN SUNWnisr OVERWRITE" >> ${TMPTRANS}
	echo "/var/yp/binding/$DN/ypservers SUNWnisr OVERWRITE" >> ${TMPTRANS}
    else
	echo "/var/yp/binding/$DN SUNWnisr" >> ${TMPTRANS}
	echo "/var/yp/binding/$DN/ypservers SUNWnisr" >> ${TMPTRANS}
    fi
	
  fi
  echo ${TMPTRANS}
  return 0
}

################################################################################
# Name:		do_checkMiniroot
# Description:	Scan media location and determine path to miniroot.
# Local Prefix: dmr_
# Arguments:	$1 = media mount point to check.
# Returns:      0 = check was successful. - location is output to stdout
#		3 = user input error.
################################################################################
do_checkMiniroot()
{

  dmr_media="$1"

  if [ ! -d "${dmr_media}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media directory does not exist (%s).'`" "${dmr_media}"b
    return 2
  fi

  # find the media cd table of contents: if not found, can not figure version,
  # so cannot use it to flash a BE
  dmr_media_cdtoc="${dmr_media}/.cdtoc"
  if [ ! -f "${dmr_media_cdtoc}" -o ! -s "${dmr_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media is not a recognized installation media.'`"
    return 2
  fi

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dmr_errorsFound=""
  dmr_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dmr_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dmr_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dmr_media_proddir="${dmr_media}/${dmr_cdtoc_proddir}"
  dmr_media_toolsDir="`dirname ${dmr_media_proddir}`/Tools"

  if [ -z "${dmr_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media table of contents does not define a product name.'`"
    dmr_errorsFound="1"
  fi
  if [ -z "${dmr_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media table of contents does not define a product version.'`"
    dmr_errorsFound="1"
  fi
  if [ -z "${dmr_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dmr_errorsFound="1"
  fi
  if [ -n "${dmr_cdtoc_proddir}" ] ; then
    if [ ! -d "${dmr_media_toolsDir}" ] ; then
      ${LUPRINTF} -Eel2 "`gettext 'The media product tools directory does not exist.'`"
      dmr_errorsFound="1"
    fi
  fi

  if [ -n "${dmr_errorsFound}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media does not contain a usable flash install image.'`"
    return 2
  fi

  ######################################################################################
  ########## Verify that the miniroot exists  ##########################################
  ######################################################################################
  dmr_miniroot=${dmr_media_toolsDir}/Boot

  lulib_validate_is_directory_not_empty "${dmr_miniroot}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The install root does not exist or is empty'`"
    return 3
  fi

  # check to see if it has a version of pfinstall that knows about live flash.
  dmr_libDir="${dmr_miniroot}/usr/snadm/lib"
  dmr_ldLibraryPath="${dmr_libDir}"
  [ -n "${LD_LIBRARY_PATH}" ] && dmr_ldLibraryPath="${dmr_ldLibraryPath}:${LD_LIBRARY_PATH}"
  dmr_pfinstallDir="${dmr_miniroot}/usr/sbin/install.d"

  LD_LIBRARY_PATH=${dmr_ldLibraryPath} ${dmr_pfinstallDir}/pfinstall -F test 1> /dev/null 2>&1
  dmr_ret="$?"


  if [ "${dmr_ret}" != 3 ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media is not a recognized Live-Flash-enabled miniroot.'`"
    return 2
  fi

  # print it out for consumption by others
  ${LUPRINTF} -1 "%s" "${dmr_miniroot}"
  return 0
}

################################################################################
# Name:		do_checkMedia
# Description:	Scan media location and determine what operations might be possible.
# Local Prefix: dcm_
# Arguments:	$1 = media mount point to check.
# Returns:      0 = check was successful.
#		3 = user input error.
################################################################################

do_checkMedia()
{
  # extract command line arguments

  dcm_media="$1"

  # reset all variables used in this function

  dcm_cdtoc_proddir=""
  dcm_cdtoc_prodname=""
  dcm_cdtoc_prodvers=""
  dcm_curdir=""
  dcm_foundSomething=""
  dcm_installerCount=""
  dcm_installerList=""
  dcm_media_basedir=""
  dcm_media_patchdir=""
  dcm_media_toolsDir=""
  dcm_media_toolsInstallConfig=""
  dcm_packageCount=""
  dcm_packageList=""

  # compute default locations from media start

  dcm_media_cdtoc="${dcm_media}/.cdtoc"
  dcm_media_mu="${dcm_media}/MU"
  dcm_media_installmu="${dcm_media_mu}/install_mu"

  # output debugging herald

  ${LUPRINTF} -lp2D - "`gettext 'Check media <%s>.'`" "${dcm_media}"

  # Validate that the media specified can be accessed

  lulib_validate_is_directory_not_empty "${dcm_media}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The path specified by the <-s> option is not the location of valid Solaris media.'`"
    return 3
  fi
  # Locate the media table of contents and extract directory and file names and product information

  if [ -f "${dcm_media}/.cdtoc" -a -s "${dcm_media}/.cdtoc" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"
    if [ -d "${dcm_media}/.install_config" ] ; then
      ${LUPRINTF} -lp1 "`gettext 'The media contains an operating system upgrade image.'`"
    fi

    if [ -d "${dcm_media}/.install" -a -x "${dcm_media}/installer" ] ; then
      ${LUPRINTF} -lp1 "`gettext 'The media contains a standard media installer which can be run.'`"
    fi

    dcm_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dcm_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
    dcm_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dcm_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
    dcm_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dcm_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
    if [ -z "${dcm_cdtoc_prodname}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media does not define a product name.'`"
      dcm_cdtoc_prodname="`gettext 'unknown'`"
    fi
    if [ -z "${dcm_cdtoc_prodvers}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media does not define a product version.'`"
      dcm_cdtoc_prodvers="`gettext 'unknown'`"
    fi
    if [ -z "${dcm_cdtoc_proddir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media does not define a product top-level directory.'`"
    elif [ ! -d "${dcm_media}/${dcm_cdtoc_proddir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product directory <%s> does not exist.'`" "${dcm_cdtoc_proddir}"
    else
      ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> version <%s>.'`" "${dcm_cdtoc_prodname}" "${dcm_cdtoc_prodvers}"
      dcm_foundSomething="yes"
    fi
    if [ -n "${dcm_cdtoc_proddir}" ] ; then
      dcm_media_basedir="`dirname ${dcm_media}/${dcm_cdtoc_proddir}`"
      dcm_media_patchdir="${dcm_media_basedir}/Patches"
      if [ -d "${dcm_media_patchdir}" ] ; then
	dcm_media_patchCount=`/bin/ls -1 "${dcm_media_patchdir}" 2>/dev/null | /bin/wc -l 2>/dev/null`
	if [ "${dcm_media_patchCount}" -ne '0' ] ; then
	  ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> patches for the product.'`" ${dcm_media_patchCount}
	fi
      fi
      dcm_media_toolsDir="${dcm_media_basedir}/Tools"
      dcm_media_toolsInstallConfig="${dcm_media_toolsDir}/Boot/usr/sbin/install.d/install_config"
      if [ -f "${dcm_media_toolsInstallConfig}/patch_finish" -a -s "${dcm_media_toolsInstallConfig}/patch_finish" ] ; then
	${LUPRINTF} -lp1 "`gettext 'The media contains an automatic patch installation script.'`"
      fi
    fi
  else
    ${LUPRINTF} -lp1 "`gettext 'The media is not a recognized installation media.'`"
  fi

  # Find the MU installer and directory

  if [ -d "${dcm_media_mu}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains an upgrade patch directory.'`"
    dcm_foundSomething="yes"
  fi

  if [ -x "${dcm_media_installmu}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains an upgrade patch installer <%s>.'`" "install_mu"
    dcm_foundSomething="yes"
  fi

  # Find all executables and installable packages

  dcm_installerList=""
  dcm_installerCount="0"
  dcm_packageList=""
  dcm_packageCount="0"
  dcm_curdir="`/bin/pwd`"
  cd ${dcm_media}
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to access directory <%s>.'`" "${dcm_media}"
  else
    for dcm_itemCandidate in * ; do
      if [ -f "${dcm_itemCandidate}" -a -s "${dcm_itemCandidate}" -a -x "${dcm_itemCandidate}" -a "${dcm_itemCandidate}" != "installer" ] ; then
	if [ -z "$dcm_installerList" ] ; then
	  dcm_installerList="${dcm_itemCandidate}"
	else
	  dcm_installerList="${dcm_installerList} ${dcm_itemCandidate}"
	fi
	dcm_installerCount="`/bin/expr ${dcm_installerCount} + 1`"
      else 
	/usr/sbin/pkgchk -d "${dcm_media}" "${dcm_itemCandidate}" 1>/dev/null 2>&1
	if [ "$?" -eq "0" ] ; then
	  if [ -z "${dcm_packageList}" ] ; then
	    dcm_packageList="${dcm_itemCandidate}"
	  else
	    dcm_packageList="${dcm_packageList} ${dcm_itemCandidate}"
	  fi
	dcm_packageCount="`/bin/expr ${dcm_packageCount} + 1`"
	dcm_foundSomething="yes"
	fi
      fi
    done
  fi

  if [ ! -z "${dcm_installerList}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains %d possible alternative installation programs: <%s>.'`" "${dcm_installerCount}" "${dcm_installerList}"
  fi

  if [ ! -z "${dcm_packageList}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains %d software packages: <%s>.'`" "${dcm_packageCount}" "${dcm_packageList}"
  fi

  if [ -z "${dcm_foundSomething}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media does not contain any recognized products, patches, or packages.'`"
  fi

  return 0
}

################################################################################
# Name:		reconfigure_devices
# Description:	Reconfigures devices on a BE.  We run different sets of binaries based
#		on what we can find in the PBE.
# Local Prefix: drd_
# Arguments:	$1 = media mount point to reconfigure
#		$2 = BE name
# Returns:      0 = reconfiguration was successful.
#		2 = internal error
################################################################################
reconfigure_devices()
{
  drd_media="$1"
  drd_beName="$2"

  ${LUPRINTF} -lp2D - "`gettext 'Reconfiguring devices for BE <%s>'`" "${drd_beName}"

  # reconfigure devices.  We first look for the latest and greatest
  # tools to do this.  Failing that, we fall back to what was used
  # on older OS's, since we might be running on such a system.
  if [ -x /usr/sbin/devfsadm ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Reconfiguring devices using devfsadm'`"
    /usr/sbin/devfsadm -R ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (devfsadm) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi
  elif [ -x /usr/sbin/drvconfig ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Reconfiguring devices using devlinks'`"

    /usr/sbin/drvconfig -R ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (drvconfig) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi

    /usr/sbin/devlinks -r ${drd_media} -t ${drd_media}/etc/devlink.tab > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (devlinks) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi

    /usr/sbin/disks -r ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (disks) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi

    /usr/sbin/ports -r ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (ports) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi
  else
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices for BE <%s>.  Cannot find devfsadm or drvconfig'`" "${drd_beName}"
  fi

  # and force a reconfiguration boot
  touch ${drd_media}/reconfigure > /dev/null 2>&1
  if [ $? != 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to force reconfiguration boot for BE <%s>.'`" "${drd_beName}"
    return 2
  fi

  # everythign worked  
  return 0
}

################################################################################
# Name:		create_be_mountpoints
# Description:	Make sure that all devices that can be mounted on a BE have mount points
#		(directories) created in the BEs root file system.
# Local Prefix: cbm_
# Arguments:	$1 = media mount point where BEs root file system is mounted
# Returns:      0 = mount points created
#		1 = mount points not created
################################################################################
create_be_mountpoints()
{
  cbm_bootMnt="$1"
  cbm_vfstab="${cbm_bootMnt}/etc/vfstab"

  ${LUPRINTF} -lp2D 1 "`gettext 'create_be_mountpoints: bootMnt <%s> vfstab <%s>.'`" "${cbm_bootMnt}" "${cbm_vfstab}"

  # If vfstab file does not exist or is empty then no work to do
  if [ ! -f "${cbm_vfstab}" -o ! -s "${cbm_vfstab}" ] ; then
    ${LUPRINTF} -lp2D 1 "`gettext 'vfstab file does not exist on target BE: no mount points created.'`"
    return 0
  fi

  # vfstab file has contents - find all mountable filesystems and make sure
  # that the BE has directories for each mount point. Format of vfstab file is:
  # 
  # ---> device       device       mount      FS      fsck    mount      mount
  # ---> to mount     to fsck      point      type    pass    at boot    options

  ${LUBIN}/lucomm_del "${cbm_vfstab}" | while read line ; do
    ${LUPRINTF} -lp2D 3 "`gettext 'vfstab line: <%s>.'`" "${line}"
    set $line
    cbm_v_mntdev="$1"
    cbm_v_fsckdev="$2"
    cbm_v_mntpt="$3"
    cbm_v_fstype="$4"
    cbm_v_fsckpass="$5"
    cbm_v_mntatboot="$6"

    ${LUPRINTF} -lp2D 2 "`gettext 'mntdev <%s> fsckdev <%s> mntpt <%s> fstype <%s> fsckpass <%s> mntatboot <%s>.'`" \
     "${cbm_v_mntdev}" "${cbm_v_fsckdev}" "${cbm_v_mntpt}" "${cbm_v_fstype}" "${cbm_v_fsckpass}" "${cbm_v_mntatboot}"

    # Skip if mount point does not begin with "/" and have at least one
    # character after it.
    cbm_x="`echo \"${cbm_v_mntpt}\" | /bin/egrep -c '^/.' 2>/dev/null`"
    if [ "${cbm_x}" != "1" ] ; then
      ${LUPRINTF} -lp2D 2 "`gettext 'Skipping device <%s> mount point <%s>: does not begin with </?>.'`" "${cbm_v_mntdev}" "${cbm_v_mntpt}"
      continue
    fi

    # Skip if fstype is not one that live upgrade supports.
    for cbm_for_fstype in ${LU_SUPPORTED_FILE_SYSTEM_TYPES} FSTYPE_NOT_FOUND ; do
      if [ "${cbm_v_fstype}" = "${cbm_for_fstype}" ] ; then
	break
      fi
    done

    # Skip if the file system type is not recognized.
    if [ -z "${cbm_v_fstype}" -o "${cbm_for_fstype}" = "FSTYPE_NOT_FOUND" ] ; then
      ${LUPRINTF} -lp2D 2 "`gettext 'Skipping device <%s> mount point <%s>: fstype <%s> not supported.'`" "${cbm_v_mntdev}" "${cbm_v_mntpt}" "${cbm_v_fstype}"
      continue
    fi

    # If the mount point does not already exist, create it.
    if [ ! -d "${cbm_bootMnt}${cbm_v_mntpt}" ] ; then
      ${LUPRINTF} -lp2D 1 "`gettext 'Creating device <%s> mount point <%s>.'`" "${cbm_v_mntdev}" "${cbm_bootMnt}${cbm_v_mntpt}"
      ERRMSG="`/bin/mkdir -p \"${cbm_bootMnt}${cbm_v_mntpt}\"`"
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} -Elp2D - "`gettext 'Cannot create mount point <%s>: %s.'`" "${cbm_bootMnt}${cbm_v_mntpt}" "${ERRMSG}"
      fi
    else
      ${LUPRINTF} -lp2D 2 "`gettext 'Skipping device <%s> mount point <%s>: mount point already exists.'`" "${cbm_v_mntdev}" "${cbm_v_mntpt}"
    fi
  done

  return 0
}


################################################################################
# Name:		update_x86boot
# Description:	Reconfigures boot-path setting on a BE, based on the currently-active BE.
# Local Prefix: u86_
# Arguments:	$1 = media mount point to reconfigure
#		$2 = BE name
# Returns:      0 = reconfiguration was successful.
#		2 = internal error
################################################################################
update_x86boot()
{
  u86_bootMnt="$1"
  u86_beName="$2"

  if [ "${LU_SYSTEM_ARCH}" != i386 ]; then
      return 0
  fi

  ${LUPRINTF} -lp2D - "`gettext 'update_x86Boot: <%s> <%s>'`" "u86_bootMnt: ${u86_bootMnt}" "u86_beName: ${u86_beName}"

  # this is done in 3 steps:
  # 1. Nuke old [ABE]/boot/bootenv.rc, since it likely contains bogus settings
  # 2. Copy [PBE]/boot/bootenv.rc contents to [ABE]/boot/bootenv.rc
  # 3. Update boot-path settings in [ABE]/boot/bootenv.rc
  # if we don't do this, the ABE will most likely have an invalid
  # bootenv.rc and will not boot.

  # first do some checks
  if [ ! -f "${u86_bootMnt}/boot/solaris/bootenv.rc" -o ! -s "${u86_bootMnt}/boot/solaris/bootenv.rc" ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: No /boot information <%s> found \
for BE <%s>.  Boot device settings cannot be updated.  The BE is unbootable.'`" \
"${u86_bootMnt}/boot/solaris/bootenv.rc" "${u86_beName}"
	return 2
  fi

  # 
  # now update the file
  # Since luupgrade will always operate on a GRUB aka newboot BE: in the mirrored
  # case it is okay to have logical (md) paths as the bootpath 
  # DCA boot aka legacy cannot handle (md) paths in the boot path.
  # 
  #
  u86_dsk=`/bin/cat ${u86_bootMnt}/etc/vfstab | /bin/grep -v "^#" | /bin/awk ' { if($3 == "/") { print $1 } } '`

  ${LUPRINTF} -lp2D - "u86_dsk: ${u86_dsk}"
  if [  -z "${u86_dsk}" ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: Boot device for BE <%s> Cannot be determined.'`" "${u86_beName}"
	return 2
  fi
  u86_dev=`/bin/ls -l ${u86_bootMnt}/${u86_dsk} | /bin/sed 's/.*\/devices\//\//g'`
  if [  -z "${u86_dev}" ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: Boot device specifier for BE <%s> Cannot be determined.'`" "${u86_beName}"
	return 2
  fi
  u86_rc=${u86_bootMnt}/boot/solaris/bootenv.rc
  /bin/grep -v "setprop bootpath" ${u86_rc} > ${u86_rc}.tmp 2>/dev/null
  u86_old=`/bin/grep "setprop bootpath" ${u86_rc} 2> /dev/null | /bin/awk '{print $3}'`
  u86_new=${u86_dev}
  ${LUPRINTF} -lp2D - "`gettext 'Old boot-path: <%s>.'`" "${u86_old}"
  ${LUPRINTF} -lp2D - "`gettext 'New boot-path: <%s>.'`" "${u86_new}"
  echo "setprop bootpath ${u86_new}" >> ${u86_rc}.tmp
  /bin/cp ${u86_rc}.tmp ${u86_rc}
  /bin/rm -f ${u86_rc}.tmp

  return 0
}

#
# This function modifies mount point of
# boot partition to /stubboot in ABE vfstab
# 
modify_x86_boot_entry()
{
    dxbe_bootMnt="$1"

    if [ "${LU_SYSTEM_ARCH}" != "i386" ]; then
        return 0
    fi

    ${LUPRINTF} -lp2D - "`gettext 'Checking for x86 boot entry in ABE vfstab.'`"

    /bin/grep -s -v '^#' "${dxbe_bootMnt}/etc/vfstab" | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null
    if [ "$?" -ne 0 ]; then
    	${LUPRINTF} -lp2D - "`gettext 'No x86 /boot entry in ABE vfstab.'`"
        return 0
    fi

    ${LUPRINTF} -lp2D - "`gettext 'Found x86 /boot entry in ABE vfstab.'`"

    DXBE_TMP_FILE="/tmp/.luupgrade.dxbe.$$"

    ERRMSG=`/bin/cp -p "${dxbe_bootMnt}/etc/vfstab" "$DXBE_TMP_FILE" 2>&1`
    if [ "$?" -ne 0 ]; then
        ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
        ${LUPRINTF} -Eelp2 "`gettext 'Cannot copy vfstab file <%s>.'`" "${dxbe_bootMnt}/etc/vfstab"
        return 1
    fi

    /bin/grep -s -v "[	]/boot[	]*pcfs[	]" "$DXBE_TMP_FILE" >  "${dxbe_bootMnt}/etc/vfstab"
    if [ "$?" -ne 0 ]; then
        ${LUPRINTF} -Eelp2 "`gettext 'Cannot delete boot entry from vfstab file <%s>.'`" "${dxbe_bootMnt}/etc/vfstab"
        /bin/cp -p "$DXBE_TMP_FILE" "${dxbe_bootMnt}/etc/vfstab" 2>&1
        return 1
    fi

    dxbe_entry=`/bin/grep -v '^#' "$DXBE_TMP_FILE" | /bin/grep "[	]/boot[	]*pcfs[	]"`
    dxbe_e1=`echo "$dxbe_entry" | /bin/awk '{print $1}'` 
    dxbe_e2=`echo "$dxbe_entry" | /bin/awk '{print $2}'` 
    dxbe_e3=`echo "$dxbe_entry" | /bin/awk '{print $3}' | /bin/sed 's/\/boot/\/stubboot/g'`
    dxbe_e4=`echo "$dxbe_entry" | /bin/awk '{print $4}'` 
    dxbe_e5=`echo "$dxbe_entry" | /bin/awk '{print $5}'` 
    dxbe_e6=`echo "$dxbe_entry" | /bin/awk '{print $6}' | /bin/sed 's/no/yes/g'` 
    dxbe_e7=`echo "$dxbe_entry" | /bin/awk '{print $7}'` 

    # Create /stubboot on ABE if it does not exist
    /bin/mkdir -p "${dxbe_bootMnt}/stubboot"

    echo "$dxbe_e1	$dxbe_e2	$dxbe_e3	$dxbe_e4	$dxbe_e5	$dxbe_e6	$dxbe_e7" >> "${dxbe_bootMnt}/etc/vfstab"

    ${LUPRINTF} -lp1 "`gettext 'Modified boot partition entry in ABE vfstab.'`"

    /bin/rm -f "$DXBE_TMP_FILE"

    return 0
}

delete_x86_boot_backing()
{
    dxbp_bootMnt="$1"

    if [ "${LU_SYSTEM_ARCH}" != "i386" ]; then
        return 0
    fi

    #
    # First delete the ABE's boot partition
    #
    ${LUPRINTF} -lp2D - "`gettext 'Deleting x86 boot backing on ABE.'`"

    #
    # We may or may not have umounted ABE's boot partition
    # 
    /usr/sbin/umount "${dxbp_bootMnt}/boot" 2>/dev/null
    if [ "$?" -ne 0 ]; then 
        ${LUPRINTF} -lp2D 4 "`gettext 'ABE x86 boot partition is not mounted.'`"
    fi
    /usr/sbin/lofiadm -d ${dxbp_bootMnt}/etc/lu/.dd_x86_boot_copy 2>/dev/null
    if [ "$?" -ne 0 ]; then 
        ${LUPRINTF} -lp2D 4 "`gettext 'ABE x86 boot backing is not a lofi device.'`"
    fi

    /bin/rm -f ${dxbp_bootMnt}/etc/lu/.dd_x86_boot_copy
    if [ "$?" -ne 0 ]; then
        ${LUPRINTF} -Eelp2 "`gettext 'failed to delete ABE x86 boot backing.'`"
    else
        ${LUPRINTF} -lp1 "`gettext 'ABE boot partition backing deleted.'`"
    fi

    # The existing (pre-newboot) code, as a side effect refreshed PBE's
    # /etc/lu/.dd_x86_boot_copy with the boot partition contents.
    # We do the same here to preserve that behavior
    ${LUPRINTF} -lp2D - "`gettext 'Checking for x86 boot partition on PBE.'`"

    /bin/grep -s -v '^#' /etc/vfstab | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null
    if [ "$?" -ne 0 ]; then
    	${LUPRINTF} -lp2D - "`gettext 'No x86 boot partition on PBE.'`"
        return 0
    fi

    DXBP_TMP_FILE="/tmp/.luupgrade.dxbp.$$"
    DXBP_TMP_FILE1="/tmp/.luupgrade.dxbp1.$$"

    ${LUPRINTF} -lp2D - "`gettext 'x86 boot partition exists on PBE.'`"

    diskid="`/bin/grep -s -v '^#' /etc/vfstab | /bin/grep \"[	]/boot[	]*pcfs[	]\" | awk '{print $1}' | sed -e 's:p0\:boot::g'`"
    diskid="`basename $diskid`"
    /usr/sbin/fdisk -W "${DXBP_TMP_FILE}" /dev/rdsk/${diskid}p0
    /bin/grep -v \* "${DXBP_TMP_FILE}" | /bin/grep -v '^[ 	]*$' > ${DXBP_TMP_FILE1}
    /bin/rm -f "${DXBP_TMP_FILE}"

    num=1
    while read id act bhead bcyl ehead ecyl rsect numsect
    do
       if [ ! -z "$id" ]; then
          if [ "$id" -eq "190" ]; then
              bootpart_id=/dev/rdsk/${diskid}p${num}
              ${LUPRINTF} -lp1 "`gettext 'PBE <%s> boot partition is <%s>.'`" "${CURR_BE}" "$bootpart_id"

              ${LUPRINTF} -lp1 "`gettext 'saving PBE boot partition.'`"
              ERRMSG="`/bin/dd if=$bootpart_id of=/etc/lu/.dd_x86_boot_copy 2>&1`"
              if [ "$?" -ne "0" ]; then
                 ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
                 ${LUPRINTF} -Eelp2 "`gettext 'Unable to save copy of active BE <%s> X86 boot partition.'`" "${CURR_BE}" "${bootpart_id}"

    		 /bin/rm -f "${DXBP_TMP_FILE}"
		 /bin/rm -f "${DXBP_TMP_FILE1}"
                 return 1
              fi
          fi
       fi
       num=`expr $num + 1`
    done < ${DXBP_TMP_FILE1}

    /bin/rm -f "${DXBP_TMP_FILE}"
    /bin/rm -f "${DXBP_TMP_FILE1}"

    ${LUPRINTF} -lp2D - "`gettext 'saved PBE boot partition copy in <%s>.'`" "/etc/lu/.dd_x86_boot_copy"

    return 0
}

configure_failsafe()
{
  cfg_miniMntpt="$1"
  cfg_beName="$2"

  cfg_tmp1=/tmp/.luupgrade.cfg.1.$$
  cfg_tmp2=/tmp/.luupgrade.cfg.2.$$

  if [ "${LU_SYSTEM_ARCH}" != i386 ]; then
      return 0
  fi

  #
  # Setting this flag ensures that configured failsafe and
  # multiboot are copied to the ABE in umount_miniroot()
  #
  INSTALL_FAILSAFE_ON="$cfg_beName"

  ${LUPRINTF} -lp1 "`gettext 'Configuring failsafe for system.'`"

  cfg_pbenv="/boot/solaris/bootenv.rc"
  if [ ! -f "$cfg_pbenv" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'Parent BE is missing boot settings file <%s>.'`" "${cfg_pbenv}"
     return 0
  fi

  cfg_bootenv="${cfg_miniMntpt}/boot/solaris/bootenv.rc"
  if [ -f "$cfg_bootenv" ]; then
     /bin/egrep -v "^[ 	]*setprop[ 	]+console[ 	]+" $cfg_bootenv > $cfg_tmp1
     /bin/egrep -v "^[ 	]*setprop[ 	]+input-device[ 	]+" $cfg_tmp1 > $cfg_tmp2
     /bin/egrep -v "^[ 	]*setprop[ 	]+output-device[ 	]+" $cfg_tmp2 > $cfg_tmp1
     /bin/rm -f $cfg_tmp2
  else
     # Not a fatal error
     ${LUPRINTF} -Welp2 "`gettext 'Default failsafe is missing boot settings file <%s>.'`" "${cfg_bootenv}"
     /bin/rm -f $cfg_tmp1
     /bin/rm -f $cfg_tmp2
  fi

  pbeSetting=`/bin/egrep "^[ 	]*setprop[ 	]+console[ 	]+" ${cfg_pbenv} | /bin/awk '{print $3}'`
  if [ -n "$pbeSetting" ]; then
     /bin/echo "setprop console $pbeSetting" >> $cfg_tmp1
  fi

  pbeSetting=`/bin/egrep "^[ 	]*setprop[ 	]+input-device[ 	]+" ${cfg_pbenv} | /bin/awk '{print $3}'`
  if [ -n "$pbeSetting" ]; then
     /bin/echo "setprop input-device $pbeSetting" >> $cfg_tmp1
  fi

  pbeSetting=`/bin/egrep "^[ 	]*setprop[ 	]+output-device[ 	]+" ${cfg_pbenv} | /bin/awk '{print $3}'`
  if [ -n "$pbeSetting" ]; then
     /bin/echo "setprop output-device $pbeSetting" >> $cfg_tmp1
  fi

  /bin/cp "$cfg_tmp1" "$cfg_bootenv" 
  /bin/rm -f $cfg_tmp1

  ${LUPRINTF} -lp1 "`gettext 'Failsafe configuration is complete.'`"
  return 0
}

install_failsafe()
{
  inf_beName="$1"

  inf_mntpt="/tmp/.luupgrade.inf.$$"

  if [ "${LU_SYSTEM_ARCH}" != i386 ]; then
      return 0
  fi

  ${LUPRINTF} -lp1 "`gettext 'Installing failsafe'`"

  if [  ! -f "${TMP_FAILSAFE_MULTIBOOT}" -o ! -s "${TMP_FAILSAFE_MULTIBOOT}" ]; then 
     ${LUPRINTF} -Eelp2 "`gettext 'Cannot find failsafe multiboot <%s>.'`" "${TMP_FAILSAFE_MULTIBOOT}"
     return 1
  fi

  if [  ! -f "${TMP_FAILSAFE_ARCHIVE}" -o ! -s "${TMP_FAILSAFE_ARCHIVE}" ]; then 
     ${LUPRINTF} -Eelp2 "`gettext 'Cannot find failsafe archive <%s>.'`" "${TMP_FAILSAFE_ARCHIVE}"
     return 1
  fi

  #
  # The failsafe archive is uncompressed at this point
  # Compress it before copying over to ABE
  #
  /bin/gzip "${TMP_FAILSAFE_ARCHIVE}" > /dev/null
  if [ "$?" -ne 0 ]; then 
     ${LUPRINTF} -Eelp2 "`gettext 'Cannot compress failsafe archive.'`"
     return 1
  fi

  if [  ! -f "${TMP_FAILSAFE_ARCHIVE}.gz" -o ! -s "${TMP_FAILSAFE_ARCHIVE}.gz" ]; then 
     ${LUPRINTF} -Eelp2 "`gettext 'Cannot find compressed failsafe archive.'`"
     return 1
  fi

  /bin/mkdir -p  "$inf_mntpt"
  inf_mntpt=`LU_OUTPUT_FORMAT=text $LUBIN/lumount "$inf_beName" "$inf_mntpt"`
  if [ "$?" -ne 0 ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${inf_beName}"
     /bin/rmdir "$inf_mntpt" > /dev/null 2>&1
     return 1
  fi

  /bin/cp -p "${TMP_FAILSAFE_MULTIBOOT}" "${inf_mntpt}/${FAILSAFE_MULTI_BOOT}"
  ret1="$?"
  /bin/cp -p "${TMP_FAILSAFE_ARCHIVE}.gz" "${inf_mntpt}/${LU_FAILSAFE_ARCHIVE}"
  ret2="$?"

  $LUBIN/luumount -f "$inf_beName" > /dev/null 2>&1
  /bin/rmdir "$inf_mntpt" > /dev/null 2>&1

  if [ "$ret1" -eq 0 -a "$ret2" -eq 0 ]; then
     ${LUPRINTF} -lp1 "`gettext 'Failsafe install is complete.'`"
     return 0
  else
     ${LUPRINTF} -Eelp2 "`gettext 'Failsafe install failed.'`"
     return 1
  fi
}

#
# With GRUB boot, systems no longer have a boot partition.
# For the ABE, if it has a boot partition, copy the contents
# into /boot on the ABE root filesystem before invoking pfinstall.
#
# Arguments:
#	$1 - mountpoint of the ABE
#	$2 - boot partition device (in c-t-d-p0:boot format). This may or
#	     may not exist. It must be a block (/dsk/) device.
# Returns
#	0 on success
#	1 on failure
#
convert_x86_boot_partition()
{
   #
   # Check args. Argument 2 is optional.
   #
   if [ "$#" -ne 2 -o -z "$1" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'convert_x86_boot_partition: Invalid arguments.'`"
      return 1
   fi

   cxb_abeMntpt="$1"
   cxb_abeBoot="$2"

   UMNTED=""
   cxb_x86_boot_copy="/tmp/.luupgrade.cxb.1.$$"
   cxb_tmpBootMnt="/tmp/.luupgrade.cxb.2.$$"
   ERRMSG="/tmp/.luupgrade.cxb.3.$$"


   #
   # First check if the ABE has a boot partition. if it doesn't we don't
   # anything to do so just return success
   #
   if [ -z "$cxb_abeBoot" ]; then
      return 0
   fi


   if [ -z "$cxb_abeMntpt" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'ABE mountpoint not specified.'`"
      return 1
   fi

   echo "$cxb_abeBoot" | /bin/grep "/dsk/" > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> is not a block device.'`" "$cxb_abeBoot"
      return 1
   fi

   ${LUPRINTF} -lp1 "`gettext 'Converting x86 boot partition on ABE'`"

   cxb_abeBootChar=`/bin/echo "$cxb_abeBoot" | /bin/sed "s/\/dsk\//\/rdsk\//g"`
   cxb_abeBootReal=`lulib_get_real_boot_partition "$cxb_abeBootChar"`
   if [ "$?" -ne 0 -o -z "$cxb_abeBootReal" ]; then 
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot determine real boot partition for: <%s>.'`" "$cxb_abeBootChar"
      return 1
   fi

   # Check if the x86 boot fdisk partition is mounted. If it is, unmount it
   cxb_abeBootMnt=`/sbin/mount | /bin/nawk -v dev=$cxb_abeBoot ' { if ($3 == dev) {printf("%s\n", $1); exit 8;}}'`
   if [ "$?" -eq 8 -a -n "$cxb_abeBootMnt" ]; then
      /sbin/umount "$cxb_abeBootMnt"
      if [ "$?" -ne 0 ]; then
         ${LUPRINTF} -Eelp2 "`gettext 'cannot unmount: <%s>.'`" "$cxb_abeBoot"
         return 1
      fi
      UMNTED=1
   fi

   # unmount the lofi-mounted ABE boot partition backing file
   /sbin/umount "${cxb_abeMntpt}/boot"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to umount X86 boot device at <%s>.'`" "${cxb_abeMntpt}/boot"
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # remove file from lofi control
   /usr/sbin/lofiadm -d "${cxb_abeMntpt}/etc/lu/.dd_x86_boot_copy"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to lofi delete X86 boot device at <%s>.'`" "${cxb_abeMntpt}/etc/lu/.dd_x86_boot_copy"
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # Save the current contents of the x86 boot partition
   /bin/dd if="$cxb_abeBootReal" of="$cxb_x86_boot_copy" > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'cannot save x86 boot partition: <%s>.'`" "$cxb_abeBootReal"
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # Copy the ABE's boot partition contents to the boot partition
   /bin/dd if="${cxb_abeMntpt}/etc/lu/.dd_x86_boot_copy" of="$cxb_abeBootReal" > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'cannot copy ABE x86 boot partition: <%s>.'`" "$cxb_abeBootReal"
      /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # Now mount the boot partition
   /bin/mkdir -p "$cxb_tmpBootMnt"
   /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_tmpBootMnt"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'cannot mount ABE x86 boot partition: <%s>.'`" "$cxb_abeBoot"
      /bin/rmdir "$cxb_tmpBootMnt"
      /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   /bin/mkdir -p "${cxb_abeMntpt}/boot"
   old_path=`pwd`
   cd "$cxb_tmpBootMnt"
   /bin/find . -mount \! -type s -print 2>"$ERRMSG" | /bin/cpio -pcdum "${cxb_abeMntpt}/boot" 2>&1
   if [ "$?" -ne "0" ]; then
      ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to copy boot partition to ABE root filesystem.'`"
      cd "$old_path" 
      /sbin/umount "$cxb_tmpBootMnt"
      /bin/rmdir "$cxb_tmpBootMnt"
      /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   cd "$old_path"

   cxb_errors=0
   /sbin/umount "$cxb_tmpBootMnt"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to umount temporary mount of <%s>.'`" "$cxb_abeBoot"
      cxb_errors=1
   fi
   /bin/rmdir "$cxb_tmpBootMnt"
   /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore content of boot partition <%s>.'`" "$cxb_abeBoot"
      cxb_errors=1
   fi
   if [ -n "$UMNTED" ]; then
      /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      if [ "$?" -ne 0 ]; then
         ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot partition <%s>.'`" "$cxb_abeBoot"
         cxb_errors=1
      fi
   fi

   return "$cxb_errors"
}

################################################################################
# Name:		do_flashInstall
# Description:	Flash operating system installation.
# Local Prefix:	dfi_
# Arguments:	$1 = current BE
#		$2 = boot environment name to install flash on.
#		$3 = path to profile template to use ("" if none).
#		$4 = profile template to use ("" if none).
#		$5 = no execute mode ("" if not enabled).
#		$6 = dry run mode ("" if not enabled).
#		$7 = media mount point for flash installation source.
#		$8 = flash archives ("" if profile in use)
# Returns:
################################################################################
do_flashInstall()
{
  dfi_beCurr="$1"
  dfi_beName="$2"
  dfi_profilePath="$3"
  dfi_profile="$4"
  dfi_noExecuteMode="$5"
  dfi_dryRunMode="$6"
  dfi_media="$7"
  dfi_archives="$8"

  ${LUPRINTF} -lp2D - "`gettext 'Flash Install CURR_BE <%s> BE <%s> Profile \
Path <%s> Profile <%s> NoExecuteMode <%s> DryRun <%s> Media <%s> Archives <%s>.'`" \
"${dfi_beCurr}" "${dfi_beName}" "${dfi_profilePath}" "${dfi_profile}" \
"${dfi_noExecuteMode}" "${dfi_dryRunMode}" "${dfi_media}" "${dfi_archives}"

  ######################################################################################
  ############### If x86, verify that the system has biosdev installed #################
  ######################################################################################

  if [ "$LU_SYSTEM_ARCH" = "i386" ]; then

     lulib_check_patch
     if [ "$?" -ne 0 ]; then
        return 2
     fi
  fi

  ######################################################################################
  ########## Verify that the media has a Solaris Operating System Image on it ##########
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dfi_media}"

  lulib_validate_is_directory_not_empty "${dfi_media}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The Flash option (-f) option requires that you \
specify the OS media location with the <-s> option.'`"
    return 3
  fi

  # find the media cd table of contents: if not found, can not figure version,
  # so cannot use it to flash a BE
  dfi_media_cdtoc="${dfi_media}/.cdtoc"
  if [ ! -f "${dfi_media_cdtoc}" -o ! -s "${dfi_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> is not a recognized installation media.'`" "${dfi_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dfi_errorsFound=""
  dfi_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dfi_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dfi_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dfi_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dfi_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dfi_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dfi_media_proddir="${dfi_media}/${dfi_cdtoc_proddir}"
  dfi_media_toolsDir="`dirname ${dfi_media_proddir}`/Tools"
  if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
      dfi_media_bootLoaderDir="${dfi_media_toolsDir}/Boot/boot/grub"
  else
      dfi_media_bootLoaderDir=""
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Product Name <%s> Version <%s>.'`" "${dfi_cdtoc_prodname}" "${dfi_cdtoc_prodvers}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Tools Directory <%s>.'`" "${dfi_media_toolsDir}" 
  ${LUPRINTF} -lp2D - "`gettext 'Media Bootloader Directory <%s>.'`" "${dfi_media_bootLoaderDir}"

  if [ -z "${dfi_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product name.'`"
    dfi_errorsFound="1"
  fi
  if [ -z "${dfi_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product version.'`"
    dfi_errorsFound="1"
  fi
  if [ -z "${dfi_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dfi_errorsFound="1"
  fi
  if [ -n "${dfi_cdtoc_proddir}" ] ; then
    if [ ! -d "${dfi_media_toolsDir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product tools directory <%s> does not exist.'`" "${dfi_media_toolsDir}"
      dfi_errorsFound="1"
    fi
  fi

  if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
    if [ ! -d "${dfi_media_bootLoaderDir}" ]; then 
      ${LUPRINTF} -Eelp2 "`gettext 'The media Boot loader directory <%s> does not exist.'`" "${dfi_media_bootLoaderDir}"
      dfi_errorsFound="1"
    fi
  fi

  if [ -n "${dfi_errorsFound}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain a usable flash install image.'`" "${dfi_media}"
    return 2
  fi

  ######################################################################################
  ########## Verify that the miniroot exists  ##########################################
  ######################################################################################
  dfi_miniroot=${dfi_media_toolsDir}/Boot

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the miniroot <%s>.'`" "${dfi_miniroot}"

  lulib_validate_is_directory_not_empty "${dfi_miniroot}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The Flash option (-f) requires that you specify a \
valid os media image with the <-s> option.'`"
    return 3
  fi

  #
  # verify that the ABE has /boot.  If it does not then we cannot flash the
  # ABE because we will not be able to make it bootable.
  #
  dfi_ret=0
  if [ "${LU_SYSTEM_ARCH}" = "i386" -a \( ! -f "/${LU_BOOTENV}" -o ! -s "/${LU_BOOTENV}" \) ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: This machine does not have <%s> (required on \
x86).  ABE cannot be flashed'`" "/${LU_BOOTENV}"
	return 2
  fi

	######################################################################################
	####################### Determine which pfinstall root to use ########################
	######################################################################################

	${LUPRINTF} -lp1 "`gettext 'Locating the flash install program.'`"

	dfi_libDir="${dfi_miniroot}/usr/snadm/lib"
	dfi_pfinstallDir="${dfi_miniroot}/usr/sbin/install.d"

	lulib_validate_is_directory "${dfi_libDir}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The pfinstall library directory <%s> does not exist.'`" "${dfi_libDir}"
		return 2
	fi

	lulib_validate_is_directory_not_empty "${dfi_pfinstallDir}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product directory <%s> does not exist.'`" "${dfi_pfinstallDir}"
		return 2
	fi

	dfi_pfinstallExecutable="${dfi_pfinstallDir}/pfinstall"
	if [ ! -x "${dfi_pfinstallExecutable}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product <%s> does not exist or is not executable.'`" "${dfi_pfinstallExecutable}"
		return 2
	fi

	# yes, /usr/sbin needs to be in the LD_LIBRARY_PATH.  It's for sys-unconfig.
	dfi_sbinDir="${dfi_miniroot}/usr/sbin"
	dfi_ldLibraryPath="${dfi_libDir}:${dfi_sbinDir}"
	[ -n "${LD_LIBRARY_PATH}" ] && dfi_ldLibraryPath="${dfi_ldLibraryPath}:${LD_LIBRARY_PATH}"

	${LUPRINTF} -lp2D - "`gettext 'Flash install program to use is <%s>.'`" "${dfi_pfinstallExecutable}"

	# Determine if this pfinstall supports the upgrade_mountpoint and/or
	# the transfer_list_types capabilities.  The "-a" option to pfinstall
	# (as of S10B27/S9U4) supports inquiring pfinstall for its
	# "capabilities". The new "upgrade_mountpoint" capability allows
	# mounting of file systems to be bypassed when doing a flash update.
	# The "transfer_list_types" capability supports a third column in the
	# transfer list file which indicates the type of transfer to perform.
	# To check for these, run
	# 'pfinstall -a sw:upgrade_mountpoint,transfer_list_types' - if it
	# does not return '3' or does not return '<capability_name>=true' then
	# that new capability is NOT implemented
	

	dfi_umcap=""
	dfi_tltcap=""
	dfi_pfcap="`LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} -a sw:upgrade_mountpoint,transfer_list_types 2>/dev/null`"

	if [ "$?" -eq "3" ]; then
	    for cap in $dfi_pfcap; do
		if [ "$cap" = "upgrade_mountpoint=true" ] ; then
		    ${LUPRINTF} -lp2D - "`gettext '<%s> implements sw:upgrade_mount capability.'`" \
		    "${dfi_pfinstallExecutable}"
		    dfi_umcap="yes"
		elif [ "$cap" = "transfer_list_types=true" ] ; then
		    ${LUPRINTF} -lp2D - "`gettext '<%s> implements sw:transfer_list_types capability.'`" \
		    "${dfi_pfinstallExecutable}"
		    dfi_tltcap="yes"
		fi
	    done
	fi

	if [ "${dfi_umcap}" != "yes" ] ; then
	    ${LUPRINTF} -lp2D - "`gettext '<%s> does NOT implement sw:upgrade_mount capability.'`" \
	    "${dfi_pfinstallExecutable}"
	fi

	if [ "${dfi_tltcap}" != "yes" ] ; then
	    ${LUPRINTF} -lp2D - "`gettext '<%s> does NOT implement sw:transfer_list_types capability.'`" \
	    "${dfi_pfinstallExecutable}"
	fi


	######################################################################################
	############ Check for copylock and fail if one exists.  Currently you can only ######
	############ schedule a flash install if no other operation is pending (including ####
	############ a scheduled copy for our BE  ############################################
	######################################################################################

	## Check to see if a copy lock exists. If so then:
	## 1- if any operation is scheduled on any BE, fail
	## 2- only if no operations are scheduled will we succeed

	${LUPRINTF} -lp1 "`gettext 'Checking for existence of previously scheduled Live Upgrade requests.'`"

	lulib_validate_lulock
	if [ -f "${COPYLOCK}" -a -s "${COPYLOCK}" ] ; then
		. ${COPYLOCK}
		if [ "${dfi_beName}" = "$CL_TARGET_BE" ]; then
			${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy Lock exists: Status <%s> Source BE <%s> Target BE <%s>.'`" "${CL_STATUS}" "${CL_SOURCE_BE}" "${CL_TARGET_BE}"
			${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy operation is schedule for this BE <%s>. You cannot flash this BE until the previous operation completes.'`" "${CL_TARGET_BE}"
			return 2
		fi
	fi
	## No copy operation is (or has been) scheduled: do the flash; create copy lock and allow it to be deleted on exit.

	copylock_create "CL_STATUS" "FLASHING" "yes"
	dfi_ret="$?"
	if [ "${dfi_ret}" -eq "0" ] ; then
		copylock_append "CL_TARGET_BE" "${dfi_beName}"
		dfi_ret="$?"
	fi
	if [ "${dfi_ret}" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to create copy lock file: unable to flash the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	######################################################################################
	######### Verify that the upgrade media mount point exists and is a directory ########
	######################################################################################

	# Make sure the media root mount point exists and is a directory.
	if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
		# Mount point is not a directory.
		if [ -r ${MEDIAROOTMOUNTPOINT} ] ; then
			# its a readable file!!
			${LUPRINTF} -Eelp2 "`gettext 'Media root mount point <%s> exists and is not a \
directory. Please remove or rename the file and try again.'`" "${MEDIAROOTMOUNTPOINT}"
			return 2
		fi
		# Attempt to create the media root mount point.
		/bin/mkdir ${MEDIAROOTMOUNTPOINT}
		if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
			# Could not create the mount point!
			${LUPRINTF} -Eelp2 "`gettext 'ERROR: Media root mount point <%s> could not be \
created.'`" "${MEDIAROOTMOUNTPOINT}"
			return 2
		fi
	fi

  ######################################################################################
  ####################### Construct the profile to use  ################################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Constructing flash profile to use.'`"

  ## Construct a pfinstall flash profile:
  ## - copy the default flash profile ${FLASH_PROFILE} to ${TMP_FLASH_PROFILE}
  ## - if the user specified -j profile file to use, append that;
  ## - else if user specified -J 'profile' on command line, append that;
  ## - otherwise, if user specified -a 'archives', append them.
  ## At end, ${TMP_FLASH_PROFILE} will have the path to the template to use 
  ## for flashing a BE.

  FLASH_TYPE="install"

  # if profile path was specified, validate it
  if [ -n "${dfi_profilePath}" ] ; then
    checkUserFlashProfile "${dfi_profilePath}"
    if [ $? -ne 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The file <%s> can not be used as a \
flash install profile.'`" "${dfi_profilePath}"
      return 2
    fi
  fi



  if [ $FLASH_TYPE = "install" ] ; then

	### #
	#   #
	### #
	#   #
	#   #

	# Make sure default flash profile exists
	if [ ! -f "${FLASH_PROFILE}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The default flash profile <%s> does not \
exist.'`" "${FLASH_PROFILE}"
		return 2
	fi

	# Create the upgrade profile to use starting with the default profile
	ERRMSG="`${LUBIN}/lucomm_del ${FLASH_PROFILE} > ${TMP_FLASH_PROFILE}`"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
		${LUPRINTF} -Eelp2 "`gettext 'Cannot create temporary profile <%s> from \
<%s>.'`" "${TMP_FLASH_PROFILE}" "${FLASH_PROFILE}"
		return 2
	fi

	# if profile path was specified, copy it in place
	if [ -n "${dfi_profilePath}" ] ; then
		ERRMSG="`${LUBIN}/lucomm_del ${dfi_profilePath} | \
/bin/egrep -v '^[ 	]*install_type[ 	]*flash_install[ 	]*$' >> ${TMP_FLASH_PROFILE}`"
		if [ "$?" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
			${LUPRINTF} -Eelp2 "`gettext 'Cannot append flash profile <-j %s> to <%s>.'`" \
			"${dfi_profilePath}" "${TMP_FLASH_PROFILE}"
			return 2
		fi
	elif [ -n "${dfi_profile}" ] ; then
		# literal profile was specified, echo it in place
		echo "${dfi_profile}" >> ${TMP_FLASH_PROFILE}
	elif [ -n "${dfi_media}" ] ; then
		# path to actual flash archive(s) were given.  Use them if they exist
		for dfi_flar in `echo ${dfi_archives}` ; do
			if [ ! -f "${dfi_flar}" -o ! -s "${dfi_flar}" ] ; then
				${LUPRINTF} -Eelp2 "`gettext 'The archive <%s> can not be found.'`" "${dfi_flar}"
				return 3
			else
				${LUPRINTF} +X -a "${TMP_FLASH_PROFILE}" "archive_location local_file %s" "${dfi_flar}"
			fi
		done
	else
		${LUPRINTF} -Eelp2 "`gettext 'The -f option must specify an archive set (-a), profile path (-j), or literal profile (-J) to use'`"
		return 3
	fi

	# at this point, the profile template has been completed and is in ${TMP_FLASH_PROFILE}

	${LUPRINTF} -lp2D - "`gettext 'Flash profile is <%s>.'`" \
	"${TMP_FLASH_PROFILE}"

	######################################################################################
	################## Create partition information for flash profile   ##################
	######################################################################################

	${LUPRINTF} -lp1 "`gettext 'Creating flash profile for BE <%s>.'`" "${dfi_beName}"

	# Create ICF file for the current be.
	$LUBIN/lumk_iconf "${dfi_beCurr}" | sort -t: +1 -2 > ${PBE_ICF}
	if [ $? -ne 0 ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration \
information for current BE <%s>.'`" "${dfi_beCurr}"
		return 2
	fi

	# Create ICF file for the target be.  Filter out shared filesystems.
	$LUBIN/lumk_iconf "${dfi_beName}" | sort -t: +1 -2 > ${ABE_ICF}
	if [ $? -ne 0 ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration \
information for BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	${LUETCBIN}/ludo filter_shared_and_swap ${PBE_ICF} ${ABE_ICF} > ${COMBINED_ICF}

	# Add in the slices of the target BE for pfinstall to make and mount.
	${LUPRINTF} +X -a "${TMP_FLASH_PROFILE}" "partitioning explicit"
	/bin/nawk -F":" ' { n = split ($3, path, "/") ; printf "filesys %s existing %s\n", path[n], $2 } ' \
< ${COMBINED_ICF} >> ${TMP_FLASH_PROFILE}
  




	# Now massage lu_transfer_list to resolve wildcards that might appear in the
	# transferlist.
	dfi_transList=`resolve_transfer_list /etc/lu/lu_transfer_list`
	if [ "$?" != 0 ] ; then
		# Could not make the transfer list
		${LUPRINTF} -Eelp2 "`gettext 'ERROR: Unable to generate transfer list.'`"
		return 2
	fi
    

	######################################################################################
	############################### --> DO THE FLASH <-- #################################
	######################################################################################

	# N.B. pfinstall expects to mount all of the slices defined in the target o.s.'s vfstab file
	# when it exits these slices remain mounted. For this reason we first need to umount the
	# BE file systems we previously mounted so pfinstall's mounts will not fail. We need to
	# take this into account after pfinstall exits so that we can clean up properly.

	# Setup common pfins1<tall arguments:
	# -L path - root mount point where target boot environment will be mounted (should be /a!).
	# profile - the profile to use to drive the upgrade.
	# -x n - debugging level (1..9 is on).
	#
	# Return codes from pfinstall are:
	# EXIT_INSTALL_SUCCESS_REBOOT     0	(successful - system rebooted)
	# EXIT_INSTALL_SUCCESS_NOREBOOT   1	(successful - system not rebooted)
	# EXIT_INSTALL_FAILURE            2	(An error occurred)

	dfi_pfComArgs="-L ${MEDIAROOTMOUNTPOINT} -p / -t ${dfi_transList} -o ${dfi_miniroot} ${TMP_FLASH_PROFILE}"
	if [ "$LU_DEBUG" -ne "0" ] ; then
		dfi_pfComArgs="-x 10 ${dfi_pfComArgs}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Using profile <%s>:\n**********\n%R\n**********\n'`" \
"${TMP_FLASH_PROFILE}" < "${TMP_FLASH_PROFILE}"

	### --> THIS CODE IS EXECUTED FOR "NO EXECUTE MODE" ONLY.. <--- ###
	### --> MUST MAKE SURE IT SYNCS UP WITH THE REAL CODE TOO. <--- ###

	if [ -n "${dfi_noExecuteMode}" ] ; then
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'Execute Command: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"
		# no patch install - this isn't a normal install, it's flash.
		return 0
	fi

	# Mount the target BE slices.
	abe_icfMount ${ABE_ICF}
	if [ "$?" != "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi
	dfi_bootMnt="${AIM_BEBOOTMNT}"

        ${LUPRINTF} -lp2D -  "`gettext 'ABE slices mounted at <%s>.'`" "${dfi_bootMnt}"

	# Save the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   save_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to save GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi


	# Unmount so pfinstall can do mount.
	abe_umount
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	# Prepare to run pfinstall
	if [ -z "${dfi_dryRunMode}" ] ; then
		# Not dry run mode: actually do the pfinstall
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash install of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'CAUTION: Interrupting this process may leave the boot environment unstable or unbootable.'`"

		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Performing the operating system flash install of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	else
		# It IS dry run mode: add -D (simulate) option to pfinstall
		dfi_pfComArgs="-D ${dfi_pfComArgs}"
		${LUPRINTF} -lp1 "`gettext 'Simulating the operating system flash install of the BE <%s>.'`" "${dfi_beName}"

		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Simulating the operating system flash install of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Executing: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs} 2>&1 1>${PFINSTALL_LOGFILE}"
	${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Using: %s'`" "`/bin/date`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"

	# yes, /usr/sbin needs to be in the LD_LIBRARY_PATH.  It's for sys-unconfig.
	dfi_sbinDir="${dfi_miniroot}/usr/sbin"
	dfi_ldLibraryPath="${dfi_libDir}:${dfi_sbinDir}"
	[ -n "${LD_LIBRARY_PATH}" ] && dfi_ldLibraryPath="${dfi_ldLibraryPath}:${LD_LIBRARY_PATH}"

	# First run pfinstall with the '-r' option and progress reporting enabled;
	# then check to see the results to determine whether or not this pfinstall
	# supports the -r option and progress reporting.
	/bin/rm -f "${PROGRESS_REPORT_FILE}" 2>/dev/null 1>&2
	LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} -r "${PROGRESS_REPORT_FILE}" ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1 &
	dfi_pfPid="$!"
	if [ -z "${_LU_OUTPUT_XML_}" ] ; then
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'text' "`gettext 'Extracting Flash Archive: %s%% completed'`" \
			'flash-extract' &
	else
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'xml' "${LU_PROG_NAME}" 'flash-extract' &
	fi
	fg "${dfi_pfPid}"
	dfi_ret="$?"

	# If the return code is "0" and the progress report file was NOT found then
	# this pfinstall is one that does not support the '-r' option. Rerun without
	# the -r option and any progress reporting.
	if [[ "${dfi_ret}" -eq "0" && ! -e "${PROGRESS_REPORT_FILE}" ]] ; then
		LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1
		dfi_ret="$?"
	fi

	# The return code for pfinstall when installing a flash archive
	# is '0' on success - any other code is a failure. In this case
	# stat_pfinstall can be set directly from pfinstall's return code.
	stat_pfinstall="${dfi_ret}"

	# if pfinstall returned any result > 1 then it failed - even though we continue
	# no patches will be added or any other work will be done - the reason we continue
	# is in the case where pfinstall may have mounted the file systems for the target
	# boot environment (probably on /a) in which case we need to do some special
	# work to restore the original vfstab file...

	if [ -n "${dfi_dryRunMode}" ] ; then
		# This was just a simulation of what would have been done.
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash install simulation failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash simulation failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		else
			${LUPRINTF} -lp1 "`gettext 'The operating flash install simulation completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash simulation completed; pfinstall results:'`"
			fi
		fi
	else
		# This was NOT a simulation but a real installation - report it as such
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash install failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		 else
			${LUPRINTF} -lp1 "`gettext 'The operating system flash install completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash install completed; pfinstall results:'`"
			fi
		fi
	fi

	# ABE will now be mounted on ${MEDIAROOTMOUNTPOINT}.
	# Change the location where we believe the ABEs backup vfstab file is located.
	# Make believe we mounted the ABEs slices (pfinstall should have done this for us).
	dfi_bootMnt=${MEDIAROOTMOUNTPOINT}
	change_vfstab_bootmnt "${dfi_bootMnt}"

	# Make sure that the ABEs root slice is mounted on the expected mount point.
	abe_checkMounted "${ABE_ICF}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Problem remounting the BE <%s>.'`" "${dfi_beName}"
	fi

	/bin/rm -f "${PFINSTALL_LOGFILE}"

	# Restore the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   restore_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi

	# If not in dry run mode, and the pfinstall was successful,
	# do work necessary to cleanup after the flash installation.

	if [ -z "${dfi_dryRunMode}" -a "${stat_pfinstall}" -eq "0" ] ; then
		# The BE now contains the contents of the flash archive; there may be
		# file systems that were configured into the BE that do not have mount
		# points in the flash archive. Add all mount points now.
		create_be_mountpoints "${MEDIAROOTMOUNTPOINT}"

		# reconfigure the device tree
		reconfigure_devices "${dfi_bootMnt}" "${dfi_beName}"
    
		if [ $? != 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices for BE <%s>.'`" "${dfi_beName}"
			return 2
		fi
    
		/bin/cp ${LU_LUTAB_FILE} ${dfi_bootMnt}/etc
		/bin/cp -r /etc/lu ${dfi_bootMnt}/etc
		/bin/rm -f ${dfi_bootMnt}/${COPYLOCK}

		# Unmount the boot environment just flashed
		abe_umount

  		${LUPRINTF} -lp2D - "`gettext 'ABE unmounted.'`"

		# Make the new boot environment bootable
		$LUBIN/lumkboot -i "${ABE_ICF}" -n "${dfi_beName}"
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to make boot environment <%s> bootable.'`" "${dfi_beName}"
			return 2
		fi

		# Mark the new boot environment as complete
		$LUBIN/lustat_set -n "${dfi_beName}" -s 'C'
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mark boot environment <%s> complete.'`" "${dfi_beName}"
			return 2
		fi

		dfi_bootMnt=`LU_OUTPUT_FORMAT=text $LUBIN/lumount $dfi_beName "${MEDIAROOTMOUNTPOINT}" 2>${TMP_RESULT_FILE}`
		if [ $? -ne 0 ] ; then
			[ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${dfi_beName}"
			return 2
		fi
  		${LUPRINTF} -lp2D - "`gettext 'ABE mounted at <%s>.'`"  "${dfi_bootMnt}"

		# now update the eeprom settings on the ABE if we are on x86.
		if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
			${LUPRINTF} -lp "`gettext 'Updating boot-path on ABE <%s>.'`" "${dfi_beName}"
			#
			# The following just updates boot-path setting in bootenv.rc
			#
			update_x86boot ${dfi_bootMnt} ${dfi_beName}
			if [ $? != 0 ] ; then
				${LUPRINTF} -Eelp2 "`gettext 'Unable to update x86 boot partition  devices for BE <%s>.'`" "${dfi_beName}"
				return 2
			fi
    			#
    			# Customize the failsafe console setting based on PBE settings.
    			#
    			configure_failsafe "$LU_MINIROOT_MNTPT" "$dfi_beName" 
		fi

    
		delete_x86_boot_backing "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi
		modify_x86_boot_entry "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi

		# If the install log exists then add the contents of the upgrade log file 
		# to the mail log file.  This probably didn't happen unless the flash 
		# archive didn't overwrite the install log
    
		if [ -f "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" -a -s "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" ] ; then
			maillog_addFile "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" "`gettext 'Target BE install log file results:'`"
		fi

		$LUBIN/luumount -f "$dfi_beName" 2>/dev/null 1>&2
	else
		abe_umount
	fi

	# The flash installation is finished. Output completion status and return.

	if [ "${stat_pfinstall}" -ne "0" ] ; then
		${LUPRINTF} -lp1 "`gettext 'The Solaris flash install of the BE <%s> failed.'`" "${dfi_beName}"
		maillog_setSubject "`gettext 'Flash FAILED (Solaris flash install failed).'`"
		return 1
	fi
	${LUPRINTF} -lp1 "`gettext 'The Live Flash Install of the boot environment <%s> is complete.'`" "${dfi_beName}"
	maillog_setSubject "`gettext 'Flash install Completed.'`"
	return 0

  else

	### #  #
	#   #  #
	### #  #
	#   #  #
	#    ##

	# proceed with flash_update

	# Make sure default flash profile exists

	if [ ! -f "${FLASH_UPDATE_PROFILE}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The default flash_update profile <%s> does not \
exist.'`" "${FLASH_UPDATE_PROFILE}"
		return 2
	fi

	# Create the upgrade profile to use starting with the default profile
	ERRMSG="`${LUBIN}/lucomm_del ${FLASH_UPDATE_PROFILE} > ${TMP_FLASH_PROFILE}`"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
		${LUPRINTF} -Eelp2 "`gettext 'Cannot create temporary profile <%s> from \
<%s>.'`" "${TMP_FLASH_PROFILE}" "${FLASH_UPDATE_PROFILE}"
		return 2
	fi

	# if profile path was specified, validate it and copy it in place
	ERRMSG="`${LUBIN}/lucomm_del ${dfi_profilePath} | \
/bin/egrep -v '^[ 	]*install_type[ 	]*flash_update[ 	]*$' >> ${TMP_FLASH_PROFILE}`"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
		${LUPRINTF} -Eelp2 "`gettext 'Cannot append flash profile <-j %s> to <%s>.'`" \
		"${dfi_profilePath}" "${TMP_FLASH_PROFILE}"
		return 2
	fi

	# at this point, the profile template has been completed and is in ${TMP_FLASH_PROFILE}

	${LUPRINTF} -lp2D - "`gettext 'Flash profile is <%s>.'`" \
	"${TMP_FLASH_PROFILE}"

	# Create ICF file for the target be and filter out all "non-system" file systems.

	$LUBIN/lumk_iconf "${dfi_beName}" | sort -t: +1 -2 > ${ABE_ICF}
	if [ $? -ne 0 ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

	# Create new upgrade profile and add in the root slice of the target BE.

	dfi_abeRootSlice=`${LUETCBIN}/ludo get_root_slice_from_be_name ${dfi_beName}`

	if [ -z "${dfi_abeRootSlice}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine root slice for BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	${LUPRINTF} -lp2D - "`gettext 'Root device for update is <%s>.'`" "${dfi_abeRootSlice}"

	# If pfinstall implements the sw:upgrade_mountpoint capability, do NOT place
	# the root_device directive into the update profile. This is because if the
	# pfinstall sw:upgrade_mountpoint is implemented, and -L is specified with
	# no root_device in the profile, pfinstall assumes that all file systems are
	# already mounted at the -L location

	if [ -z "${dfi_umcap}" ] ; then
	  ${LUPRINTF} +X -a "${TMP_FLASH_PROFILE}" "root_device %s" "${dfi_abeRootSlice}"
	  ${LUPRINTF} -lp2D - "`gettext '<root_device %s> added to update profile <%s>.'`" \
      "${dfi_abeRootSlice}" "${TMP_FLASH_PROFILE}"
	else
	  ${LUPRINTF} -lp2D - "`gettext 'root_device NOT ADDED to update profile.'`"
	fi

	# Add in the slices of the target BE for pfinstall to make and mount.
	${LUPRINTF} +X -a "${TMP_FLASH_PROFILE}" "root_device %s" "${dfi_abeRootSlice}"

	# Mount the target BE slices.
	abe_icfMount ${ABE_ICF}
	if [ "$?" != "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi
	dfi_bootMnt="${AIM_BEBOOTMNT}"

        # At this point we have mounted the ABE including boot partition (if any)
        ${LUPRINTF} -lp2D - "`gettext 'ABE slices mounted at <%s>.'`" "${dfi_bootMnt}"

	# Save the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   save_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to save GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi

        # Check if ABE uses a boot partition before changing vfstab
        dfi_bootPart=""
        if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
            ${LUPRINTF} -lp1 "`gettext 'Checking for x86 boot partition on ABE.'`"
            /bin/grep -s -v '^#' "${dfi_bootMnt}/etc/vfstab" | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null 2>&1
            if [ "$?" -eq 0 ]; then
                dfi_bootPart=`/bin/grep -s -v '^#' "${dfi_bootMnt}/etc/vfstab" | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" | /usr/bin/awk '{print $1}'`
                ${LUPRINTF} -lp1 "`gettext 'x86 boot partition exists on ABE <%s>'`" "${dfi_beName}"
            fi
        fi

	# Backup the target ABE's vfstab file.

	backup_vfstab_file "${dfi_bootMnt}" "${dfi_beName}" "${ABE_ICF}"
	dfi_ret="$?"
	if [ "${dfi_ret}" -ne "0" ] ; then
		if [ "${dfi_ret}" -eq "1" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to save backup copy of vfstab file for BE <%s>.'`" "${dfi_beName}"
		fi
		return 2
	fi

	#--> At this point, the exit_script() code will automagically restore the       <--#
	#--> target boot environments vfstab file if it has not already been restored.  <--#
	#--> Because of this, there is no reason to include "restore_vfstab_file" calls <--#
	#--> before each error return from this function.                               <--#

	# Replace the target ABE's vfstab file with the one we created which only
	# has the "system" file systems on it. The "-I" option means do not include
	# any filesystems that are not mentioned in the ICF file.

	${LUBIN}/luedvfstab -i "${COMBINED_ICF}" -m "${dfi_bootMnt}" -n "${dfi_beName}" -I

	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to create revised vfstab file on BE.'`"
		return 2
	else
		${LUPRINTF} -lp2D - "`gettext 'boot environment <%s> temporary vfstab file:\
\n**********************************\n%R\n**********************************'`" \
"${dfi_beName}" < ${dfi_bootMnt}/etc/vfstab
	fi

	#
        # Do processing only for x86 boot partition on intel platforms
	# Before pfinstall runs, copy the contents of the ABE boot
	# partition and write it onto the ABE's root filesystem at <mntpt>/boot.
	#
        if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
	   convert_x86_boot_partition "$dfi_bootMnt" "$dfi_bootPart"
	   if [ "$?" -ne 0 ]; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to convert X86 boot partition.'`"
	      return 1
	   fi
        fi

	######################################################################################
	############################### --> DO THE FLASH <-- #################################
	######################################################################################

	# N.B. pfinstall expects to mount all of the slices defined in the target o.s.'s vfstab file
	# when it exits these slices remain mounted. For this reason we first need to umount the
	# BE file systems we previously mounted so pfinstall's mounts will not fail. We need to
	# take this into account after pfinstall exits so that we can clean up properly.

	# Setup common pfins1<tall arguments:
	# -L path - root mount point where target boot environment will be mounted (should be /a!).
	# profile - the profile to use to drive the upgrade.
	# -x n - debugging level (1..9 is on).
	#
	# Return codes from pfinstall are:
	# EXIT_INSTALL_SUCCESS_REBOOT     0	(successful - system rebooted)
	# EXIT_INSTALL_SUCCESS_NOREBOOT   1	(successful - system not rebooted)
	# EXIT_INSTALL_FAILURE            2	(An error occurred)


	dfi_pfComArgs="-L ${MEDIAROOTMOUNTPOINT} -p / -o ${dfi_miniroot} ${TMP_FLASH_PROFILE}"
	if [ "$LU_DEBUG" -ne "0" ] ; then
		dfi_pfComArgs="-x 10 ${dfi_pfComArgs}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Using profile <%s>:\n**********\n%R\n**********\n'`" \
"${TMP_FLASH_PROFILE}" < "${TMP_FLASH_PROFILE}"

	### --> THIS CODE IS EXECUTED FOR "NO EXECUTE MODE" ONLY.. <--- ###
	### --> MUST MAKE SURE IT SYNCS UP WITH THE REAL CODE TOO. <--- ###

	if [ -n "${dfi_noExecuteMode}" ] ; then
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'Execute Command: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"
		# no patch install - this isn't a normal install, it's flash.
		return 0
	fi

	# If the pfinstall sw:upgrade_mountpoint capability is implemented, the
	# mounting of file systems by pfinstall has already been disabled because
	# the "root_slice" directive has not been placed into the pfinstall
	# update profile. If the sw:upgrade_mountpoint capability is implemented,
	# there is no need to unmount the abe file systems before calling pfinstall

	if [ "${dfi_umcap}" = "yes" ] ; then
	  ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> remains mounted at <%s>.'`" \
      "${dfi_beName}" "${MEDIAROOTMOUNTPOINT}"
	else
	  # pfinstall sw:upgrade_mountpoint capability IS NOT IMPLEMENTED.
	  # Unmount so pfinstall can do mount.
	  abe_umount
	  if [ "$?" -ne "0" ] ; then
	    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dfi_beName}"
	    return 2
	  fi
	  ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> has been unmounted.'`" \
      "${dfi_beName}"
	fi

	# Prepare to run pfinstall
	if [ -z "${dfi_dryRunMode}" ] ; then
		# Not dry run mode: actually do the pfinstall
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash update of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'CAUTION: Interrupting this process may leave the boot environment unstable or unbootable.'`"
		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Performing the operating system flash update of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	else
		# It IS dry run mode: add -D (simulate) option to pfinstall
		dfi_pfComArgs="-D ${dfi_pfComArgs}"
		${LUPRINTF} -lp1 "`gettext 'Simulating the operating system flash update of the BE <%s>.'`" "${dfi_beName}"

		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Simulating the operating system flash update of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Executing: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs} 2>&1 1>${PFINSTALL_LOGFILE}"
	${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Using: %s'`" "`/bin/date`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"

	# yes, /usr/sbin needs to be in the LD_LIBRARY_PATH.  It's for sys-unconfig.
	dfi_sbinDir="${dfi_miniroot}/usr/sbin"
	dfi_ldLibraryPath="${dfi_libDir}:${dfi_sbinDir}"
	[ -n "${LD_LIBRARY_PATH}" ] && dfi_ldLibraryPath="${dfi_ldLibraryPath}:${LD_LIBRARY_PATH}"

	# First run pfinstall with the '-r' option and progress reporting enabled;
	# then check to see the results to determine whether or not this pfinstall
	# supports the -r option and progress reporting.
	/bin/rm -f "${PROGRESS_REPORT_FILE}" 2>/dev/null 1>&2
	LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} -r "${PROGRESS_REPORT_FILE}" ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1 &
	dfi_pfPid="$!"
	if [ -z "${_LU_OUTPUT_XML_}" ] ; then
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'text' "`gettext 'Extracting Flash Archive: %s%% completed'`" \
			'flash-extract' &
	else
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'xml' "${LU_PROG_NAME}" 'flash-extract' &
	fi
	fg "${dfi_pfPid}"
	dfi_ret="$?"

	# If the return code is "0" and the progress report file was NOT found then
	# this pfinstall is one that does not support the '-r' option. Rerun without
	# the -r option and any progress reporting.
	if [[ "${dfi_ret}" -eq "0" && ! -e "${PROGRESS_REPORT_FILE}" ]] ; then
		LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1
		dfi_ret="$?"
	fi

	# The return code for pfinstall when installing a flash archive
	# is '0' on success - any other code is a failure. In this case
	# stat_pfinstall can be set directly from pfinstall's return code.
	stat_pfinstall="${dfi_ret}"

	# if pfinstall returned any result > 1 then it failed - even though we continue
	# no patches will be added or any other work will be done - the reason we continue
	# is in the case where pfinstall may have mounted the file systems for the target
	# boot environment (probably on /a) in which case we need to do some special
	# work to restore the original vfstab file...

	if [ -n "${dfi_dryRunMode}" ] ; then
		# This was just a simulation of what would have been done.
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash update simulation failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash simulation failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		else
			${LUPRINTF} -lp1 "`gettext 'The operating flash update simulation completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash simulation completed; pfinstall results:'`"
			fi
		fi
	else
		# This was NOT a simulation but a real installation - report it as such
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash update failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		 else
			${LUPRINTF} -lp1 "`gettext 'The operating system flash update completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash update completed; pfinstall results:'`"
			fi
		fi
	fi

	# ABE will now be mounted on ${MEDIAROOTMOUNTPOINT}.
	# Change the location where we believe the ABEs backup vfstab file is located.
	# Make believe we mounted the ABEs slices (pfinstall should have done this for us).
	dfi_bootMnt=${MEDIAROOTMOUNTPOINT}
	change_vfstab_bootmnt "${dfi_bootMnt}"

	# Make sure that the ABEs root slice is mounted on the expected mount point.
	abe_checkMounted "${ABE_ICF}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Problem remounting the BE <%s>.'`" "${dfi_beName}"
	fi

        ${LUPRINTF} -lp2D - "`gettext 'ABE is mounted at <%s>.'`" "$dfi_bootMnt"

	/bin/rm -f "${PFINSTALL_LOGFILE}"

	# Restore the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   restore_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi

	# If not in dry run mode, and the pfinstall was successful,
	# do work necessary to cleanup after the flash installation.

	if [ -z "${dfi_dryRunMode}" -a "${stat_pfinstall}" -eq "0" ] ; then

		restore_vfstab_file
		dfi_bootMnt=${VFST_BOOT_MNT}

		# The BE now contains the contents of the flash archive; there may be
		# file systems that were configured into the BE that do not have mount
		# points in the flash archive. Add all mount points now.
		create_be_mountpoints "${MEDIAROOTMOUNTPOINT}"

		# reconfigure the device tree
		reconfigure_devices "${dfi_bootMnt}" "${dfi_beName}"
    
		if [ $? != 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices for BE <%s>.'`" "${dfi_beName}"
			return 2
		fi
    
		/bin/cp ${LU_LUTAB_FILE} ${dfi_bootMnt}/etc
		/bin/cp -r /etc/lu ${dfi_bootMnt}/etc
		/bin/rm -f ${dfi_bootMnt}/${COPYLOCK}


		# Unmount the boot environment just flashed
		abe_umount

  		${LUPRINTF} -lp2D - "`gettext 'ABE unmounted.'`"

		# Make the new boot environment bootable
		$LUBIN/lumkboot -i "${ABE_ICF}" -n "${dfi_beName}"
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to make boot environment <%s> bootable.'`" "${dfi_beName}"
			return 2
		fi

		# Mark the new boot environment as complete
		$LUBIN/lustat_set -n "${dfi_beName}" -s 'C'
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mark boot environment <%s> complete.'`" "${dfi_beName}"
			return 2
		fi

		dfi_bootMnt=`LU_OUTPUT_FORMAT=text $LUBIN/lumount $dfi_beName "${MEDIAROOTMOUNTPOINT}" 2>${TMP_RESULT_FILE}`
		if [ $? -ne 0 ] ; then
			[ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${dfi_beName}"
			return 2
		fi
  		${LUPRINTF} -lp2D - "`gettext 'ABE mounted at <%s>.'`"  "${dfi_bootMnt}"

		# now update the eeprom settings on the ABE if we are on x86.
		if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
			${LUPRINTF} -lp "`gettext 'Updating boot-path on ABE <%s>.'`" "${dfi_beName}"
			#
			# The following just updates boot-path setting in bootenv.rc
			#
			update_x86boot ${dfi_bootMnt} ${dfi_beName}
			if [ $? != 0 ] ; then
				${LUPRINTF} -Eelp2 "`gettext 'Unable to update x86 boot partition  devices for BE <%s>.'`" "${dfi_beName}"
				return 2
			fi

    			#
    			# Customize the failsafe console setting based on PBE settings.
    			#
    			configure_failsafe "$LU_MINIROOT_MNTPT" "$dfi_beName" 
		fi
    
		delete_x86_boot_backing "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi
		modify_x86_boot_entry "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi

		# If the install log exists then add the contents of the upgrade log file 
		# to the mail log file.  This probably didn't happen unless the flash 
		# archive didn't overwrite the install log
    
		if [ -f "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" -a -s "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" ] ; then
			maillog_addFile "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" "`gettext 'Target BE install log file results:'`"
		fi

		$LUBIN/luumount -f "${dfi_beName}" 2>/dev/null 1>&2
	else
		abe_umount
	fi

	# The flash installation is finished. Output completion status and return.

	if [ "${stat_pfinstall}" -ne "0" ] ; then
		${LUPRINTF} -lp1 "`gettext 'The Solaris flash update of the BE <%s> failed.'`" "${dfi_beName}"
		maillog_setSubject "`gettext 'Flash FAILED (Solaris flash update failed).'`"
		return 1
	fi
	${LUPRINTF} -lp1 "`gettext 'The Live Flash Update of the boot environment <%s> is complete.'`" "${dfi_beName}"
	maillog_setSubject "`gettext 'Flash Update Completed.'`"
	return 0

  fi

}

################################################################################
# Name:		do_runInstaller
# Description:	Run installer on boot environment from specified media.
# Local Prefix:	dri_
# Arguments:	$1 = boot environment name to run installer against.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for installer ("" if none).
#		$4 = media mount point to run installer from.
#		$5 = command arguments to pass to installer on command line ("" if none).
# Returns:
################################################################################

do_runInstaller()
{
  dri_beName="$1"
  dri_noExecuteMode="$2"
  dri_optArgs="$3"
  dri_media="$4"
  dri_cmdArgs="$5"


  ${LUPRINTF} -lp2D - "`gettext 'Run installer BE <%s> NoExecuteMode <%s> Installer Args <%s %s> Media <%s>.'`" "${dri_beName}" "${dri_noExecuteMode}" "${dri_optArgs}" "${dri_cmdArgs}" "${dri_media}"

  ######################################################################################
  ################### Verify that the media has an installer present ###################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dri_media}"
  lulib_validate_is_directory_not_empty "${dri_media}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The run installer (-i) option requires that you specify the installer to run location with the <-s> option.'`"
    return 3
  fi

  dri_media_cdtoc="${dri_media}/.cdtoc"
  if [ ! -f "${dri_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> is not a recognized installation media.'`" "${dri_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dri_errorsFound=""
  dri_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dri_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dri_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dri_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dri_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dri_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dri_media_proddir="${dri_media}/${dri_cdtoc_proddir}"
  dri_media_installDir="${dri_media}/.install"
  dri_media_installer="${dri_media}/installer"

  ${LUPRINTF} -lp2D - "`gettext 'Product Name <%s> Version <%s>.'`" "${dri_cdtoc_prodname}" "${dri_cdtoc_prodvers}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Packages Directory <%s>.'`" "${dri_media_proddir}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Directory <%s>'`" "${dri_media_installDir}"
  ${LUPRINTF} -lp2D - "`gettext 'Installer <%s>'`" "${dri_media_installer}"

  if [ -z "${dri_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product name.'`"
    dri_errorsFound="1"
  fi
  if [ -z "${dri_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product version.'`"
    dri_errorsFound="1"
  fi
  if [ -z "${dri_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dri_errorsFound="1"
  fi
  if [ ! -d "${dri_media_installDir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media product install directory <%s> is missing.'`" "${dri_media_installDir}"
    dri_errorsFound="1"
  fi
  if [ ! -x "${dri_media_installer}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media product installer <%s> does not exist.'`" "${dri_media_installer}"
    dri_errorsFound="1"
  fi

  if [ -n "${dri_errorsFound}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain an operating system upgrade image.'`" "${dri_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media contains a standard Solaris installer.'`"

  ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> version <%s>.'`" "${dri_cdtoc_prodname}" "${dri_cdtoc_prodvers}"

  cd "${dri_media}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting BE <%s>.'`" "${dri_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${dri_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dri_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount BE <%s>.'`" "${dri_beName}"
    return 2
  fi
  dri_bootMnt="${AIM_BEBOOTMNT}"

  ######################################################################################
  ############### Locate "/usr/java/bin/java" on target boot environment ###############
  ######################################################################################

  # If the ABE contains a /usr/java, and /usr/java/bin/java exists and is an executable,
  # pass in "-java" followed by path to ABE /usr/java to the installer.

  dri_javaArgs=""
  dri_javaDir="${dri_bootMnt}/usr/java"
  dri_javaCmd="${dri_javaDir}/bin/java"

  if [ -d "${dri_javaDir}" -a -f "${dri_javaCmd}" -a -x "${dri_javaCmd}" ] ; then
    dri_javaVersion="`${dri_javaCmd} -version 2>&1 | /bin/head -1`"
    dri_javaArgs="-java ${dri_javaDir}"
    ${LUPRINTF} -lp2D - "`gettext 'ABE Java at <%s> arg <%s> version <%s>'`" \
    "${dri_javaDir}" "${dri_javaArgs}" "${dri_javaVersion}"
  fi

  ######################################################################################
  ################################# Run the Installer ##################################
  ######################################################################################

  # Setup installer arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from installer are:
  # 0  - Successful execution.
  # >0 - Failure.
  #
  # Because of various issues an installation may appear to be successful ($? == 0)
  # when infact there were problems. To deal with this, the fact that the installer
  # generated any output is used to determine whether or not to notify the system
  # administrator about a possible problem.

  dri_installComArgs="${dri_javaArgs} ${dri_optArgs} -R ${dri_bootMnt} ${dri_cmdArgs}"

  ${LUPRINTF} -lp1 "`gettext 'Running installer on BE <%s>.'`" "${dri_beName}"
  if [ -n "${dri_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "${dri_media_installer} ${dri_installComArgs}"
  else
    PKG_INSTALL_ROOT="${dri_bootMnt}" ${dri_media_installer} ${dri_installComArgs}
  fi

  if [ -z "${dri_dryRunMode}" ] ; then

	# reset flag indicating whether or not there are log files to review

	dri_reviewFiles=""

	# Determine if package instance data needs to be refreshed:
	# If running a Solaris release that does not support zones, and upgrading to a
	# Solaris release that does support zones, upgrade package instance data on the abe. 

	sourceRelease=$(lulib_normalize_os_version "$(/bin/uname -r)")

	targetRelease=$(lulib_normalize_os_version 5.$(/bin/grep '^VERSION=' \
		${dri_bootMnt}/var/sadm/system/admin/INST_RELEASE | \
		/bin/sed 's/VERSION=//'))

	${LUPRINTF} -lp2D - "`gettext 'OS Releases: current <%s> upgraded <%s>.'`" \
		"${sourceRelease}" "${targetRelease}"

	# If upgrading to release that supports zones from one that does not,
	# make sure all package instance data is updated on the ABE.

	if [[ "${sourceRelease}" -le 51000 && "${targetRelease}" -ge 51000 ]] ; then
		# Update package information on the ABE

		${LUPRINTF} -lp1 -a "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Updating package information on boot environment <%s>.'`" "${dri_beName}"

		${LUETCBIN}/ludo update_package_instance_data "${dri_media}"\
		    "${dri_bootMnt}" 2>> "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}"

		if [ "$?" -ne "0" ] ; then

			${LUPRINTF} -Eelp2 -a "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Unable to update package instance information on boot environment <%s>.'`" "${dri_beName}"

		else

			${LUPRINTF} -lp1 -a "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Package information successfully updated on boot environment <%s>.'`" "${dri_beName}"

		fi
	fi

    ###
    ### Review all log files and output appropriate messages.
    ###

    # If the upgrade log exists let the user know where the upgrade log is.

    if [ -f "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" -a -s "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" ] ; then

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of the upgrade operation.'`" "${PFINSTALL_UPGRADE_LOG}" \
"${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext '<%s> contains a log of the upgrade operation.'`" "${PFINSTALL_UPGRADE_LOG}"
      dri_reviewFiles="yes"
    fi

    # If the upgrade cleanup exists and it then add the contents of the upgrade
    # cleanup file to the mail log file. Also, let the user know where the 
    # upgrade cleanup is.

    if [ -f "${dri_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" -a -s "${dri_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" ] ; then

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of cleanup operations required.'`" "${PFINSTALL_UPGRADE_CLEANUP}" \
"${dri_beName}"

      dri_reviewFiles="yes"
    fi

    # If the failed package log exists add the contents of the failed package log
    # file to the mail log file. Also, let the user know where the failed
    # package log is.

    if [ -f "${dri_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" -a -s "${dri_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" ] ; then
      ${LUPRINTF} -Welp2 "`gettext '<%d> packages failed to install properly \
on boot environment <%s>.'`" "`/bin/cat ${dri_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS} | \
/bin/wc -l`" "${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that failed to upgrade or install properly.'`" \
"${PFINSTALL_UPGRADE_FAILED_PKGADDS}" "${dri_beName}"

      dri_reviewFiles="yes"
    fi

    # If the packages to be added log exists add the contents of the packages 
    # to be added log file to the mail log file. Also, let the user know
    # where the packages to be added log is.

    if [ -f "${dri_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" -a -s "${dri_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" ] ; then
      ${LUPRINTF} -Welp2 "`gettext '<%d> packages must be installed on boot environment <%s>.'`" \
"`/bin/grep -c '^PKG=' ${dri_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}`" "${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that must be installed on the boot environment \
for the upgrade to be complete. The packages in this list were not present \
on the media that was used to upgrade this boot environment.'`" \
"${PFINSTALL_PACKAGES_TO_BE_ADDED}" "${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'If the boot environment was upgraded using \
one media of a multiple media distribution, for example the Solaris CD media, \
you must continue the upgrade process with the next media. Complete the \
upgrade by using the luupgrade <-i> option to install the next media of the \
distribution. Failure to complete the upgrade process with all media of the \
software distribution makes the boot environment unstable.'`"
      dri_reviewFiles="yes"
    fi

    # If files were listed, request that user review the file contents.
    if [ -n "${dri_reviewFiles}" ] ; then
      ${LUPRINTF} -fIlp1 "`gettext 'Review the files listed above. Remember \
that all of the files are located on boot environment <%s>. Before you \
activate boot environment <%s>, determine if any additional system maintenance \
is required or if additional media of the software distribution must be \
installed.'`" "${dri_beName}" "${dri_beName}"
    fi

  fi

  # Unmount the target boot environment

  ${LUPRINTF} -lp1 "`gettext 'Unmounting BE <%s>.'`" "${dri_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount BE <%s>.'`" "${dri_beName}"
  fi

  ${LUPRINTF} -lp1 "`gettext 'The installer run on boot environment <%s> is complete.'`" "${dri_beName}"

  return 0
}

################################################################################
# Name:		do_addPackages
# Description:	Add packages on boot environment from specified media.
# Local Prefix:	dap_
# Arguments:	$1 = boot environment name to add packages to.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkgadd ("" if none).
#		$4 = media mount point to run pkgadd from.
#		$5 = command arguments to pass to pkgadd on command line ("" if none).
# Returns:	0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_addPackages()
{
  dap_beName="$1"
  dap_noExecuteMode="$2"
  dap_optArgs="$3"
  dap_media="$4"
  dap_cmdArgs="$5"

  ${LUPRINTF} -lp2D - "`gettext 'Add packages BE <%s> Media <%s> NoExecuteMode \
<%s> Pkgadd Args <%s %s> '`" "${dap_beName}" "${dap_media}" \
"${dap_noExecuteMode}" "${dap_optArgs}" "${dap_cmdArgs}"

  ######################################################################################
  ##################### Verify that the media has packages present #####################
  ######################################################################################

  # Packages can either be contained in a directory, or in a file that has
  # packages in "package stream" format. If a directory is passed in make 
  # sure it has contents. If a file is passed in, leave it to pkgadd to
  # determine if it is valid.
  if [ ! -f "${dap_media}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dap_media}"
    lulib_validate_is_directory_not_empty "${dap_media}"
    if [ $? -ne 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The add packages (-p) option requires that \
you specify the packages location with the <-s> option.'`"
      return 3
    fi

    cd "${dap_media}"
  fi

  ######################################################################################
  ######### Verify that any packages specified on the command line are present #########
  ######################################################################################

  # If package media is a directory and arguments given, make sure
  # the arguments exist and are directories.
  if [ -d "${dap_media}" -a -n "${dap_cmdArgs}" ] ; then
    dap_packagesNotFound=""
    for dap_packageRequested in ${dap_cmdArgs} ; do
      dap_packageFound=""
      if [ -d "${dap_media}/${dap_packageRequested}" ] ; then
	/usr/sbin/pkgchk -d "${dap_media}" "${dap_packageRequested}" 1>/dev/null 2>&1
	if [ "$?" -eq "0" ] ; then
	    dap_packageFound="yes"
	else
	  dap_packagesNotFound="${dap_packageRequested} ${dap_packagesNotFound}"
	fi
      fi
    done
    if [ -n "${dap_packagesNotFound}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain these requested packages: <%s>.'`" "${dap_media}" "${dap_packagesNotFound}"
      return 2
    fi
  fi

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dap_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${dap_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dap_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dap_beName}"
    return 2
  fi
  dap_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dap_beName}" "${dap_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ################################## Add the packages ##################################
  ######################################################################################

  # Setup command pkgadd arguments:
  # -M Do not use the BE's etc/vfstab file for determining the mount points.
  # -R path - Define the full path name of a directory to use as the root-path.
  # -d Install or copy a package from device (full path to directory).
  # -v Trace all of the scripts that get executed by pkgadd.
  #
  # Return code from pkgadd are:
  # 0  - Successful execution.
  # 1  - Fatal error.
  # 2  - Warning.
  # 3  - Interruption.
  # 4  - Administration.
  # 5  - Administration. Interaction is required.  Do  not  use  pkgadd -n.
  # 10 - Reboot after installation of all packages.
  # 20 - Reboot after installation of this package.

  dap_pkgaddComArgs="${dap_optArgs} -M -R ${dap_bootMnt} -d ${dap_media} ${dap_cmdArgs}"
  if [ "$LU_DEBUG" -ne "0" ] ; then
    dap_pkgaddComArgs="-v $dap_pkgaddComArgs"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Adding packages to the BE <%s>.'`" "${dap_beName}"
  if [ -n "${dap_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/pkgadd ${dap_pkgaddComArgs}"
    dap_ret="0"
  else
    /usr/sbin/pkgadd ${dap_pkgaddComArgs} 
    dap_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dap_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dap_beName}"
  fi

  case "${dap_ret}" in 
    0|10|20|3|13|23) # Successful execution, Reboot After Installation of all packages, Reboot after installation of this package, Interruption.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> completed.'`" "${dap_beName}"
       return 0
       ;;
    1|11|21) # Fatal error.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed with a Fatal Error.'`" "${dap_beName}"
       return 1
       ;;
    2|12|22) # Warning.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> completed with Warnings.'`" "${dap_beName}"
       return 0
       ;;
    4|14|24) # Administration.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed because Administrative action is required.'`" "${dap_beName}"
       return 1
       ;;
    5|15|25) # Administration. Interaction is required.  Do  not  use  pkgadd -n.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed because Administrative Interaction is required (do not use the pkgadd -n option).'`" "${dap_beName}"
       return 1
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed (with result code <%s>).'`" "${dap_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_addPatches
# Description:	Add patches to the boot environment from specified media.
# Local Prefix:	dpa_
# Arguments:	$1 = boot environment name to add patches to.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for patchadd ("" if none).
#		$4 = media mount point to run patchadd from.
#		$5 = command arguments to pass to patchadd on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_addPatches()
{
  dpa_beName="$1"
  dpa_noExecuteMode="$2"
  dpa_optArgs="$3"
  dpa_media="$4"
  dpa_cmdArgs="$5"

  ${LUPRINTF} -lp2D - "`gettext 'Add patches BE <%s> Media <%s> NoExecuteMode <%s> patchadd Args <%s %s> '`" "${dpa_beName}" "${dpa_media}" "${dpa_noExecuteMode}" "${dpa_optArgs}" "${dpa_cmdArgs}"

  ######################################################################################
  ###################### Verify that the media has patches present #####################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dpa_media}"
  lulib_validate_is_directory_not_empty "${dpa_media}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The add patches (-P) option requires that you specify the patches location with the <-s> option.'`"
    return 3
  fi

  cd "${dpa_media}"
  dpa_patchList=""
  dpa_patchCount="0"
  for dpa_patchCandidate in ??* ; do
    if [ -d "${dpa_patchCandidate}" -a '(' -f "${dpa_patchCandidate}/.diPatch" -o -f "${dpa_patchCandidate}/installpatch" ')' ] ; then
      if [ -z "${dpa_patchList}" ] ; then
	dpa_patchList="${dpa_patchCandidate}"
      else
	dpa_patchList="${dpa_patchList} ${dpa_patchCandidate}"
      fi
      dpa_patchCount="`/bin/expr ${dpa_patchCount} + 1`"
    fi
  done

  if [ "${dpa_patchCount}" -eq "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain any software patches that can be installed.'`" "${dpa_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media contains %d software patches that can be added.'`" "${dpa_patchCount}"
  ${LUPRINTF} -lp2D - "`gettext 'The media contains these %d software patches that can be added: <%s>.'`" "${dpa_patchCount}" "${dpa_patchList}"

  ######################################################################################
  ###### If any files are specified, extract any patches contained in those files ######
  ######################################################################################

  if [ -n "${dpa_cmdArgs}" ] ; then
    dpa_newCmdArgs=""
    for dpa_patchRequested in ${dpa_cmdArgs} ; do
      if [ -f "${dpa_media}/${dpa_patchRequested}" -a -s "${dpa_media}/${dpa_patchRequested}" ] ; then
	${LUPRINTF} -lp2D - "`gettext 'Adding patches from file <%s>.'`" "${dpa_media}/${dpa_patchRequested}"
	if [ "`/bin/wc -w < \"${dpa_media}/${dpa_patchRequested}\" 2>/dev/null`" -gt "${MAX_PATCHES_FROM_FILE}" ] ; then
	  ${LUPRINTF} -Eelp2 "`gettext 'The file <%s> can not be used because it has too many possible patch names (over %d).'`" "${dpa_media}/${dpa_patchRequested}" "${MAX_PATCHES_FROM_FILE}"
	  return 3
	fi
	dpa_newCmdArgs="${dpa_newCmdArgs} `/bin/cat ${dpa_media}/${dpa_patchRequested}`"
      else
	dpa_newCmdArgs="${dpa_newCmdArgs} ${dpa_patchRequested}"
      fi
    done
    dpa_cmdArgs="${dpa_newCmdArgs}"
  fi

  ######################################################################################
  ######### Verify that any patches specified on the command line are present #########
  ######################################################################################

  if [ -n "${dpa_cmdArgs}" ] ; then
    # One of more patches specified - verify they really exist
    dpa_patchesNotFound=""
    for dpa_patchRequested in ${dpa_cmdArgs} ; do
      dpa_patchFound=""
      for dpa_patchCandidate in ${dpa_patchList} ; do
	if [ "${dpa_patchRequested}" = "${dpa_patchCandidate}" ] ; then
	  dpa_patchFound="yes"
	  break
	fi
      done
      if [ -z "${dpa_patchFound}" ] ; then
	dpa_patchesNotFound="${dpa_patchRequested} ${dpa_patchesNotFound}"
      fi
    done
    if [ -n "${dpa_patchesNotFound}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain these requested patches: <%s>.'`" "${dpa_media}" "${dpa_patchesNotFound}"
      return 2
    fi
  else
    # No patches specified - assume all patches are to be added
    ${LUPRINTF} -lp1 "`gettext 'All %s patches will be added because you did not specify any specific patches to add.'`" "${dpa_patchCount}"
    dpa_cmdArgs="${dpa_patchList}"
  fi

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dpa_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${dpa_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dpa_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dpa_beName}"
    return 2
  fi
  dpa_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dpa_beName}" "${dpa_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ################################## Add the patches ##################################
  ######################################################################################

  # Setup command patchadd arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  # -M patch_dir patch_id ... | patch_dir patch_list
  #
  # Return code from patchadd are:
  # 0  - Successful execution.
  # >0 - Failure.

  dpa_patchaddComArgs="${dpa_optArgs} -R ${dpa_bootMnt} -M ${dpa_media} ${dpa_cmdArgs}"

  ${LUPRINTF} -lp1 "`gettext 'Adding patches to the BE <%s>.'`" "${dpa_beName}"
  if [ -n "${dpa_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/patchadd ${dpa_patchaddComArgs}"
    dpa_ret="0"
  else
    /usr/sbin/patchadd ${dpa_patchaddComArgs}
    dpa_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dpa_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dpa_beName}"
  fi

  case "${dpa_ret}" in 
    0) # Successful execution, Reboot After Installation of all patches, Reboot after installation of this patch.
       ${LUPRINTF} -lp1 "`gettext 'The patch add to the BE <%s> completed.'`" "${dpa_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The patch add to the BE <%s> failed (with result code <%s>).'`" "${dpa_beName}" "${dpa_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_removePackages
# Description:	Remove packages from boot environment.
# Local Prefix:	drp_
# Arguments:	$1 = boot environment name to remove packages from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkgrm ("" if none).
#		$4 = command arguments to pass to pkgrm on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_removePackages()
{
  drp_beName="$1"
  drp_noExecuteMode="$2"
  drp_optArgs="$3"
  drp_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Remove packages BE <%s> NoExecuteMode <%s> Pkgrm Args <%s %s>.'`" "${drp_beName}" "${drp_noExecuteMode}" "${drp_optArgs}" "${drp_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${drp_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${drp_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${drp_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${drp_beName}"
    return 2
  fi
  drp_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${drp_beName}" "${drp_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ######## Verify that any packages specified on the command line are installed ########
  ######################################################################################

  if [ -n "${drp_cmdArgs}" ] ; then
    drp_packagesNotFound=""
    for drp_packageRequested in ${drp_cmdArgs} ; do
      /bin/pkginfo -R "${drp_bootMnt}" -q "${drp_packageRequested}"
      if [ "$?" -ne "0" ] ; then
	drp_packagesNotFound="${drp_packageRequested} ${drp_packagesNotFound}"
      fi
    done
    if [ -n "${drp_packagesNotFound}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The BE <%s> does not have these packages installed: <%s>.'`" "${drp_beName}" "${drp_packagesNotFound}"
      return 2
    fi
  fi

  ######################################################################################
  ################################ Remove the packages #################################
  ######################################################################################

  # Setup command pkgrm arguments:
  # -M Do not use the BE's etc/vfstab file for determining the mount points.
  # -R path - Define the full path name of a directory to use as the root-path.
  # -v Trace all of the scripts that get executed by pkgrm.
  #
  # Return code from pkgrm are:
  # 0  - Successful execution.
  # >0 - Failure.

  drp_pkgrmComArgs="${drp_optArgs} -M -R ${drp_bootMnt} ${drp_cmdArgs}"
  if [ "$LU_DEBUG" -ne "0" ] ; then
    drp_pkgrmComArgs="-v $drp_pkgrmComArgs"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Removing packages from the BE <%s>.'`" "${drp_beName}"
  if [ -n "${drp_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/pkgrm ${drp_pkgrmComArgs}"
    drp_ret="0"
  else
    /usr/sbin/pkgrm ${drp_pkgrmComArgs}
    drp_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${drp_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${drp_beName}"
  fi

  case "${drp_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The package remove from the BE <%s> completed.'`" "${drp_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package remove from the BE <%s> failed (with result code <%s>).'`" "${drp_beName}" "${drp_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_infoPackages
# Description:	Obtain information on packages from boot environment.
# Local Prefix:	dip_
# Arguments:	$1 = boot environment name to retrieve information on packages from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkginfo ("" if none).
#		$4 = command arguments to pass to pkginfo on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_infoPackages()
{
  dip_beName="$1"
  dip_noExecuteMode="$2"
  dip_optArgs="$3"
  dip_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Information on packages BE <%s> NoExecuteMode <%s> Pkginfo Args <%s %s>.'`" "${dip_beName}" "${dip_noExecuteMode}" "${dip_optArgs}" "${dip_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dip_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${dip_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dip_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dip_beName}"
    return 2
  fi
  dip_bootMnt="${AIM_BEBOOTMNT}"

  ######################################################################################
  ################################ Get the package info ################################
  ######################################################################################

  # Setup command pkginfo arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from pkginfo are:
  # 0  - Successful execution.
  # >0 - Failure.

  dip_pkginfoComArgs="${dip_optArgs} -R ${dip_bootMnt} ${dip_cmdArgs}"

  ${LUPRINTF} -lp1 "`gettext 'Retrieving package information from the BE <%s>.'`" "${dip_beName}"
  if [ -n "${dip_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/bin/pkginfo ${dip_pkginfoComArgs}"
    dip_ret="0"
  else
    /bin/pkginfo ${dip_pkginfoComArgs}
    dip_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dip_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dip_beName}"
  fi

  case "${dip_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> completed.'`" "${dip_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> failed (with result code <%s>).'`" "${dip_beName}" "${dip_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_checkPackages
# Description:	Check on packages from boot environment.
# Local Prefix:	dcp_
# Arguments:	$1 = boot environment name to check on packages from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkgchk ("" if none).
#		$4 = command arguments to pass to pkgchk on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_checkPackages()
{
  dcp_beName="$1"
  dcp_noExecuteMode="$2"
  dcp_optArgs="$3"
  dcp_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Checking packages BE <%s> NoExecuteMode <%s> Pkgchk Args <%s %s>.'`" "${dcp_beName}" "${dcp_noExecuteMode}" "${dcp_optArgs}" "${dcp_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dcp_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${dcp_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dcp_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dcp_beName}"
    return 2
  fi
  dcp_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dcp_beName}" "${dcp_bootMnt}"
  [ $? -ne 0 ] && return 1


  ######################################################################################
  ################################ Check the packages ##################################
  ######################################################################################

  # Setup command pkgchk arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from pkgchk are:
  # 0  - Successful execution.
  # >0 - Failure.

  dcp_pkgchkComArgs="${dcp_optArgs} -R ${dcp_bootMnt} ${dcp_cmdArgs}"

  if [ "$LU_DEBUG" -ne "0" ] ; then
    dcp_pkgchkComArgs="-v $dcp_pkgchkComArgs"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Checking packages from the BE <%s>.'`" "${dcp_beName}"
  if [ -n "${dcp_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/pkgchk ${dcp_pkgchkComArgs}"
    dcp_ret="0"
  else
    /usr/sbin/pkgchk ${dcp_pkgchkComArgs}
    dcp_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dcp_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dcp_beName}"
  fi

  case "${dcp_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> completed.'`" "${dcp_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> failed (with result code <%s>).'`" "${dcp_beName}" "${dcp_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_removePatches
# Description:	Remove patches from boot environment.
# Local Prefix:	dpr_
# Arguments:	$1 = boot environment name to remove patches from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for patchrm ("" if none).
#		$4 = command arguments to pass to patchrm on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
################################################################################

do_removePatches()
{
  dpr_beName="$1"
  dpr_noExecuteMode="$2"
  dpr_optArgs="$3"
  dpr_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Remove patches BE <%s> NoExecuteMode <%s> Patchrm Args <%s %s>.'`" "${dpr_beName}" "${dpr_noExecuteMode}" "${dpr_optArgs}" "${dpr_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dpr_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${dpr_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dpr_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dpr_beName}"
    return 2
  fi
  dpr_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dpr_beName}" "${dpr_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ################################ Remove the patches ##################################
  ######################################################################################

  # Setup command patchrm arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from patchrm are:
  # 0  - Successful execution.
  # >0 - Failure.

  ${LUPRINTF} -lp1 "`gettext 'Removing patches from the BE <%s>.'`" "${dpr_beName}"
  for pArgs in ${dpr_cmdArgs}
  do
    dpr_patchrmComArgs="${dpr_optArgs} -R ${dpr_bootMnt} ${pArgs}"
    if [ -n "${dpr_noExecuteMode}" ] ; then
      ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/patchrm ${dpr_patchrmComArgs}"
      dpr_ret="0"
    else
      /usr/sbin/patchrm ${dpr_patchrmComArgs}
      dpr_ret="$?"
    fi
  done

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dpr_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dpr_beName}"
  fi

  case "${dpr_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The patch remove from the BE <%s> completed.'`" "${dpr_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The patch remove from the BE <%s> failed.'`"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_upgradeOs
# Description:	Upgrade operating system on boot environment.
# Local Prefix:	dug_
# Arguments:	$1 = target boot environment name to upgrade operating system on.
#		$2 = upgrade profile template ("" to use default profile).
#		$3 = no execute mode ("" if not enabled).
#		$4 = media mount point to upgrade operating system from.
#		$5 = current boot environment name of operating system running.
#		$6 = dry run mode ("" if not enabled).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_upgradeOs()
{
  dug_beName="$1"
  dug_profilePath="$2"
  dug_noExecuteMode="$3"
  dug_media="$4"
  dug_pbeName="$5"
  dug_dryRunMode="$6"

  ${LUPRINTF} -lp2D - "`gettext 'Upgrade Operating System of BE <%s> from Media <%s> NoExecuteMode <%s> DryRunMode <%s>.'`" "${dug_beName}" "${dug_media}" "${dug_noExecuteMode}" "${dug_dryRunmode}"

  ######################################################################################
  ############### If x86, verify that the system has biosdev installed #################
  ######################################################################################

  if [ "$LU_SYSTEM_ARCH" = "i386" ]; then
     lulib_check_patch
     if [ "$?" -ne 0 ]; then
        return 2
     fi
  fi

  ######################################################################################
  ########## Verify that the media has a Solaris Operating System Image on it ##########
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dug_media}"

  lulib_validate_is_directory_not_empty "${dug_media}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The OS upgrade (-u) option requires that you specify the OS media location with the <-s> option.'`"
    return 3
  fi
  # find the media cd table of contents: if not found, can not upgrade from this media

  dug_media_cdtoc="${dug_media}/.cdtoc"
  if [ ! -f "${dug_media_cdtoc}" -o ! -s "${dug_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> is not a recognized installation media.'`" "${dug_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dug_errorsFound=""
  dug_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dug_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dug_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dug_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dug_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dug_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dug_media_proddir="${dug_media}/${dug_cdtoc_proddir}"
  dug_media_installConfig="${dug_media}/.install_config"
  dug_media_toolsDir="`dirname ${dug_media_proddir}`/Tools"
  dug_media_platformDir="${dug_media_toolsDir}/Boot/platform"
  dug_media_toolsInstallConfig="${dug_media_toolsDir}/Boot/usr/sbin/install.d/install_config"
  dug_media_basedir="`dirname ${dug_media}/${dug_cdtoc_proddir}`"
  dug_media_patchdir="${dug_media_basedir}/Patches"
  if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
      dug_media_bootLoaderDir="${dug_media_toolsDir}/Boot/boot/grub"
  else
      dug_media_bootLoaderDir=""
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Product Name <%s> Version <%s>.'`" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Base Directory <%s>.'`" "${dug_media_basedir}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Packages Directory <%s>.'`" "${dug_media_proddir}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Patches Directory <%s>.'`" "${dug_media_patchdir}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Configuration Directory <%s>'`" "${dug_media_installConfig}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Tools Directory <%s>.'`" "${dug_media_toolsDir}" 
  ${LUPRINTF} -lp2D - "`gettext 'Install Platform Support Directory <%s>.'`" "${dug_media_platformDir}" 
  ${LUPRINTF} -lp2D - "`gettext 'Install Tools Config Directory <%s>.'`" "${dug_media_toolsInstallConfig}"
  ${LUPRINTF} -lp2D - "`gettext 'Media BootLoader Directory <%s>.'`" "${dug_media_bootLoaderDir}"

  if [ -z "${dug_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product name.'`"
    dug_errorsFound="1"
  fi
  if [ -z "${dug_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product version.'`"
    dug_errorsFound="1"
  fi
  if [ -z "${dug_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dug_errorsFound="1"
  fi
  if [ ! -d "${dug_media_installConfig}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media product install configuration directory <%s> is missing.'`" "${dug_media_installConfig}"
    dug_errorsFound="1"
  fi
  if [ -n "${dug_cdtoc_proddir}" ] ; then
    if [ ! -d "${dug_media_proddir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product directory <%s> does not exist.'`" "${dug_media_proddir}"
      dug_errorsFound="1"
    fi
    if [ ! -d "${dug_media_toolsDir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product tools directory <%s> does not exist.'`" "${dug_media_toolsDir}"
      dug_errorsFound="1"
    fi
    if [ ! -d "${dug_media_toolsInstallConfig}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product tools installation directory <%s> does not exist.'`" "${dug_media_toolsInstallConfig}"
      dug_errorsFound="1"
    fi
    if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
        if [ ! -d "${dug_media_bootLoaderDir}" ]; then
            ${LUPRINTF} -Eelp2 "`gettext 'The media bootloader directory <%s> does not exist.'`" "${dug_media_bootLoaderDir}"
            dug_errorsFound="1"
	fi
    fi
  fi

  if [ -n "${dug_errorsFound}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain an operating system upgrade image.'`" "${dug_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media contains an operating system upgrade image.'`"

  ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> version <%s>.'`" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"

  if [ -d "${dug_media_patchdir}" ] ; then
    dug_media_patchCount=`/bin/ls -1 "${dug_media_patchdir}" 2>/dev/null | /bin/wc -l 2>/dev/null`
    if [ "${dug_media_patchCount}" -ne '0' ] ; then
      ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> patches for the product.'`" ${dug_media_patchCount}
    fi
  fi

  ######################################################################################
  ####################### Determine if version can be updated to #######################
  ######################################################################################

  lulib_is_upgrade_supported "${dug_cdtoc_prodvers}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -fEelp2 "`gettext 'This version of Live Upgrade is unable to \
upgrade to <%s> version <%s>. Only upgrades to <%s> version <%s> are supported \
by this version of Live Upgrade. To upgrade to <%s> version <%s>, remove Live \
Upgrade from the currently running system, and then install Live Upgrade from \
the <%s> version <%s> install media. Then use Live Upgrade to upgrade boot \
environment <%s>.'`" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}" \
"${dug_cdtoc_prodname}" "${LU_BUILT_FOR_SOLARIS_VERSION}" "${dug_cdtoc_prodname}" \
"${dug_cdtoc_prodvers}" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}" "${dug_beName}"
    return 1
  fi

  ######################################################################################
  ########################### Determine if platform is EOLed ###########################
  ######################################################################################

  # This verifies that the processor specific hardware architecture (such
  # sun, sun4c, sun4d, sun4m, sun4u, etc.) is directly supported
  # by this release of Live Upgrade.

  lulib_is_platform_supported "${dug_cdtoc_prodvers}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -fEelp2 "`gettext 'This system hardware architecture <%s> is not \
supported by <%s> version <%s>.'`" "${LU_HARDWARE_ARCH}" "${dug_cdtoc_prodname}" \
"${dug_cdtoc_prodvers}"
    return 1
  fi

  # Verify that the hardware platform implementation has support in the
  # new operating environment to upgrade to

  if [ -d "${dug_media_platformDir}" ] ; then
    if [ ! -d "${dug_media_platformDir}/${LU_HARDWARE_IMPLEMENTATION}" ] ; then
      ${LUPRINTF} -fEelp2 "`gettext 'This system hardware platform <%s> is not \
  supported by <%s> version <%s>.'`" "${LU_HARDWARE_IMPLEMENTATION}" \
  "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"
      return 1
    else
      ${LUPRINTF} -lp2D - "`gettext 'Platform <%s> is supported by <%s> version <%s>.'`" \
      "${LU_HARDWARE_IMPLEMENTATION}" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"
    fi
  fi

  ######################################################################################
  ####################### Construct the profile to use  ################################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Constructing upgrade profile to use.'`"

  ## Construct a pfinstall upgrade profile:
  ## - copy the default upgrade profile ${UPGRADE_PROFILE} to ${TMP_UPGRADE_PROFILE}
  ## - if the user specified a profile to use, append that to ${TMP_UPGRADE_PROFILE}
  ## At end, ${TMP_UPGRADE_PROFILE} will have the path to the template to use 
  ## for upgrading.

  # Make sure default upgrade profile exists
  if [ ! -f "${UPGRADE_PROFILE}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The default upgrade profile <%s> does not \
exist.'`" "${UPGRADE_PROFILE}"
    return 2
  fi

  # Create the upgrade profile to use starting with the default profile
  ERRMSG="`${LUBIN}/lucomm_del ${UPGRADE_PROFILE} > ${TMP_UPGRADE_PROFILE}`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Cannot create temporary profile <%s> from \
<%s>.'`" "${TMP_UPGRADE_PROFILE}" "${UPGRADE_PROFILE}"
    return 2
  fi

  # If user specified profile, append it to the end of the default profile
  if [ -n "${dug_profilePath}" ] ; then
    checkUserUpgradeProfile "${dug_profilePath}"
    if [ $? -ne 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The file <%s> can not be used as an \
upgrade profile.'`" "${dug_profilePath}"
      return 2
    fi

    ERRMSG="`${LUBIN}/lucomm_del ${dug_profilePath} | \
/bin/egrep -v '^[ 	]*install_type[ 	]*upgrade[ 	]*$' >> ${TMP_UPGRADE_PROFILE}`"
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot append upgrade profile <-j %s> to <%s>.'`" \
 "${dug_profilePath}" "${TMP_UPGRADE_PROFILE}"
      return 2
    fi
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Upgrade profile is <%s>.'`" \
"${TMP_UPGRADE_PROFILE}"

  ######################################################################################
  ####################### Determine which pfinstall root to use ########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Locating the operating system upgrade program.'`"

  dug_libDir="${dug_media_toolsDir}/Boot/usr/snadm/lib"
  dug_pfinstallDir="${dug_media_toolsDir}/Boot/usr/sbin/install.d"

  lulib_validate_is_directory "${dug_libDir}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The pfinstall library directory does not exist.'`"
    return 2
  fi

  lulib_validate_is_directory_not_empty "${dug_pfinstallDir}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product directory does not exist.'`"
    return 2
  fi

  dug_pfinstallExecutable="${dug_pfinstallDir}/pfinstall"
  if [ ! -x "${dug_pfinstallExecutable}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product <%s> does not exist or is not executable.'`" "${dug_pfinstallExecutable}"
    return 2
  fi

  # Create a library path for use when pfinstall is run
  dug_ldLibraryPath="${dug_libDir}"
  [ -n "${LD_LIBRARY_PATH}" ] && dug_ldLibaryPath="${dug_ldLibraryPath}:${LD_LIBRARY_PATH}"

  ${LUPRINTF} -lp2D - "`gettext 'Upgrade program to use is <%s>.'`" "${dug_pfinstallExecutable}"

  # Determine if this pfinstall supports the upgrade_mountpoint capability
  # The "-a" option to pfinstall (as of S10B27/S9U4) supports inquiring
  # pfinstall for its "capabilities". The new "upgrade_mountpoint" capability
  # allows mounting of file systems to be bypassed when doing an upgrade.
  # To check for this, run 'pfinstall -a sw:upgrade_mountpoint' - if it
  # does not return '3' or does not return 'upgrade_mountpoint=true' then
  # this new capability is NOT implemented

  dug_umcap="`LD_LIBRARY_PATH=${dug_ldLibraryPath} ${dug_pfinstallExecutable} -a sw:upgrade_mountpoint 2>/dev/null`"
  if [ "$?" -ne "3" -o "${dug_umcap}" != "upgrade_mountpoint=true" ] ; then
    ${LUPRINTF} -lp2D - "`gettext '<%s> does NOT implement sw:upgrade_mount capability.'`" \
"${dug_pfinstallExecutable}"
    dug_umcap=""
  else
    ${LUPRINTF} -lp2D - "`gettext '<%s> implements sw:upgrade_mount capability.'`" \
"${dug_pfinstallExecutable}"
    dug_umcap="yes"
  fi

  # Find the parse dynamic cluster toc script.
  dug_pdcExecutable="${dug_media_toolsDir}/Boot/usr/sbin/install.d/parse_dynamic_clustertoc"
  if [ ! -x "${dug_pdcExecutable}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The program <%s> does not exist or is not executable.'`" "${dug_pdcExecutable}"
    return 2
  fi

  ${LUPRINTF} -lp2D - "`gettext 'clustertoc parse program to use is <%s>.'`" "${dug_pdcExecutable}"

  # Find the parse packages to be added script. The location moved in s10;
  # search the new location first and if not found search the older location.
  # Search order:
  # 1--> /Boot/usr/lib/install/data/wizards/bin
  # 2--> /Boot/webstart/wizards/bin

  dug_pptbaExecutable="${dug_media_toolsDir}/Boot/usr/lib/install/data/wizards/bin/parsePackagesToBeAdded"
  if [ ! -x "${dug_pptbaExecutable}" ] ; then
    if [ -x ${dug_media_toolsDir}/Boot/webstart/wizards/bin/parsePackagesToBeAdded ] ; then
      dug_pptbaExecutable="${dug_media_toolsDir}/Boot/webstart/wizards/bin/parsePackagesToBeAdded"
    fi
  fi

  # Indicate decision made.
  if [ -x "${dug_pptbaExecutable}" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'parse packages to be added program to use is <%s>.'`" "${dug_pptbaExecutable}"
  else
    ${LUPRINTF} -Welp2 "`gettext 'The parse packages to be added program <%s> does not exist or is not executable.'`" "${dug_pptbaExecutable}"
    dug_pptbaExecutable=''
  fi

  ######################################################################################
  ############ Check for copylock and schedule delayed update if necessary #############
  ######################################################################################

  ## Check to see if a copy lock exists. If so then:
  ## 1- if an operation other than a scheduled copy exists, a BE is busy: do not allow any operation to be performed.
  ## 2- if an operation is scheduled on another BE besides our target, do not allow any operation to be performed.
  ## 3- only if a copy for our target BE is scheduled, then add to that an upgrade operation.

  ${LUPRINTF} -lp1 "`gettext 'Checking for existence of previously scheduled Live Upgrade requests.'`"

  lulib_validate_lulock
  if [ -f "${COPYLOCK}" -a -s "${COPYLOCK}" ]
  then
    . ${COPYLOCK}
    if [ "$CL_STATUS" != "SCHEDULED" ] ; then
      # If a scheduled copy exists, we can only schelude an
      # OS upgrade. Only an OS upgrade can be scheduled since
      # other upgrade may be interactive.
      ${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy Lock exists: Status <%s> Source BE <%s> Target BE <%s>.'`" "${CL_STATUS}" "${CL_SOURCE_BE}" "${CL_TARGET_BE}"
      ${LUPRINTF} -Eelp2 "`gettext 'A boot environment is busy with another operation.'`"
      return 2
    fi
    
    if [ "${dug_beName}" != "$CL_TARGET_BE" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy Lock exists: Status <%s> Source BE <%s> Target BE <%s>.'`" "${CL_STATUS}" "${CL_SOURCE_BE}" "${CL_TARGET_BE}"
      ${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy operation is schedule for another BE. An Upgrade operation for another BE can not be peformed or scheduled until this copy is complete.'`"
      return 2
    fi
    
    # A copy has been scheduled for this BE so the upgrade can now
    # be scheduled to occur after the copy.
    ${LUPRINTF} -lp1 "`gettext 'A Live Upgrade Copy operation is scheduled on this BE at <%s>\nThe upgrade operation will be scheduled to occur after the copy is completed.'`" "${CL_EXEC_TIME}"
    attime=`echo "$CL_EXEC_TIME" | /bin/awk ' { { hm = substr( $4, 1, 5) } { printf "%s %s %s\n", hm, $2, $3 } } '`
      make_at_command "${dug_beName}" "${dug_media}" | /bin/at -m "$attime + 16 minutes" \
       > /tmp/${AT_ERRLOG} 2>&1
    if [ "$?" != "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Attempt to schedule the upgrade at the specified time failed.'`"
      return 2
    fi
    /bin/grep INFO /tmp/${AT_ERRLOG} > /dev/null 2>&1
    if [ $? = 0 ]; then
      AT_JOB_TIME=`/bin/grep INFO /tmp/${AT_ERRLOG} | /bin/cut -d" " -f6-`
    else
      /bin/grep -i job /tmp/${AT_ERRLOG} > /dev/null 2>&1
      if [ $? = 0 ] ; then
	AT_JOB_TIME=`/bin/grep job /tmp/${AT_ERRLOG} | /bin/cut -d" " -f4-`
      else
	AT_JOB_TIME="CANNOT DETERMINE"
      fi
    fi
    AT_JOB_NUM=`/bin/awk '{ 
      for (i=0; i <= NF; i++)
	{
	  if ( $i == "Job" || $i == "job" )
	    { 
	      i++
	      print $i 
	      exit 0
            }
	}
      }' /tmp/${AT_ERRLOG}`
    if [ -f "${COPYLOCK}" ] ; then
      copylock_append "CL_UPGRADE_EXEC_TIME" "$AT_JOB_TIME"
      copylock_append "CL_UPGRADE_AT_JOB_NUM" "$AT_JOB_NUM"
    fi
    ${LUPRINTF} -lp1 "`gettext 'The upgrade has been scheduled to occur after: <%s>.'`" "${AT_JOB_TIME}"
    return 0
  fi

  ## No copy operation is (or has been) scheduled: do the upgrade; create copy lock and allow it to be deleted on exit.

  copylock_create "CL_STATUS" "UPDATING" "yes"
  dug_ret="$?"
  if [ "${dug_ret}" -eq "0" ] ; then
    copylock_append "CL_TARGET_BE" "${dug_beName}"
    dug_ret="$?"
  fi
  if [ "${dug_ret}" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create copy lock file: unable to upgrade the BE <%s>.'`" "${dug_beName}"
    return 2
  fi

  ######################################################################################
  ################## Create partition information for upgrade profile ##################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Creating upgrade profile for BE <%s>.'`" "${dug_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  $LUBIN/lumk_iconf "${dug_beName}" | sort -t: +1 -2 > ${ABE_ICF}
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dug_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Create new upgrade profile and add in the root slice of the target BE.
  dug_abeRootSlice=`/bin/awk -F":" ' { if ($2 == "/") {printf "%s\n", $3 } } ' < ${COMBINED_ICF} | /bin/sed 's/\/dev\/dsk\///g'`
  if [ -z "${dug_abeRootSlice}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine root slice for BE <%s>.'`" "${dug_beName}"
    return 2
  fi
  ${LUPRINTF} -lp2D - "`gettext 'Root device for upgrade is <%s>.'`" "${dug_abeRootSlice}"

  # If pfinstall implements the sw:upgrade_mountpoint capability, do NOT place
  # the root_device directive into the upgrade profile. This is because if the
  # pfinstall sw:upgrade_mountpoint is implemented, and -L is specified with
  # no root_device in the profile, pfinstall assumes that all file systems are
  # already mounted at the -L location

  if [ -z "${dug_umcap}" ] ; then
    ${LUPRINTF} +X -a "${TMP_UPGRADE_PROFILE}" "root_device %s" "${dug_abeRootSlice}"
    ${LUPRINTF} -lp2D - "`gettext '<root_device %s> added to upgrade profile <%s>.'`" \
"${dug_abeRootSlice}" "${TMP_UPGRADE_PROFILE}"
  else
    ${LUPRINTF} -lp2D - "`gettext 'root_device NOT ADDED to upgrade profile.'`"
  fi

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dug_beName}"
    return 2
  fi
  dug_bootMnt="${AIM_BEBOOTMNT}"

  # At this point we have mounted the ABE including boot partition (if any)
  ${LUPRINTF} -lp2D - "`gettext 'ABE slices mounted at <%s>.'`" "${dug_bootMnt}"
  ######################################################################################
  #################### Refuse upgrade if non-global zones installed ####################
  ######################################################################################
  
  # lustatus -X -r returns a message similar to:
  # <zoneStatus nonGlobalZonesExist="yes" source="xxx"/>
  # Extract first fields double-quoted value and see if it is "yes"

  ans=$( /usr/sbin/lustatus -X -r -R ${dug_bootMnt} 2>/dev/null | \
	/bin/grep '^<zoneStatus ' | \
	/bin/grep ' nonGlobalZonesExist="' | \
	/bin/cut -d'"' -f 2 )

  # if the answer is 'yes' then refuse to allow the upgrade.

  if [ "${ans}" = 'yes' ] ; then
    ${LUPRINTF} -fEelp2 "`gettext '\
Unable to upgrade boot environment <%s>.'`" "${dug_beName}"
    ${LUPRINTF} -fIelp2 "`gettext 'Boot environment <%s> has one or \
more non-global zones installed. This version of Live Upgrade cannot \
upgrade a boot environment that has any non-global zones installed. \
Please refer to <%s> for current information on upgrading such a boot \
environment.'`" "${dug_beName}" "http://sun.com/msg/SUNOS-8000-91"
    return 1
  fi

  # Save the GRUB menu (if any) on the ABE
  if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dug_dryRunMode}" ] ; then
     save_menu "${dug_bootMnt}" "${dug_beName}"
     if [ "$?" -ne 0 ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'Unable to save GRUB menu on BE <%s>.'`" "${dug_beName}"
        return 2
     fi
  fi

  # Check if ABE uses a boot partition before changing vfstab
  dug_bootPart=""
  if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
       ${LUPRINTF} -lp1 "`gettext 'Checking for x86 boot partition on ABE.'`"
      /bin/grep -s -v '^#' "${dug_bootMnt}/etc/vfstab" | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null 2>&1
      if [ "$?" -eq 0 ]; then
          dug_bootPart=`/bin/grep -s -v '^#' "${dug_bootMnt}/etc/vfstab" | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" | /usr/bin/awk '{print $1}'`
          ${LUPRINTF} -lp1 "`gettext 'x86 boot partition exists on ABE <%s>'`" "$dug_beName"
      fi
  fi

  # Backup the target ABE's vfstab file.

  backup_vfstab_file "${dug_bootMnt}" "${dug_beName}" "${ABE_ICF}"
  dug_ret="$?"
  if [ "${dug_ret}" -ne "0" ] ; then
    if [ "${dug_ret}" -eq "1" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to save backup copy of vfstab file for BE <%s>.'`" "${dug_beName}"
    fi
    return 2
  fi

  #--> At this point, the exit_script() code will automagically restore the       <--#
  #--> target boot environments vfstab file if it has not already been restored.  <--#
  #--> Because of this, there is no reason to include "restore_vfstab_file" calls <--#
  #--> before each error return from this function.                               <--#

  # Replace the target ABE's vfstab file with the one we created which only
  # has the "system" file systems on it. The "-I" option means do not include
  # any filesystems that are not mentioned in the ICF file.

  ${LUBIN}/luedvfstab -i "${COMBINED_ICF}" -m "${dug_bootMnt}" -n "${dug_beName}" -I

  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create revised vfstab file on BE.'`"
    return 2
  else
    ${LUPRINTF} -lp2D - "`gettext 'boot environment <%s> temporary vfstab file:\
\n**********************************\n%R\n**********************************'`" \
"${dug_beName}" < ${dug_bootMnt}/etc/vfstab
  fi
	#
        # Do processing only for x86 boot partition on intel platforms
	# Before pfinstall runs, copy the contents of the ABE boot
	# partition and write it onto the ABE's root filesystem at <mntpt>/boot.
	#
        if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
	   convert_x86_boot_partition "$dug_bootMnt" "$dug_bootPart"
	   if [ "$?" -ne 0 ]; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to convert X86 boot partition.'`"
	      return 1
	   fi
        fi

  ######################################################################################
  ######### Verify that the upgrade media mount point exists and is a directory ########
  ######################################################################################

  # Make sure the media root mount point exists and is a directory.
  if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
    # Mount point is not a directory.
    if [ -r ${MEDIAROOTMOUNTPOINT} ] ; then
      # its a readable file!!
      ${LUPRINTF} -Eelp2 "`gettext 'Media root mount point <%s> exists and is not a directory. Please remove or rename the file and try again.'`" "${MEDIAROOTMOUNTPOINT}"
      return 2
    fi
    # Attempt to create the media root mount point.
    /bin/mkdir ${MEDIAROOTMOUNTPOINT}
    if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
      # Could not create the mount point!
      ${LUPRINTF} -Eelp2 "`gettext 'ERROR: Media root mount point <%s> could not be created.'`" "${MEDIAROOTMOUNTPOINT}"
      return 2
    fi
  fi

  ######################################################################################
  ############################### --> DO THE UPGRAGE <-- ###############################
  ######################################################################################

  # N.B. pfinstall expects to mount all of the slices defined in the target o.s.'s vfstab file
  # when it exits these slices remain mounted. For this reason we first need to umount the
  # BE file systems we previously mounted so pfinstall's mounts will not fail. We need to
  # take this into account after pfinstall exits so that we can clean up properly.

  # Setup common pfinstall arguments:
  # -L path - root mount point where target boot environment will be mounted (must be /a)
  # -c path - location where the upgrade media can be located.
  # profile - the profile to use to drive the upgrade.
  # -x n - debugging level (1..9 is on).
  #
  # Return codes from pfinstall are:
  # EXIT_INSTALL_SUCCESS_REBOOT     0	(successful - system rebooted)
  # EXIT_INSTALL_SUCCESS_NOREBOOT   1	(successful - system not rebooted)
  # EXIT_INSTALL_FAILURE            2	(An error occurred)
  # ???                             3   (test capability return code)

  dug_pfComArgs="-L ${MEDIAROOTMOUNTPOINT} -c ${dug_media} ${TMP_UPGRADE_PROFILE}"
  if [ "$LU_DEBUG" -ne "0" ] ; then
    dug_pfComArgs="-x 10 ${dug_pfComArgs}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Using profile <%s>:\n**********\n%R\n**********\n'`" \
"${TMP_UPGRADE_PROFILE}" < "${TMP_UPGRADE_PROFILE}"

  ### --> THIS CODE IS EXECUTED FOR "NO EXECUTE MODE" ONLY.. <--- ###
  ### --> MUST MAKE SURE IT SYNCS UP WITH THE REAL CODE TOO. <--- ###

  if [ -n "${dug_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Performing the operating system upgrade of the BE <%s>.'`" "${dug_beName}"
    ${LUPRINTF} -lp1 "`gettext 'Execute Command: <%s>.'`" "${dug_pfinstallExecutable} ${dug_pfComArgs}"
    add_auto_os_patches "${dug_beName}" "${dug_bootMnt}" "${dug_media_toolsInstallConfig}" \
"${dug_media_patchdir}" "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" "${dug_noExecuteMode}" \
"${PATCH_LOGFILE}" "${dug_media}"
    return 0
  fi
  
  # If the pfinstall sw:upgrade_mountpoint capability is implemented, the
  # mounting of file systems by pfinstall has already been disabled because
  # the "root_slice" directive has not been placed into the pfinstall
  # upgrade profile. If the sw:upgrade_mountpoint capability is implemented,
  # there is no need to unmount the abe file systems before calling pfinstall

  if [ "${dug_umcap}" = "yes" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> remains mounted at <%s>.'`" \
"${dug_beName}" "${MEDIAROOTMOUNTPOINT}"
  else
    # pfinstall sw:upgrade_mountpoint capability IS NOT IMPLEMENTED.
    # Unmount so pfinstall can do mount.
    abe_umount
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dug_beName}"
      return 2
    fi
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> has been unmounted.'`" \
"${dug_beName}"
  fi

  # Determine the locale to pass in to parse_dynamic_clustertoc

  if [ -n "${LANG}" ] ; then
    PDC_LOCALE="${LANG}"
  elif [ -n "${LOCALE}" ] ; then
    PDC_LOCALE="${LOCALE}"
  else
    PDC_LOCALE="C"
  fi

  # take the existing local stripping off any trailing "_xxx" and ".xxx"
  # so zh_TW.BIG5 becomes "zh" and "ko.UTF-8" becomes "ko"

  PDC_LOCALE="`echo "${PDC_LOCALE}" | /bin/cut -f1 -d'_' | /bin/cut -f1 -d'.'`"

  ${LUPRINTF} -lp2D - "`gettext 'Locale lang <%s> locale <%s> passed to <%s> is <%s>'`" \
"${LANG}" "${LOCALE}" "${dug_pdcExecutable}" "${PDC_LOCALE}"

  # parse the clustertoc to form the final clustertoc that pfinstall will read
  ${LUPRINTF} -lp1 "`gettext 'Determining packages to install or upgrade for BE <%s>.'`" "${dug_beName}"
  ${dug_pdcExecutable} -c "${dug_media}" -l "${PDC_LOCALE}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to parse software table of contents.'`"
    return 2
  fi

  # Before running pfinstall, remove the patch database - this forces
  # the patch database to be recreated the next time any patch command
  # is executed. This is done because the upgrade process itself does
  # not attempt to update or remove the patch database, and it is 
  # rendered out of sync with the OS once the OS is upgraded.
  #  ? This is not right - we may have unmounted the ABE at this point
  if [ -f "${dug_bootMnt}/${PATCH_DATABASE_FILE}" -a -z "${dug_dryRunMode}" ] ; then
    /bin/rm -f "${dug_bootMnt}/${PATCH_DATABASE_FILE}" 2>/dev/null
  fi

  # Prepare to run pfinstall
  if [ -z "${dug_dryRunMode}" ] ; then
    # Not dry run mode: actually do the pfinstall
    ${LUPRINTF} -flp1 "`gettext 'Performing the operating system upgrade of the BE <%s>.'`" "${dug_beName}"
    ${LUPRINTF} -flp1 "`gettext 'CAUTION: Interrupting this process may leave the boot environment unstable or unbootable.'`"

    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Performing the operating system upgrade of the BE <%s>.'`" "`/bin/date`" "${dug_beName}"
  else
    # It IS dry run mode: add -D (simulate) option to pfinstall
    dug_pfComArgs="-D ${dug_pfComArgs}"
    ${LUPRINTF} -lp1 "`gettext 'Simulating the operating system upgrade of the BE <%s>.'`" "${dug_beName}"

    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Simulating the operating system upgrade of the BE <%s>.'`" "`/bin/date`" "${dug_beName}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Executing: <%s>.'`" "${dug_pfinstallExecutable} ${dug_pfComArgs} 2>&1 1>${PFINSTALL_LOGFILE}"
  ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Using: %s'`" "`/bin/date`" "${dug_pfinstallExecutable} ${dug_pfComArgs}"

  # First run pfinstall with the '-r' option and progress reporting enabled;
  # then check to see the results to determine whether or not this pfinstall
  # supports the -r option and progress reporting.

  /bin/rm -f "${PROGRESS_REPORT_FILE}" 2>/dev/null 1>&2
  LD_LIBRARY_PATH=${dug_ldLibraryPath} ${dug_pfinstallExecutable} -r "${PROGRESS_REPORT_FILE}" ${dug_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1 &
  dug_pfPid="$!"
  if [ -z "${_LU_OUTPUT_XML_}" ] ; then
    ${LUETCBIN}/ludo 'report_progress' "${dug_pfPid}" "${PROGRESS_REPORT_FILE}" \
      'text' "`gettext 'Upgrading Solaris: %s%% completed'`" \
      'solaris-upgrade' &
  else
    ${LUETCBIN}/ludo 'report_progress' "${dug_pfPid}" "${PROGRESS_REPORT_FILE}" \
      'xml' "${LU_PROG_NAME}" 'solaris-upgrade' &
  fi
  fg "${dug_pfPid}"
  dug_ret="$?"

  # If the return code is "0" and the progress report file was NOT found then
  # this pfinstall is one that does not support the '-r' option. Rerun without
  # the -r option and any progress reporting.
  if [[ "${dug_ret}" -eq "0" && ! -e "${PROGRESS_REPORT_FILE}" ]] ; then
    LD_LIBRARY_PATH=${dug_ldLibraryPath} ${dug_pfinstallExecutable} ${dug_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1
    dug_ret="$?"
  fi

  # Normalize the return code from pfinstall - unlike flash, for upgrade pfinstall
  # returns '0' or '1' on success - any other value is a failure:
  # 0 - success but need to reboot
  # 1 - success no need to reboot
  # otherwise... error
  # set stat_pfinstall to "0" if 0 or 1, otherwise set to real code
  stat_pfinstall="${dug_ret}"
  if [ "${dug_ret}" -eq "1" ] ; then
    stat_pfinstall="0"
  fi

  # if pfinstall returned any result > 1 then it failed - even though we continue
  # no patches will be added or any other work will be done - the reason we continue
  # is in the case where pfinstall may have mounted the file systems for the target
  # boot environment (probably on /a) in which case we need to do some special
  # work to restore the original vfstab file...

  if [ -n "${dug_dryRunMode}" ] ; then
    # This was just a simulation of what would have been done.
    if [ "${stat_pfinstall}" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The upgrade simulation failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
      ${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The upgrade simulation failed:'`" "`/bin/date`"
      maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
    else
      ${LUPRINTF} -lp1 "`gettext 'The operating system upgrade simulation is complete.'`"
      if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
	if [ "${LU_DEBUG}" -ne "0" ] ; then
	  ${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
	fi
	maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The upgrade simulation completed; pfinstall results:'`"
      fi
    fi
  else
    # This was NOT a simulation but a real installation - report it as such
    if [ "${stat_pfinstall}" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Installation of the packages from this media \
of the media failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
      ${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The upgrade failed:'`" "`/bin/date`"
      maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
    else
      ${LUPRINTF} -lp1 "`gettext 'Installation of the packages from this \
media is complete.'`"
      if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
	if [ "${LU_DEBUG}" -ne "0" ] ; then
	  ${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
	fi
	maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The upgrade completed; pfinstall results:'`"
      fi
    fi
  fi

  /bin/rm -f "${PFINSTALL_LOGFILE}"

  # ABE will now be mounted on ${MEDIAROOTMOUNTPOINT}.
  # Change the location where we believe the ABEs backup vfstab file is located.
  # Make believe we mounted the ABEs slices (pfinstall should have done this for us).

  dug_bootMnt=${MEDIAROOTMOUNTPOINT}
  change_vfstab_bootmnt "${dug_bootMnt}"

  # Make sure that the ABEs root slice is mounted on the expected mount point.
  abe_checkMounted "${ABE_ICF}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Problem remounting the BE <%s>.'`" "${dug_beName}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'ABE is mounted at <%s>.'`" "$dug_bootMnt"

  # Restore the GRUB menu (if any) on the ABE
  if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dug_dryRunMode}" ] ; then
     restore_menu "${dug_bootMnt}" "${dug_beName}"
     if [ "$?" -ne 0 ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore GRUB menu on BE <%s>.'`" "${dug_beName}"
        return 2
     fi
  fi
  ######################################################################################
  ############################ Update package instance data ############################
  ######################################################################################

  # Determine if package instance data needs to be refreshed:
  # If running a Solaris release that does not support zones, and upgrading to a
  # Solaris release that does support zones, upgrade package instance data on the abe. 

  if [ "${stat_pfinstall}" -eq "0" ] ; then
	sourceRelease=$(lulib_normalize_os_version "$(/bin/uname -r)")

	targetRelease=$(lulib_normalize_os_version 5.$(/bin/grep '^VERSION=' \
		${dug_bootMnt}/var/sadm/system/admin/INST_RELEASE | \
		/bin/sed 's/VERSION=//'))

	${LUPRINTF} -lp2D - "`gettext 'OS Releases: current <%s> upgraded <%s>.'`" \
		"${sourceRelease}" "${targetRelease}"

	# If upgrading to release that supports zones from one that does not,
	# make sure all package instance data is updated on the ABE.

	if [[ "${sourceRelease}" -le 51000 && "${targetRelease}" -ge 51000 ]] ; then
		if [ -n "${dug_dryRunMode}" ] ; then
			# dry run mode - just report what would have been done.

			${LUPRINTF} -lp1 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Simulating update of package information on boot environment <%s>.'`" "${dug_beName}"

		else
			# real installation - update package information

			${LUPRINTF} -lp1 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Updating package information on boot environment <%s>.'`" "${dug_beName}"

			${LUETCBIN}/ludo update_package_instance_data \
	"${dug_media}" "${dug_bootMnt}" 2>> "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}"

			if [ "$?" -ne "0" ] ; then

				${LUPRINTF} -Eelp2 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Unable to update package instance information on boot environment <%s>.'`" "${dug_beName}"

				stat_pfinstall=2
			else

				${LUPRINTF} -lp1 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Package information successfully updated on boot environment <%s>.'`" "${dug_beName}"

			fi
		fi
	fi
  fi

  ######################################################################################
  ############################## Apply patches if needed ###############################
  ######################################################################################

  # run parse packages to be added script.
  if [ "${stat_pfinstall}" -eq "0" -a -n "${dug_pptbaExecutable}" ] ; then
    ERRMSG=`${dug_pptbaExecutable} -R "${dug_bootMnt}" -c "${dug_media}"`
    if [ $? -ne 0 ] ; then
      stat_pfinstall=2
    fi
    if [ "${stat_pfinstall}" -ne "0" ] ; then
      [ -n "${ERRMSG}" ] && ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to parse packages to be added.'`"
    fi
  fi

  # Add in any operating system patches
  stat_addPatches=0
  if [ -z "${dug_dryRunMode}" ] ; then
    if [ "$stat_pfinstall" -eq "0" ] ; then
      [ -f "${PATCH_LOGFILE}" ] && /bin/rm -f "${PATCH_LOGFILE}"
      add_auto_os_patches "${dug_beName}" "${dug_bootMnt}" "${dug_media_toolsInstallConfig}" "${dug_media_patchdir}" "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" "${dug_noExecuteMode}" "${PATCH_LOGFILE}" "${dug_media}"
      stat_addPatches="$?"
      if [ "${stat_addPatches}" -ne "0" ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'The operating system patch installation failed; patch installation returned these diagnostics:\n%R'`" < ${PATCH_LOGFILE}
	${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The operating system patch installation failed:'`" "`/bin/date`"
	maillog_addFile "${PATCH_LOGFILE}" "`gettext 'patch installation diagnostics output'`"
      else
	${LUPRINTF} -lp1 "`gettext 'The operating system patch installation is complete.'`"
	if [ -f "${PATCH_LOGFILE}" -a -s "${PATCH_LOGFILE}" ] ; then
	  if [ "${LU_DEBUG}" -ne "0" ] ; then
	    ${LUPRINTF} -lp2D - "`gettext 'patch installation returned these results:\n%R'`" < ${PATCH_LOGFILE}
	  fi
	  maillog_addFile "${PATCH_LOGFILE}" "`gettext 'The operating system patch installation completed; patch installation results:'`"
	fi
      fi
    fi
  fi

  [ -f "${PATCH_LOGFILE}" ] && /bin/rm -f "${PATCH_LOGFILE}"

  if [ -z "${dug_dryRunMode}" ] ; then
    #
    # Before the run of pfinstall, we umounted boot partition
    # and copied its contents into /boot on the root filesystem
    # We now go ahead and remove the backing file (.dd_x86_boot_copy)
    # Newboot enabled OS doesn't use boot partitions
    #
    delete_x86_boot_backing "$dug_bootMnt"
    if [ "$?" -ne 0 ] ; then
      stat_pfinstall="2"
    fi

    #
    # Customize the failsafe console setting based on PBE settings.
    #
    configure_failsafe "$LU_MINIROOT_MNTPT" "$dug_beName" 
    if [ "$?" -ne 0 ] ; then
      stat_pfinstall="2"
    fi
  fi

  # All upgrades and patch adds are completed - restore the target
  # boot environments vfstab file.

  restore_vfstab_file
  dug_bootMnt=${VFST_BOOT_MNT}
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2a "${MAIL_LOGFILE}" "`gettext 'Failed to restore vfstab file on the BE <%s>.'`" "${dug_beName}"
  fi

  if [ -z "${dug_dryRunmode}" ] ; then

    #
    # Now that vfstab file has been restored, set bootpath based on vfstab
    # and modify boot partition entry in it.
    #
    update_x86boot "$dug_bootMnt" "$dug_beName"
    if [ "$?" -ne 0 ] ; then
      stat_pfinstall="2"
    fi
    modify_x86_boot_entry "$dug_bootMnt"
    if [ "$?" -ne 0 ] ; then
      stat_pfinstall="2"
    fi

    ###
    ### Review all log files and output appropriate messages.
    ###

    dug_reviewFiles=""
    dug_partialInstall=""

    # If the upgrade log exists, add the contents of the upgrade log file to 
    # the mail log file. Also, let the user know where the upgrade log is.

    if [ -f "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" -a -s "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" ] ; then
      maillog_addFile "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Target BE upgrade log file results:'`"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of the upgrade operation.'`" "${PFINSTALL_UPGRADE_LOG}" "${dug_beName}"

      dug_reviewFiles="yes"
    fi

    # If the upgrade cleanup exists add the contents of the upgrade cleanup 
    # file to the mail log file. Also, let the user know where the upgrade 
    # cleanup is.

    if [ -f "${dug_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" -a -s "${dug_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" ] ; then

      maillog_addFile "${dug_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" \
"`gettext 'Target BE upgrade cleanup file results:'`"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of cleanup operations required.'`" \
"${PFINSTALL_UPGRADE_CLEANUP}" "${dug_beName}"

      dug_reviewFiles="yes"
    fi

    # If the failed package log exists add the contents of the failed package 
    # log file to the mail log file. Also, let the user know where the failed
    # package log is.

    if [ -f "${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" -a -s "${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" ] ; then
      maillog_addFile "${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" \
"`gettext 'Target BE packages that failed to upgrade log file results:'`"

      ${LUPRINTF} -Welp2 "`gettext '<%d> packages failed to install properly \
on boot environment <%s>.'`" "`/bin/cat ${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS} | \
/bin/wc -l`" "${dug_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that failed to upgrade or install properly.'`" \
"${PFINSTALL_UPGRADE_FAILED_PKGADDS}" "${dug_beName}"

      dug_reviewFiles="yes"
      dug_partialInstall="yes"
    fi

    if [ -f "${dug_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" -a -s "${dug_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" ] ; then

      ${LUPRINTF} -Welp2 "`gettext '<%d> additional packages must be installed \
on boot environment <%s>.'`" "`/bin/grep -c '^PKG=' \
${dug_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}`" "${dug_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that must be installed on the boot environment \
for the upgrade to be complete. The packages in this list were not present \
on the media that was used to upgrade this boot environment.'`" \
"${PFINSTALL_PACKAGES_TO_BE_ADDED}" "${dug_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'If the boot environment was upgraded using \
one media of a multiple media distribution, for example the Solaris CD media, \
you must continue the upgrade process with the next media. Complete the \
upgrade by using the luupgrade <-i> option to install the next media of the \
distribution. Failure to complete the upgrade process with all media of the \
software distribution makes the boot environment unstable.'`"
      dug_reviewFiles="yes"
      dug_partialInstall="yes"
    fi

    # If files were listed, request that user review the file contents.
    if [ -n "${dug_reviewFiles}" ] ; then
      ${LUPRINTF} -fIlp1 "`gettext 'Review the files listed above. Remember \
that all of the files are located on boot environment <%s>. Before you \
activate boot environment <%s>, determine if any additional system maintenance \
is required or if additional media of the software distribution must be \
installed.'`" "${dug_beName}" "${dug_beName}"
    fi

  fi

  # Unmount the target boot environment

  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the boot environment <%s>.'`" "${dug_beName}"
  fi
  
  if [ $stat_pfinstall -ne 0 ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade of the boot environment <%s> failed.'`" "${dug_beName}"
    maillog_setSubject "`gettext 'Solaris upgrade FAILED.'`"
    return 1
  elif [ $stat_addPatches != 0 ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade completed but the automatic \
patch installation to the boot environment <%s> failed.'`" "${dug_beName}"
    maillog_setSubject "`gettext 'Solaris upgrade FAILED (Solaris upgrade \
successful but patch installation FAILED).'`"
    return 1
  elif [ -n "${dug_partialInstall}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade of the boot environment <%s> is partially complete.'`" "${dug_beName}"
    maillog_setSubject "`gettext 'Solaris upgrade is partially complete.'`"
    return 0
  fi
  ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade of the boot environment <%s> is complete.'`" "${dug_beName}"
  maillog_setSubject "`gettext 'Solaris upgrade is complete.'`"
  return 0
}

#
# The lax argument does less strict checking. This is for
# do_checkMedia() which may or may not be run on media with miniroot
#
mount_miniroot()
{
   mmr_media="$1"
   mmr_lax="$2"

   #
   # NOP on all platforms other than x86
   #
   if [ "${LU_SYSTEM_ARCH}" != i386 ]; then
      return
   fi

   if [ -z "$mmr_media" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'No media path provided.'`"
      exit_script 2
   fi

   if [ ! -d "$mmr_media" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media directory does not exist <%s>.'`" "$mmr_media"
      exit_script 2
   fi

   # Find cdtoc
   mmr_media_cdtoc="${mmr_media}/.cdtoc"
   if [ ! -f "$mmr_media_cdtoc" -o ! -s "$mmr_media_cdtoc" ]; then
      if [ -n "$mmr_lax" ]; then
         return
      fi
      ${LUPRINTF} -Eelp2 "`gettext 'The media is not recognized installation media <%s>.'`" "$mmr_media"
      exit_script 2
   fi


   LU_MINIROOT_PATH="${mmr_media}/${LU_MINIROOT_DIR}"

   if [ ! -d "$LU_MINIROOT_PATH" ]; then
      if [ -n "$mmr_lax" ]; then
         return
      fi
      ${LUPRINTF} -Eelp2 "`gettext 'The media miniroot directory does not exist <%s>.'`" "$LU_MINIROOT_PATH"
      exit_script 2
   fi

   #
   # The GRUB boot project introduced the above directory. If it is present, there should be no lax checking
   # beyond this point.
   #

   # Locate compressed miniroot
   if [ ! -f "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}" -o ! -s "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media miniroot archive does not exist <%s>.'`" "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}"
      exit_script 2
   fi
   if [ ! -f "${mmr_media}/${FAILSAFE_MULTI_BOOT}" -o ! -s "${mmr_media}/${FAILSAFE_MULTI_BOOT}" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media multiboot does not exist <%s>.'`" "${mmr_media}/${FAILSAFE_MULTI_BOOT}"
      exit_script 2
   fi

   #
   # Save failsafe multiboot. This will be installed in the ABE later when we unmount the miniroot
   #
   ${LUPRINTF} -lp1 "`gettext 'Copying failsafe multiboot from media.'`"
   TMP_FAILSAFE_MULTIBOOT="/tmp/multiboot.$$"
   /bin/cp -p "${mmr_media}/${FAILSAFE_MULTI_BOOT}" "${TMP_FAILSAFE_MULTIBOOT}" 
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Save of failsafe multiboot to <%s> failed.'`" "${TMP_FAILSAFE_MULTIBOOT}"
      exit_script 2
   fi

   ${LUPRINTF} -lp1 "`gettext 'Uncompressing miniroot'`"
   TMP_FAILSAFE_ARCHIVE="/tmp/${LU_MINIROOT_ARCHIVE}.$$"
   /usr/bin/gzcat "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}" > "${TMP_FAILSAFE_ARCHIVE}"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot decompress media miniroot archive <%s>.'`" "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}"
      exit_script 2
   fi

   ${LUPRINTF} -lp1 "`gettext 'Creating miniroot device'`"
   LU_MINIROOT_DEVICE=`/usr/sbin/lofiadm -a ${TMP_FAILSAFE_ARCHIVE}`
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot create miniroot device.'`"
      LU_MINIROOT_DEVICE=""
      exit_script 2
   fi

   #
   # The archive can (currently) be ufs or isofs. Determine the filesystem type
   #
   LU_MINIROOT_FSTYPE=`lulib_fstyp ${LU_MINIROOT_DEVICE}`
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot determine miniroot archive filesystem type <%s>.'`" "${LU_MINIROOT_DEVICE}"
      exit_script 2
   fi
   ${LUPRINTF} -lp1 "`gettext 'miniroot filesystem is <%s>'`" "${LU_MINIROOT_FSTYPE}"


   # Find miniroot mount point i.e. Solaris_?/Tools/Boot
   mmr_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${mmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
   mmr_media_proddir="${mmr_media}/${mmr_cdtoc_proddir}"
   LU_MINIROOT_MNTPT="`dirname ${mmr_media_proddir}`/Tools/Boot"

   if [ ! -d "$LU_MINIROOT_MNTPT" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media miniroot mountpoint does not exist <%s>.'`" "$LU_MINIROOT_MNTPT"
      LU_MINIROOT_MNTPT=""
      exit_script 2
   fi

   ${LUPRINTF} -lp1 "`gettext 'Mounting miniroot at <%s>'`" "${LU_MINIROOT_MNTPT}"

   /usr/sbin/mount -F "${LU_MINIROOT_FSTYPE}" "${LU_MINIROOT_DEVICE}" "${LU_MINIROOT_MNTPT}" 
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot mount miniroot at <%s>.'`" "${LU_MINIROOT_MNTPT}"
      LU_MINIROOT_MNTPT=""
      exit_script 2
   fi
}

#
# Note: this is called from exit_script() which in turn can
# be invoked from various points in this script. Hence the checks
#
umount_miniroot()
{
  if [ -n "${LU_MINIROOT_MNTPT}" ]; then
     /usr/sbin/umount "${LU_MINIROOT_MNTPT}" > /dev/null 2>&1
     if [ "$?" -ne 0 ]; then
        ${LUPRINTF} -Eelp2 "`gettext 'Cannot unmount miniroot at <%s>.'`" "${LU_MINIROOT_MNTPT}"
     fi
     LU_MINIROOT_MNTPT=""
  fi

  if [ -n "${LU_MINIROOT_DEVICE}" ]; then
     /usr/sbin/lofiadm -d "${LU_MINIROOT_DEVICE}"  >/dev/null 2>&1
     LU_MINIROOT_DEVICE=""
  fi

  if [ -n "$INSTALL_FAILSAFE_ON" ]; then
     # Install the configured failsafe archive and multiboot in the ABE.
     install_failsafe "$INSTALL_FAILSAFE_ON"
  fi

  /bin/rm -f "${TMP_FAILSAFE_ARCHIVE}"  >/dev/null 2>&1 
  /bin/rm -f "${TMP_FAILSAFE_ARCHIVE}.gz"  >/dev/null 2>&1 
  /bin/rm -f "${TMP_FAILSAFE_MULTIBOOT}" >/dev/null 2>&1 
}

#
# Save the GRUB menu (if any) that exists on the ABE
# This function assumes that the ABE is mounted.
#
# Arguments:
#	$1 - The mountpoint of the ABE
#	$2 - The name of the ABE
# Returns:
#	0 on success
#	1 on failure
#
save_menu()
{
    /bin/rm -f "$TMP_MENU_LST"

    if [ "$LU_SYSTEM_ARCH" != i386 ]; then
       ${LUPRINTF} -Eelp2 "`gettext 'save_menu(): Cannot be invoked on a <%s> system.'`" "${LU_SYSTEM_ARCH}"
       return 1
    fi

    if [ "$#" -ne 2 -o -z "$1" -o -z "$2" ]; then
       ${LUPRINTF} -Eelp2 "`gettext 'save_menu(): Invalid arguments.'`"
       return 1
    fi

    ABEmntpt="$1"
    ABEname="$2"

    #
    # Check if the ABE has a boot partition. If yes,
    # unmount it to get access to /boot on the ABE
    # root filesystem
    #
    dev=`/sbin/mount | /bin/nawk -v mntpt="${ABEmntpt}/boot" ' { if ($1 == mntpt) {printf("%s\n", $3); exit 8;}}'`
    if [ "$?" -eq 8 -a -n "$dev" ]; then
       /sbin/umount "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'save_menu(): Cannot unmount x86 boot partition <%s>.'`" "$dev"
	  return 1
       fi
    else
       dev=""
    fi

    ${LUPRINTF} -lp1 "`gettext 'Checking for GRUB menu on ABE <%s>.'`" "$ABEname"
    if [ -f "${ABEmntpt}/${BOOT_MENU}" -a -s "${ABEmntpt}/${BOOT_MENU}" ]; then
        ${LUPRINTF} -lp1 "`gettext 'Saving GRUB menu on ABE <%s>.'`" "$ABEname"
       /bin/cp -p "${ABEmntpt}/${BOOT_MENU}" "${TMP_MENU_LST}"
    fi

    #
    # If we unmounted the ABE boot partition above, mount it now
    #
    if [ -n "$dev" ]; then
       /sbin/mount -F pcfs "$dev" "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'save_menu(): Cannot remount x86 boot partition <%s>.'`" "$dev"
	  /bin/rm -f "${TMP_MENU_LST}"
	  return 1
       fi
    fi

    return 0
}

#
# Restore the GRUB menu (if any) that existed on the ABE prior to upgrade.
# This function assumes that the ABE is mounted.
# A (good) side effect of this function is that it deletes any blank menu
# that may have been created by upgrade.
# Note that we cannot assume the boot partition has been deleted at this point.
#
# Arguments:
#	$1 - The mountpoint of the ABE
#	$2 - The name of the ABE
# Returns:
#	0 on success
#	1 on failure
#
restore_menu()
{
    if [ "$LU_SYSTEM_ARCH" != i386 ]; then
       ${LUPRINTF} -Eelp2 "`gettext 'restore_menu(): Cannot be invoked on a <%s> system.'`" "${LU_SYSTEM_ARCH}"
       return 1
    fi

    if [ "$#" -ne 2 -o -z "$1" -o -z "$2" ]; then
       ${LUPRINTF} -Eelp2 "`gettext 'restore_menu(): Invalid arguments.'`"
       return 1
    fi

    ABEmntpt="$1"
    ABEname="$2"

    #
    # Check if the ABE has a boot partition. If yes,
    # unmount it to get access to /boot on the ABE
    # root filesystem
    #
    dev=`/sbin/mount | /bin/nawk -v mntpt="${ABEmntpt}/boot" ' { if ($1 == mntpt) {printf("%s\n", $3); exit 9;}}'`
    if [ "$?" -eq 9 -a -n "$dev" ]; then
       /sbin/umount "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'restore_menu(): Cannot unmount x86 boot partition <%s>.'`" "$dev"
	  return 1
       fi
    else
       dev=""
    fi

    #
    # If a GRUB menu previously existed on the ABE restore it. If not, delete any menu
    # found as this would be a blank menu generated by upgrade
    #
    if [ -f "${TMP_MENU_LST}" -a -s "${TMP_MENU_LST}" ]; then
       ${LUPRINTF} -lp1 "`gettext 'Restoring GRUB menu on ABE <%s>.'`" "$ABEname"
       # The directory may not have been created yet.
       /bin/mkdir -p "${ABEmntpt}/${BOOT_MENU_DIR}"
       /bin/cp -p "${TMP_MENU_LST}" "${ABEmntpt}/${BOOT_MENU}"
    elif [ -f "${ABEmntpt}/${BOOT_MENU}" ]; then
       /bin/rm "${ABEmntpt}/${BOOT_MENU}"
       ${LUPRINTF} -lp1 "`gettext 'Deleted empty GRUB menu on ABE <%s>.'`" "$ABEname"
    fi

    /bin/rm -f "${TMP_MENU_LST}"

    #
    # If we unmounted the ABE boot partition above, mount it now
    #
    if [ -n "$dev" ]; then
       /sbin/mount -F pcfs "$dev" "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'restore_menu(): Cannot remount x86 boot partition <%s>.'`" "$dev"
	  return 1
       fi
    fi

    return 0
}

################################################################################
# Name:		<main>
# Description:	Main code (outside of any function definitions) - executed at script startup.
# Local Prefix:	<none>
# Arguments:	$0...$n = All arguments specified by user on command line that invoked this script.
#
# The main code is supposed to do minimal processing sufficient to parse and validate as much
# of the command line arguments and environment as possible for options and arguments that
# are common to all operations, and then to pass control to a specific "do_" function that 
# performs the specific operation requested.
################################################################################

# Make sure that all temporary files are initially deleted.

/bin/rm -f ${ALL_TEMP_FILES} 1>/dev/null 2>&1

# signal handling for cleanup.
# 1- SIGHUP (hangup)
# 2- SIGINT (user interrupt)
# 3- SIGQUIT (user quit)
# 9- SIGKILL (kill process - can not be caught or ignored :)
# 15- SIGTERM (software termination request)

trap "interruptHandler" 1 2 3 9 15

# Dot the defaults file.

if [ ! -s /etc/default/lu ] ; then
  echo "${LU_PROG_NAME}: ""`gettext 'ERROR: Live Upgrade not installed properly (/etc/default/lu not found).'`"
  exit_script 1
fi
. /etc/default/lu

# Default global variables we expect to be set from /etc/default/lu.

LUBIN=${LUBIN:=/usr/lib/lu}

# Dot the Live Upgrade library functions.

if [ ! -s $LUBIN/lulib ] ; then
  echo "${LU_PROG_NAME}: ""`gettext 'ERROR: The Live Upgrade product is not installed properly (${LUBIN}/lulib not found).'`"
  exit_script 5
fi

. $LUBIN/lulib

# Check for existence and non-zero size of lutab file.

if [ ! -f ${LU_LUTAB_FILE} -o ! -s ${LU_LUTAB_FILE} ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'No boot environments are configured on this system.'`"
  exit_script 2
fi

  ######################################################################################
  ##################### Command line option and argument processing ####################
  ######################################################################################

# Reset all command line parse flags to default values.
# These flags are MAJOR MODES, only one of which can be specified:
flag_c="" # -c - check media.			[** MAJOR MODE **]
flag_C="" # -C - check package.			[** MAJOR MODE **]
flag_f="" # -f - flash install.			[** MAJOR MODE **]
flag_i="" # -i - installer.			[** MAJOR MODE **]
flag_I="" # -I - information on package.	[** MAJOR MODE **]
flag_p="" # -p - add packages.			[** MAJOR MODE **]
flag_P="" # -r - remove packages.		[** MAJOR MODE **]
flag_t="" # -t - add patches.			[** MAJOR MODE **]
flag_T="" # -T - remove patches.		[** MAJOR MODE **]
flag_u="" # -u - update os.			[** MAJOR MODE **]

# These flags are PARAMETERS, which are dependent upon the major mode:
flag_a="" # -a - flash_archive for -f flash major mode / pkg_admin_file for -p package add major mode.
flag_d="" # -d - same as '-s' flag for -p package add major mode only.
flag_D="" # -D - dry run mode.
flag_F="" # -F - flash verify.
flag_J="" # -J "p" - jumpstart profile.
flag_j="" # -j p - jumpstart profile path.
flag_l="" # -l f - log file path.
flag_N="" # -N - no execute mode.
flag_n="" # -n "n" - be name.
flag_o="" # -o f - output file path.
flag_O="" # -O "o" - options passed to underlying installation tool(s).
flag_s="" # -s p - source path.
flag_x="" # -x n - set debug level (PRIVATE).

# Validate the command line arguments.

while [ $# -ne 0 ] ; do
  while getopts a:cCDd:fFiIJ:j:l:Nn:O:o:PpTts:ux:X c ; do

    case $c in
      a) # -a - flash_archive for -f flash major mode / pkg_admin_file for -p package add major mode.
	 flag_a="${flag_a} ${OPTARG}"
	 ;;
      c) # -c - check media .
	 flag_c="1"
	 ;;
      C) # -C - check package.
	 flag_C="1"
	 ;;
      d) # -d - same as '-s' flag for -p package add major mode only.
	 lulib_cannot_duplicate_option "${flag_d}" "${OPTARG}" "-d"
	 flag_d="${OPTARG}"
	 ;;
      D) # -D - dry run mode.
	 flag_D="1"
	 ;;
      f) # -f - flash install
	 flag_f="1"
	 ;;
      F) # -F - flash verify
	 flag_F="1"
	 ;;
      i) # -i - installer.
	 flag_i="1"
	 ;;
      I) # -I - information on package.
	 flag_I="1"
	 ;;
      J) # -J "p" - jumpstart profile.
	 lulib_cannot_duplicate_option "${flag_J}" "${OPTARG}" "-J"
	 flag_J="${OPTARG}"
	 ;;
      j) # -j p - jumpstart profile path.
	 lulib_cannot_duplicate_option "${flag_j}" "${OPTARG}" "-j"
	 flag_j="${OPTARG}"
	 ;;
      l) # -l f - error log file path.
	 # This overrides the LU_ERROR_LOG_FILE setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_l}" "${OPTARG}" "-l"
	 ${LUPRINTF} -lp2D - "`gettext 'Verifying that the error log file <%s> specified can be created and appended to.'`" "${OPTARG}"
	 ERRMSG="`${LUPRINTF} -c \"${OPTARG}\" 2>&1`"
	 if [ $? -ne 0 ] ; then
	   ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -l option may not be created or appended to.'`" "${OPTARG}"
	   exit_script 3
	 fi
	 flag_l="${OPTARG}"
	 lulib_set_error_log_file "${flag_l}"
	 ;;
      N) # -N - no execute mode.
	 flag_N="1"
	 ;;
      n) # -n "n" - be name.
	 lulib_cannot_duplicate_option "${flag_n}" "${OPTARG}" "-n"
	 flag_n="${OPTARG}"
	 ;;
      O) # -O "o" - options passed to underlying installation tool(s).
	 if [ -z "${flag_O}" ] ; then
	   flag_O="${OPTARG}"
	 else
	   flag_O="${flag_O} ${OPTARG}"
	 fi
	 ;;
      o) # -o f - output file path.
	 # This overrides the LU_SESSION_LOG_FILE setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_o}" "${OPTARG}" "-o"
	 ${LUPRINTF} -lp2D -  "`gettext 'Verifying that the session log file <%s> can be created and appended to.'`" "${OPTARG}"
	 ERRMSG="`${LUPRINTF} -c \"${OPTARG}\" 2>&1`"
	 if [ $? -ne 0 ] ; then
	   ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -o option may not be created or appended to.'`" "${OPTARG}"
	   exit_script 3
	 fi
	 flag_o="${OPTARG}"
	 lulib_set_session_log_file "${flag_o}"
	 ;;
      p) # -p - add packages.
	 flag_p="1"
	 ;;
      P) # -P - remove packages.
	 flag_P="1"
	 ;;
      s) # -s p - source path.
	 lulib_cannot_duplicate_option "${flag_s}" "${OPTARG}" "-s"
	 flag_s="${OPTARG}"
	 LU_MEDIA_PATH="$flag_s"; export LU_MEDIA_PATH
	 ;;
      T) # -T - remove patches.
	 flag_T="1"
	 ;;
      t) # -t - add patches.
	 flag_t="1"
	 ;;
      u) # -u - update os.
	 flag_u="1"
	 ;;
      X) # -X - set XML output mode.
	 lulib_set_output_format 'xml'
	 ;;
      x) # -x n - set debug level to n (PRIVATE).
	 # This overrides the default setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_x}" "${OPTARG}" "-x"
	 /bin/test "${OPTARG}" -ge 0 2>/dev/null
	 if [ $? -gt 1 ] ; then
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -x option is not a number.'`" "${OPTARG}"
	   usage 3
	 fi
	 flag_x="${OPTARG}"
	 lulib_set_debug "${flag_x}"
	 ;;
      *) # unknown - option.
	  usage 3
    esac
  done

  # Found either end of arguments, +option, or non-option argument; shift out
  # what has been processed so far; if a non-option argument is present
  # capture it and continue processing the command line arguments.
  shift `/bin/expr $OPTIND - 1`
  OPTIND=1
  if [ $# -ne 0 -a "$1" = '+X' ] ; then
      # +X - set TEXT output mode.
      lulib_set_output_format 'text'
      shift
  else
    break
  fi
done

# Fixup debug, session log, and error log settings
lulib_fixup_startup_settings

  ######################################################################################
  ############ Validate all command line arguments and options as possible #############
  ######################################################################################

# Set command line arguments found (if any).
cmdNames="$*"

# Verify that at least one operation option was specified..
if [ -z "${flag_c}${flag_C}${flag_f}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}" ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'At least one option from <-c, -C, -f, -i, -I, -p, -P, -t, -T, -u> must be specified.'`"
  usage 3
fi

# Verify that only one operation option was specified.
if [ "${flag_c}${flag_C}${flag_f}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}" != "1" ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'Only one option from <-c, -C, -f, -i, -I, -p, -P, -t, -T, -u> may be specified.'`"
  usage 3
fi

# Determine the name of current BE (PBE).
CURR_BE="`lulib_lucurr`"
if [ $? != 0 ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine the name of the current active BE.'`"
  exit_script 2
fi

# If an operation is requested that requires a target boot environment
# name, validate it here.
if [ -n "${flag_C}${flag_f}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}" ] ; then

  # A valid BE name must be provided.
  if [ -z "${flag_n}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The required target BE name was not specified with the -n option.'`"
    usage 3
  fi
  BE_NAME="${flag_n}"
fi
  
# If an operation is requested that requires a target boot environment
# itself be valid ("complete"), validate it here.

if [ -n "${flag_C}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}${flag_f}" ] ; then

  lulib_validate_be "${BE_NAME}" "${CURR_BE}" "${flag_f}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to use the boot environment <%s>.'`" "${BE_NAME}"
    exit_script 2
  fi

  # The BE must not currently be mounted.
  lulib_verify_be_unmounted "${BE_NAME}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to use the boot environment <%s>.'`" "${BE_NAME}"
    exit_script 2
  fi
fi

# If an operation is requested that can not be done when a BE is busy, check for it now.
if [ -n "${flag_f}${flag_p}${flag_P}${flag_t}${flag_T}${flag_i}" ] ; then
  lulib_check_any_be_busy
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'A BE is busy with another operation.'`"
    exit_script 2
  fi
fi

# If dry run mode, disable mailing of any log files
if [ -n "${flag_N}" ] ; then
  MAIL_DISABLE="yes"
fi

#
# Delete menu entries if BE content changes
#
if [ "$LU_SYSTEM_ARCH" = i386 -a -z "${flag_N}" ]; then
   if [ -z "$flag_c" -a -z "$flag_C" -a -z "$flag_I" ]; then
      lulib_delete_menu_entry "${BE_NAME}" 
      if [ $? -ne 0 ] ; then
         ${LUPRINTF} -Eelp2 "`gettext 'Cannot delete GRUB menu entry for boot environment <%s>.'`" "${BE_NAME}"
         exit_script 2
      fi
   fi
fi

  ######################################################################################
  ############## Call specific function to handle the operation requested ##############
  ######################################################################################

#
# The [-l error_log] and [-o outfile] and [-n "BE_name"] options have already been processed.
#

commandStatus="0"

if [ -n "${flag_c}" ] ; then
  ###
  ### Check Media:     luupgrade -c -F -s media_path [-l error_log] [-o outfile]
  ###
  lulib_cannot_have_options "${flag_d}${flag_D}${flag_n}${flag_j}${flag_J}${flag_N}${flag_O}" "-c" "-d, -D, -n, -j, -J, -N, -O"
  lulib_must_have_option "${flag_s}" "-c" "-s"
  lulib_cannot_have_argument "${cmdNames}" "-c"
  if [ -n "${flag_F}" ] ; then
    mount_miniroot "$flag_s" ""
    do_checkMiniroot "${flag_s}"
    commandStatus="$?"
  else
    mount_miniroot "$flag_s" "lax"
    do_checkMedia "${flag_s}"
    commandStatus="$?"
  fi
elif [ -n "${flag_f}" ] ; then
  ###
  ### Flash Upgrade:   luupgrade -f -n "BE_name" [-l error_log] [-o outfile] [-N] (-s flash_path | -j profile_path | -J "profile")
  ###
  lulib_must_have_option "${flag_n}" "-f" "-n"
  lulib_must_have_option "${flag_s}" "-f" "-s"
  lulib_must_have_options "${flag_j}${flag_J}${flag_a}" "-f" "-j, -J, -a"
  lulib_cannot_have_conflicting_option "${flag_a}" "-f" "${flag_j}" "-j"
  lulib_cannot_have_conflicting_option "${flag_a}" "-f" "${flag_J}" "-J"
  lulib_cannot_have_conflicting_option "${flag_j}" "-f" "${flag_J}" "-J"
  lulib_cannot_have_argument "${cmdNames}" "-f"

  mount_miniroot "$flag_s" ""
  do_flashInstall "${CURR_BE}" "${BE_NAME}" "${flag_j}" "${flag_J}" "${flag_N}" "${flag_D}" "${flag_s}" "${flag_a}"
  commandStatus="$?"
elif [ -n "${flag_i}" ] ; then
  ###
  ### Run Installer:   luupgrade -i -n "BE_name" [-l error_log] [-o outfile] [-N] -s installer_source_path [-O "installer_options"] [installer]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}" "-i" "-d, -a, -D, -F, -j, -J"
  lulib_must_have_option "${flag_n}" "-i" "-n"
  lulib_must_have_option "${flag_s}" "-i" "-s"
  do_runInstaller "${BE_NAME}" "${flag_N}" "${flag_O}" "${flag_s}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_p}" ] ; then
  ###
  ### Add Packages:    luupgrade -p -n "BE_name" [-l error_log] [-o outfile] [-N] ((-s|-d) packages_path) [-a pkg_admin_file] [-O "pkgadd_options"] [pkginst [pkginst...]]
  ###
  lulib_cannot_have_options "${flag_D}${flag_F}${flag_j}${flag_J}" "-p" "-D, -F, -j, -J"
  lulib_cannot_have_conflicting_option "${flag_s}" "-s" "${flag_d}" "-d"
  lulib_must_have_option "${flag_n}" "-p" "-n"
  lulib_must_have_option "${flag_s}${flag_d}" "-p" "-s, -d"
  # For the -a option, pretend that it was inside of a "-O" option
  if [ -n "${flag_a}" ] ; then
    if [ -z "${flag_O}" ] ; then
      flag_O="-a ${flag_a}"
    else
      flag_O="${flag_O} -a ${flag_a}"
    fi
  fi
  do_addPackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${flag_s}${flag_d}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_t}" ] ; then
  ###
  ### Add Patches:     luupgrade -t -n "BE_name" [-l error_log] [-o outfile] [-N] -s patches_path  [-O "patchadd_options"] [patchname [patchname...]]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}" "-t" "-d, -a, -D, -F, -j, -J"
  lulib_must_have_option "${flag_n}" "-t" "-n"
  lulib_must_have_option "${flag_s}" "-t" "-s"
  do_addPatches "${BE_NAME}" "${flag_N}" "${flag_O}" "${flag_s}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_P}" ] ; then
  ###
  ### Remove Packages: luupgrade -P -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "pkgadd_options"] pkginst [pkginst...]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_s}${flag_j}${flag_J}" "-P" "-d, -a, -D, -F, -s, -j, -J"
  lulib_must_have_option "${flag_n}" "-P" "-n"
  lulib_must_have_argument "${cmdNames}" "-P"
  do_removePackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_T}" ] ; then
  ###
  ### Remove Patches:  luupgrade -T -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "patchrm_options"] patchname [patchname...]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_s}${flag_j}${flag_J}" "-T" "-d, -a, -D, -F, -s, -j, -J"
  lulib_must_have_option "${flag_n}" "-T" "-n"
  lulib_must_have_argument "${cmdNames}" "-T"
  do_removePatches "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_C}" ] ; then
  ###
  ### Check Packages:    luupgrade -C -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "pkgadd_options"] [pkginst [pkginst...]]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}${flag_s}" "-p" "-d, -a, -D, -F, -j, -J, -s"
  lulib_must_have_option "${flag_n}" "-p" "-n"
  do_checkPackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_I}" ] ; then
  ###
  ### Package Info:    luupgrade -I -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "pkgadd_options"] [pkginst [pkginst...]]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}${flag_s}" "-p" "-d, -a, -D, -F, -j, -J, -s"
  lulib_must_have_option "${flag_n}" "-p" "-n"
  do_infoPackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_u}" ] ; then
  ###
  ### OS Upgrade:      luupgrade -u -n "BE_name" [-l error_log] [-o outfile] [-N] -s os_image_path [-j profile_path]
  ###
  lulib_cannot_have_options "${flag_d}${flag_J}" "-u" "-d, -J"
  lulib_must_have_option "${flag_n}" "-u" "-n"
  lulib_must_have_option "${flag_s}" "-u" "-s"
  lulib_cannot_have_argument "${cmdNames}" "-u"
  ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext 'Upgrade Operating System of BE <%s> from media <%s>.'`" "${BE_NAME}" "${flag_s}"

  #
  # With Newboot aka GRUB boot, the miniroot is a compressed file
  # Expand and mount the miniroot here.
  #
  mount_miniroot "$flag_s" ""
  do_upgradeOs "${BE_NAME}" "${flag_j}" "${flag_N}" "${flag_s}" "${CURR_BE}" "${flag_D}"
  commandStatus="$?"
  if [ "${commandStatus}" -ne "0" ] ; then
    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext 'Operating System upgrade FAILED.'`"
  else
    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext 'Operating System upgrade successful.'`"
  fi
else
  # ### NO OPERATION TO PERFORM?
  ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (dont know which operation to perform).'`"
  exit_script 2
fi

# Operation has completed

exit_script $commandStatus
