#!/bin/ksh
#
# Script to initiate Flash update from Soalris
#
# id: @(#)FWupdate 1.5 02/10/22
# purpose: 
# copyright: Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved
#


#
# Display the banner
#

BANNER="@(#) Flash Update Tool (c) 2002 Sun Microsystems, Inc. v"
VER="0.1"
echo
echo
echo $BANNER$VER
echo


#
# Assign the defaults
#

filename="zzxyz"
device="zzxyz"
fwtype="zzxyz"
force=0

#
# Define the script usage
#

usage()
{
    echo "usage: $0 [-h]"
    echo "usage: $0 [-F] -f <filepath> -d <device> -t <FW type>"
    echo
    echo "\t -h : Help, show usage"
	echo "\t -F : To Force the update when the FW is being downgraded"
    echo "\t -f : Complete filepath & filename specified by following argument"
    echo "\t -t : Type of FW binary. Possible options={sparc, smc, sparc+smc}"
    echo "\t -d : Complete path of device node or device alias specifying"
    echo "\t      the device where file is located"
    echo "\t      If disk is specified, the file must be in the root"
	echo "\t      directory. Also, the file cannot of a Symbolic link"
	echo
	echo "\t      Note: To use this script, you must be super user"
	echo
	echo "#### RUNNING THIS SCRIPT REBOOTS THE CPU BOARD FOR FIRMWARE UPDATE ####"
    echo
}


#
# Look at the arguments and validate them
#

set -A opts
opts[1]=$1
opts[2]=$2
opts[3]=$3
opts[4]=$4
opts[5]=$5
opts[6]=$6
opts[7]=$7
opts[8]=$8

i=1
while [ $i -le $# ]
do
    j=$((i+1))

    case ${opts[$i]} in
    -f) filename=${opts[$j]} ; i=$((i+2)) ;;
    -d) device=${opts[$j]}   ; i=$((i+2)) ;;
    -t) fwtype=${opts[$j]}   ; i=$((i+2)) ;;
    -h) usage ; exit 1 ;;
	-F) force=1              ; i=$((i+1)) ;;
     *) echo "Bad options. Use -h option for help" ; exit 1;;
    esac
done


#
# Check if we are Super User
#

UTYPE1=`id`
UTYPE2=`id | grep root`
if [[ $UTYPE1 != $UTYPE2 ]]
then
	echo "### MUST BE SUPER USER TO EXECUTE THIS SCRIPT ###"
	exit 1
fi

echo
echo
echo "##### THIS SCRIPT WILL REBOOT THE SYSTEM TO PERFORM FIRMWARE UPDATE #####"
echo


#
# Check if all mandatory options are specified
#

if [[ $filename = "zzxyz" ]]
then
	echo "Missing \"filename\". Use -f option to specify the filename"
	echo "Use -h option to get the usage"
	exit 1
fi

if [[ $device = "zzxyz" ]]
then
	echo "Missing \"device\". Use -d option to specify the device"
	echo "Use -h option to get the usage"
	exit 1
fi

if [[ $fwtype = "zzxyz" ]]
then
	echo "Missing \"FW type\". Use -t option to specify the FW type"
	echo "Use -h option to get the usage"
	exit 1
fi


#
# Display the current options selected
#

echo "Using the following settings..."
echo "Filename : " $filename
echo "Device   : " $device
echo "FW type  : " $fwtype


#
# Check the value of <FW type>
#

case $fwtype in
sparc)      cmd=flash-update;;
smc)        cmd=smc-flash-update;;
sparc+smc)  cmd=flash-update;;
*)          echo "Unknown \"<FW Type>\" value : " $fwtype ; exit 1;;
esac

#
# The file specified should not have any relative paths. Must be
#   complete filepaths
#

BASEFILENAME=`basename $filename`
DIRFILENAME=`dirname $filename`

while true
do
	if [[ $BASEFILENAME = "." ]] || [[ $BASEFILENAME = ".." ]]
	then
		echo "Relative File Paths are not allowed"
		echo "Please Specify the Complete Filepath without the use of \"..\" & \".\""
		exit 1
	fi
	if [[ $BASEFILENAME = "/" ]]
	then
		break
	fi
	BASEFILENAME=`basename $DIRFILENAME`
	DIRFILENAME=`dirname $DIRFILENAME`
done

# Device name maybe just an devalias or complete path to device node
# When device is disk:
#	Filename cannot be a Symbolic Link
#	Filename must be in root directory

DEVICENAME=`basename $device`
DEVICEBASENAME=`echo $DEVICENAME | awk -F@ '{ print $1 }'`
DIRFILENAME=`dirname $filename`

if [[ $DEVICEBASENAME = "disk" ]] || [[ $DEVICEBASENAME = "sd" ]]
then
	if [ -L $filename ]
	then
		echo "File $filename is a Symbolic Link"
		echo "Update from disk cannot work with a Sym Link"
		exit 1
	fi

	if [[ $DIRFILENAME != "/" ]]
	then
		echo "Update from disk needs the file to be in Root directory"
		exit 1
	fi
fi

#
# Check if specified file exists
#

if [ -d $filename ]
then
	echo "$filename is a directory!"
	exit 1
fi

if [ ! -f $filename ]
then
	echo "Specified file : " $filename " Not Found"
	exit 1
fi


#
# Lets check the contents of the binary
#

echo
echo "Checking the input file format..."

MAGIC=`od -X -N 4 $filename | awk '{print $2}'`
case $MAGIC in
"4f424d44") echo "\tFile is OBP/Combined image"   ; INP=flash-update ;;
"43450000") echo "\tFile is SMC Boot Code image"  ; INP=smc-flash-update ;;
"43452000") echo "\tFile is SMC Boot Code image"  ; INP=smc-flash-update ;;
"43460000") echo "\tFile is SMC Flash Code image" ; INP=smc-flash-update ;;
*)          echo "\tFile is of Unknown Format. Cannot Proceed!" ; exit 1 ;;
esac

if [[ $cmd != $INP ]]
then
	echo "Specified \"FW Type\" DOES NOT matches the Input File Format"
	echo "Use -t option to specify right \"FW type\". Cannot proceed!"
	exit 1
fi


#
# Lets get the new binary info
#

echo
SCRPTPATH=`dirname $0`
echo "FW Info file : " $SCRPTPATH/.FWupdate.info
. $SCRPTPATH/.FWupdate.info

echo
echo "NEW FIRMWARE INFO :"
echo "SPARC Version  : " $FWVER
echo "SPARC Build    : " $BLDVER
echo "SMCFW Version  : " $SMCFWVER
echo "Board          : " $BOARDNAME
echo "Model          : " $BOARDMODEL
echo


#
# Lets get the existing binary info
#

PRTDIAG=/usr/platform/`uname -i`/sbin/prtdiag
PRTCONF=/usr/sbin/prtconf

echo "CURRENT FIRMWARE INFO :"

CURRFWVER=`$PRTCONF -V | awk '{print $18}'`
CURRBLDVER=`$PRTCONF -V | awk '{print $21}'`
CURRBOARDNAME=`$PRTDIAG | grep SPARC | awk '{print $7}'`
CURRBOARDMODEL=`$PRTDIAG | grep SPARC | awk '{print $9}'`

echo "SPARC Version  : " $CURRFWVER
echo "SPARC Build    : " $CURRBLDVER
echo "Board          : " $CURRBOARDNAME
echo "Model          : " $CURRBOARDMODEL
echo


#
# Lets check the validity  : board type, model, fw version etc.
#

if [[ $CURRBOARDNAME != $BOARDNAME ]]
then
	echo "The New Firmware Binary does not belongs to this platform"
	echo "Board Name do not match. Cannot proceed!"
	exit 1
fi

if [[ $CURRBOARDMODEL != $BOARDMODEL ]]
then
	echo "The New Firmware Binary does not belongs to this platform"
	echo "Board Model do not match. Cannot Proceed!"
	exit 1
fi

if [[ $FWVER -le $CURRFWVER ]]
then
	echo "WARNING: The New FW Version is Equal or Older to the Current FW!"
	if [[ $force = 0 ]]
	then
		echo "Use -F option to Force the Update of this Firmware"
		exit 1
	fi
fi


#
# All the validation has been done. Lets initiate the update.
#

echo
echo "Updating $fwtype image with file :"
echo "\t\t$filename"
echo "\t\ton device \"$device\" using \"$cmd\""

rebootpar="obp:$cmd $device:,$filename"

echo
echo "Reboot parameter:"
echo "\t\t" $rebootpar
echo

sync;sync;sync
/usr/sbin/reboot -- "$rebootpar"


#
# Control should not get here...
#

echo
echo Reboot Failed!!!
echo
