#!/bin/sh
#
#    Broadcom Proprietary and Confidential. Copyright © 2004-2021 Broadcom.
#    All Rights Reserved.
#    The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
#
#    Description:
#
#        This pre-install script will be run before firmware
#        download or firmwarerestore starts. 
#
MSG="
There  is  a  problem  with  the  firmware  image  installed  on  the  server.
The preinst file is in DOS format. Please reload the firmware image on server,
using the right tool/options  (to prevent  DOS style  ASCII file conversions),
and then retry firmwaredownload.  "; # comment so ^M will not impact MSG.
#set -x
check4dos() { if [ $# -gt 1 ] ; then echo "$MSG" ; exit 5 ; fi ; } ; check4dos 1 

#
# Note the extra space (above) at the end of the call "check4dos 1 " right here ^
# This space is very important for it to work correctly.
# In case of dos conversion it will add a ^M at the end of this space.
# That will make it look like calling check4dos with 2 parameters,
# and result in $MSG being printed out instead of the current failure
# ": not a signal specification" which does not convey what exactly went wrong.
#
# This will not address all types of conversion errors though.
# We have seen cases wher ^M was added at the end of PATH below.
# To address that a space has been added at the end of that line
#


#################################################################################
# Preinst BASH mode logs will be saved in /var/log/preinst.log
#################################################################################

CUR_MAJOR=$(/sbin/getfabosver | /bin/sed -n -e 's/Major://gp')
# Preintstall script debug mode execution
if [ $CUR_MAJOR -ge 9 ]; then
       exec 19>/var/log/preinst.log
       export BASH_XTRACEFD=19
       set -x
fi

#####################################################################################
# The install_subversion is manintained across each patch releases. If the major,
# minor and patch firmware versions are same between current firmware and the to-be 
# downloadable firmware, the preinstall script which has higher install_subversion 
# will be executed.
#####################################################################################
INSTALL_SUBVERSION=11

##################################################################################
#  Attention!!  Attention!!  Attention!!  Attention!!  Attention!!  Attention!!  # 
#  ---------    ---------    ---------    ---------    ---------    ---------    #
#              Add Only TAGS here! This is the TAGs section.........              #
# Please do not remove these lines in all future merges. These are feature TAGS. #
# each TAG in a given preinst script indicates support for the respective feature#
# in that version of FOS. The TAG method of compatibility checking/fwdl blocking #
# was first introduce to block fwdl of versions not supporting 8548 Rev 3.1 CPU  #
# on zentron 4 CP and then extended to support these other subsequent features.  #
#																				 #
# TAG method provides a finer granularity compatibility checking/fwdl blocking   #
# at the patch id level, thereby permitting feature porting to patch versions.   #
# These defines are for use with the check_features.sh.in script where all the   #
# firmware version compatibility checking and firmwaredownload blocking resides. #
# the TAGs are NOT for use by preinst script itself. This is because there is no #
# guarantee as to  whether the preinst of the current version or the new version #
# will be invoked. fwdl always invokes the higher FOS version's preinst script.  #
# if <major>.<minor>.<patch> version of the current and new (to be downloaded)   #
# FOS version are equal then it invokes the preinst of the to be downloaded FOS  #
#																				 #
##################################################################################

CP31_ZENTRON4_SUPPORTED="Version Supports 8548 Rev 3.1 CP"
NON_DFE_SUPPORTED="Version Supports NON DFE"
QSFPP_ICL_SUPPORTED="Version Supports QSFPP ICL"
BUF_OP_MODE_SUPPORTED="Version Supports BufOpMode"
GEN6_BUF_OP_MODE_SUPPORTED="Version Supports Gen 6 BufOpMode"
Q20_SWBD134_SUPPORTED="Version Supports Q20 for Huawei"
ROOT_PERMANET_DISABLE_SUPPORTED="Version Supports Permanetly Disable root for Huawei"
IPFILTER514_SUPPORTED="Skybolt does not boot with this. warn user to remove 514"
NONDFE_FORCE_DISABLE_SUPPORTED="Version supports portcfgnondfe --force_disable"
TACACS_ENCRYPTION_SUPPORTED="Version Supports TACACS Encryption"
RADIUS_TACACS_ENCRYPTION="Version has encrypted secrets"
CHEW_SERDES_SUPPORTED="SBI:0x101b_0x01_SI:0xFE5D_0045"
SOLO_SUPPORTED="Supports solo device"
QSFP_32G_ICL_SUPPORTED="This verison Supports 2KM 32G QSFP ICL"
NEW_128MB_FLASH_SUPPORTED="This verison Supports the new 128MB Flash"
QSFP_32G_2KM_ICL_NON_ICL_SUPPORTED="Version Supports 2KM 32G QSFP in both ICL and NON ICL Ports"
WEDGE_CR_SUPPORT="Version support LCW"
LS_ACC_CLEAN_ADDRESS_BIT_SUPPORTED="Version supports Clean Address Bit"
DOWNGRADE_UPGRADE_FROM_V81X_TEST_ONLY_SUPPORTED="Version supports downgrade to & upgrade from v8.1.x_test_only_release builds"
BSN_SUPPORT_LINK_SUPPORTED="Version supports BSL"
EMULEX_FPORT_TRUNKING_SUPPORTED="Version supports Emulex F-Port Trunking"
LDAP_ROLE_NAME_LENGTH_64_SUPPORTED="This version supports LDAP role name with length 64 characters"
DOWNGRADE_UPGRADE_FROM_V81X_TEST_ONLY_SUPPORTED="Version supports downgrade to & upgrade from v8.1.x_test_only_release builds"
SSH_PERMIT_USER_ENV_NOTSUPPORTED="PermitUserEnvironment is not supported"
SUPPORTS_CYPRESS_16M_BOOTFLASH="Version supports the new Cypress 16M BootFlash"
GEN7_SUPPORTED="Version supports Gen7 switches"
FCR_LONG_DISTANCE_FABRIC_MODE_SUPPORT="Version supports FCR to bring up EX-port with differnet Long Distance Fabric Mode"
CYPRESS_MID01_BOOTFLASH_SUPPORTED="Version support for the new Cypress 16M BootFlash-do not use 9.0 Tag - use this for this support"
HUAWEI_SPECIAL_SWBD_SUPPORTED="This special verison of huawei switches without encryption support"
SUPPORT_NEWER_G610="Version supports NEW V4 G610 and G610LW switches"
FICON_DISRUPTIVE_DOWNGRADE="Version has CUP filters installed even if FMS is disabled in FICON."
MS_ACL_SUPPORTED="Version supports the MS ACL feature"
GRAPHITE32_MISS_HASH_SUPPORT="This version support Graphite32 enhanced licensing"
LUMENTUM32G_QSFP_GEN7_CORE_BLADE_SUPPORTED="Version Supports Lumentum 32G QSFP in GEN7 Core Blades"
FTC_AG_SUPPORT="Version supports FTC on AG"
CHEW_VF="Version supports VF on Chewbacca with 2 partitions"
LWL_32G_SFP_SUPPORTED="Version Supports 32G LWL SFP in GEN7 setups. This tag first implemented in v9.0.1b release"
SERVICE_SHELL_SUPPORTED="Version supports Service Shell"
FINISAR_GEN7_2KM_ICL_QSFP_SUPPORTED="Version supports Finisar GEN7 2KM QSFP"
SFPDD_SUPPORTED='Version supports SFPDD'
LICENSED_64G_SFP_SUPPORTED='Version supports Licensed 64G SFP'
GEN6_KENOBI_SUPPORTED='Version supports Gen6 Kenobi feature'
NON_SECURE_VESPER_SUPPORTED='Version supports non secure vesper feature'
SECURE_CHEWBACCA_SUPPORTED='Version supports secure chewbacca feature'
UBOOT_FPGA_SUPPORTED='Uboot supports FPGA version'
LWL_ELWL_64G_ELWL_32G_SUPPORTED='Version Supports 64G LWL and ELWL SFP and 32G ELWL SFP in GEN7 setups.'
SECURE_MAXIM_SEEPROM_V1_SUPPORTED='Version supports platfroms with Secure Maxim SEEPROM.'
HISENSE_32G_LWL_SUPPORTED="Version supports Hisense 32G LWL SFP"
#################################################################################
##     END of TAGs Section.........                                            ##
#################################################################################

# Trap / Ignore SIGINT so user cannot interrupt this script with ^C
trap "" 2
trap "" SIGPIPE

#
# Passed in version numbers
#
TO_MAJOR=$1
TO_MINOR=$2
TO_PATCH=$3


PREINST="/sbin/preinst"
NEW_PREINST_FILE="/tmp/preinst"
ENC_VERSION_STR="6.1.1_enc"
ENC_VERSION_STR_DEV="6.1.1orion"
CEE_VERSION_STR="6.1.2_cee"
RELEASE_FILE="/tmp/release.plist"
RESTORE_FILE="/mnt/fabos/share/release"
CHECK_FEATURES_FILE="/sbin/check_features"
MAPS_WARN_FILE="maps_82_warning.txt"
MAPS_WARN_VFID_FILE="/tmp/.maps_warn_vfid_file"
MAPS_OPC_WARN="WARN"
MAPS_OPC_ERR="ERROR"


#
# When firmwaredownload is invoking this script,
# TYPE should be NULL; when firmwarerestore is
# invoking it, TYPE is "restore"
#
if [ "$4" = "restore" ]; then
    TYPE=$4
    FWNAME="$5 $6 $7"
    FWVERSION=$7
    FROM_MAJOR=$5
    FROM_MINOR=$6
    FROM_PATCH=$7
    FROM_RELEASE_STR=`/bin/cat /etc/version.conf  | /bin/grep "Release" | /bin/awk '{print $2}'`
    FROM_RELEASE=${FROM_RELEASE_STR:0:1}
else
    FWNAME=$4
    TYPE=""
fi

CHASSISCONFIG=/bin/getchassisconfig
AUTHORIZED_KEYS_PATH=/fabos/users/admin/.ssh/

##########################################################
#    Begin Common code for Preinst / check_features      #
#    Need to move this to common file shared by the      #
#    2 scripts to prevent finding/fixing same bug twice  #
##########################################################

PATH=/bin:/usr/bin:/sbin:/usr/sbin # adding comment to protect from DOS conversion

#
# Common variables
#
DEBUG=0
NULL=/dev/null
if [ "$DEBUG" = 1 ]; then
	ECHO='echo -e'
else
	ECHO=:
fi

$ECHO $@
$ECHO To version:${TO_MAJOR}.${TO_MINOR}.${TO_PATCH}
if [ -n "$TYPE" ]; then
  $ECHO From version:${FROM_MAJOR}.${FROM_MINOR}.${FROM_PATCH}
fi

# This should match the file name in src/lib/upgrade/upgrade.c
STATUS_FILE=/tmp/fwdl_err.txt
BNA_STATUS_FILE=/tmp/bna_fwdl_err.txt
EULA_FILE=/etc/fabos/eula.txt

#
# Error codes - these have to match the error codes
# in fwdl.h.
#

STS_OK=0
STS_ERR=255

AMP_22_CONFIG_SIZE=30000
RET_CODE=${STS_OK}
RET=${STS_OK}

export CHASSIS_ROLEID=0
if /fabos/bin/fosconfig --show | grep "Virtual Fabric" | grep enabled > /dev/null 2>&1 ; then
	VF_ENABLED=$STS_ERR;
else 
	VF_ENABLED=$STS_OK;
fi

#
# cpid
#
# Retrieve the current Control Processor ID
#
cpid() {
    /bin/sed -n -e 's/^Control.\+No: \([[:digit:]]\{1,\}\)$/\1/gp'
}

#
# swbd
#
# Retrieve the current system platform name, of the form "SWBDn", where n
# is cardinal number, assuming a sin/hinv input stream.
#
swbd() {
    /bin/sed -n -e 's/^.\+\(SWBD[[:digit:]]\{1,\}\).\+$/\1/gp'
}

# Determine the system platform identifier.
SWBD=`sin | swbd 2> ${NULL}`
CPID=`sin | cpid 2> ${NULL}`


timestamp()
{
	/bin/date '+%m/%d/%y %H:%M:%S'
}

otherhost(){
#        printf 10.0.0.$((5+$(othercp)))
	case ${SWBD##SWBD} in
	'165' | '166' | '179' | '180')
	    printf 127.3.1.$((2 - CPID % 2))
	    ;;
	*)
	    printf 10.0.0.$((6 - CPID % 2))
	    ;;
	esac
}

HASHOW="$(/fabos/bin/hashow)"

othercp(){
        that=${HASHOW#*Remote CP \(Slot}
        that="${that%%,*}"
        printf $(($that - 5))
}


ha_role() {
	/fabos/cliexec/hashow -l | /bin/grep ACTIVE > /dev/null 2>&1
	if [ $? -eq 0 ]; then
		printf "ACTIVE"
	else
		printf "STANDBY"
	fi
}

HA_ROLE=$(ha_role)
if [ $HA_ROLE == "ACTIVE" ]; then
    ACTIVECP=1
fi

ha_state() {
    sync=`/fabos/cliexec/hashow | /bin/sed -n -e 's/^.\+\(State sync\).\+$/\1/gp'`

    if [ "$sync" != "State sync" ]; then
	    printf "NOSYNC"
    else
	    printf "SYNC"
    fi
}

HA_STATE=$(ha_state)


########################################################
#    End Common code for Preinst / check_features      #
########################################################


BNA_WARN_STATUS_FILE=/tmp/bna_fwdl_warn.txt
FWDL_WARN_STATUS_FILE=/tmp/fwdl_warn.txt
FCIP_STATUS_FILE=/tmp/fcip_fwdl_err.txt
APPSERVER_STATUS_FILE=/tmp/appserver_status_file.txt
ENC_BLOCK_DGRD_FILE=/tmp/enc_block_dgrd.txt


# clear status file
# Moved the clear to checkfeatures script for firmwaredownload case

# Clear for firmwarerestore case
if [ -n "$TYPE" ]; then
	echo > $STATUS_FILE
	echo " " > $STATUS_FILE
	echo > $BNA_STATUS_FILE
	echo " " > $BNA_STATUS_FILE

	echo "The following items need to be addressed before restoring the specified firmware:" >> $STATUS_FILE
fi

add_err_status(){
	echo -e "$1" >> $STATUS_FILE
	if [ "$#" -eq "1" ]; then
		echo -e "$1" >> $BNA_STATUS_FILE
	elif [ "$#" -eq "2" ]; then
		echo -e "$2" >> $BNA_STATUS_FILE
	fi	
}

add_warn_status(){
	if [ $CUR_MAJOR -lt 9 ]; then 
		echo -e "$1"
	fi
	echo -e "$1" >> $FWDL_WARN_STATUS_FILE
	if [ "$#" -eq "1" ]; then
		echo -e "$1" >> $BNA_WARN_STATUS_FILE 
	elif [ "$#" -eq "2" ]; then
		echo -e "$2" >> $BNA_WARN_STATUS_FILE
	fi	
}


add_err_status_fid(){
	if [ "$#" -eq 2 ]; then
		echo -e "$1" "$2" >> $STATUS_FILE
		echo -e "$1" "$2" >> $BNA_STATUS_FILE
	elif [ "$#" -eq 3 ]; then
		echo -e "$1" "$3" >> $STATUS_FILE
		echo -e "$2" "$3" >> $BNA_STATUS_FILE
	fi
	
}

add_warn_status_fid(){
		if [ "$#" -eq 2 ]; then
		if [ $CUR_MAJOR -lt 9 ]; then
                	echo -e "$1" "$2"
        	fi
                echo -e "$1" "$2" >> $FWDL_WARN_STATUS_FILE
                echo -e "$1" "$2" >> $BNA_WARN_STATUS_FILE
	        elif [ "$#" -eq 3 ]; then
		if [ $CUR_MAJOR -lt 9 ]; then
                	echo -e "$1" "$3"
        	fi
                echo -e "$1" "$3" >> $FWDL_WARN_STATUS_FILE
                echo -e "$2" "$3" >> $BNA_WARN_STATUS_FILE
       		fi
                #echo -e "$1" "$2" >> $BNA_WARN_STATUS_FILE
}

is_fwdl_arg() {

	#
	# Reads command line args passed to firmwaredownload
	# and checks if the required argument is specified
	#
	fwdl_proc_id=`ps -ef | awk '/[f]irmwaredownload /{print $2}'`
	for arg in $(/usr/bin/tr '\0' ' ' < /proc/${fwdl_proc_id}/cmdline)
	do
            case $arg in
            (-*$1*)
		return $STS_OK
		;;
            esac
        done
        return $STS_ERR
}

allow_nondisruptive_fwdl() {
	# Skip for restore
	if [ -n "$TYPE" ]; then
		$ECHO " running firmwarerestore"
		return $STS_OK
	fi

	is_fwdl_arg "s"
	local singlemode=$?
	is_fwdl_arg "f"
	local forcemode=$?
	if [ $singlemode -ne 0 -o $forcemode -ne 0 ]; then
		return $STS_ERR
	fi

	return $STS_OK
}


STS_AUTOBOOT_ERR=254
allow_disruptive_single_mode_fwdl() {
	# Skip for restore
	if [ -n "$TYPE" ]; then
		$ECHO " running firmwarerestore"
		return $STS_OK
	fi
	local slotbased= 
	local auto_boot=
	is_fwdl_arg "s"
	local singlemode=$?
	if [ $singlemode -ne 0 ]; then
		return $STS_ERR
	fi
	slotbased=`/sbin/bootenv slotbased 2>/dev/null| grep yes`
	
	if [ "$slotbased" != "yes" ] ; then
		auto_reboot=`/sbin/bootenv autoboot 2>/dev/null | grep yes`
		if [ "$auto_reboot" = "yes" ] ; then
			#return $STS_ERR		
            return $STS_AUTOBOOT_ERR;
		fi
	fi
	return $STS_OK
}

handle_disruptive_single_mode_fwdl() {
    allow_disruptive_single_mode_fwdl
    local tempvar=$?
        if [ $tempvar != $STS_OK ]; then
            if [ $tempvar = $STS_AUTOBOOT_ERR ]; then
                add_err_status "$DISRUPTIVE_FWDL_AUTOBOOT_DISABLE" "$BNA_UNSUPPORTED_NON_DISRUPTIVE_MODE_FWDL"
            elif [ $tempvar = $STS_ERR ]; then
                add_err_status "$UNSUPPORTED_NON_DISRUPTIVE_MODE_FWDL" "$BNA_UNSUPPORTED_NON_DISRUPTIVE_MODE_FWDL"
            fi
            return $STS_ERR
        fi
    return $STS_OK
}

check_for_non_disruptive_fwdl() {
	# Skip for restore
	if [ -n "$TYPE" ]; then
		$ECHO " running firmwarerestore"
		return $STS_ERR
	fi

	is_fwdl_arg "s"
	local singlemode=$?
	if [ $singlemode -ne 0 ]; then
		return $STS_ERR
	fi

	return $STS_OK
} 

check_autoreboot_opt() {
	# Skip for restore
	if [ -n "$TYPE" ]; then
		$ECHO " running firmwarerestore"
		return $STS_OK
	fi

	is_fwdl_arg "b"
	local auto_reboot=$?
	if [ $auto_reboot -eq 0 ]; then
		return $STS_ERR
	fi

	return $STS_OK
}


handle_disruptive_single_mode_fwdl_amp() {
    check_for_non_disruptive_fwdl
    local tempvar=$?
        if [ $tempvar != $STS_OK ]; then
            add_err_status "$UNSUPPORTED_NON_DISRUPTIVE_MODE_FWDL" "$BNA_UNSUPPORTED_NON_DISRUPTIVE_MODE_FWDL"
            return $STS_ERR
        fi
    return $STS_OK
}

TEST() {

	$ECHO  -n "$(timestamp) TEST $1 "
	if [ $HA_ROLE == "STANDBY" ] && [ $HA_STATE == "NOSYNC" ]; then
	    return $STS_OK
	fi

	$1
 	if [ "$?" -ne "$STS_OK" ]; then
		$ECHO "failed"
		if [ "$#" -eq "2" ]; then
			add_err_status "$2"
		elif [ "$#" -eq "3" ]; then
			add_err_status "$2"	"$3"
		fi		
		RET_CODE=$STS_ERR
		return $STS_ERR
	fi

	$ECHO "passed"
	return $STS_OK
}

TEST_FIDS()
{
	check_failed=0
	FID_CONTEXT="FID(s)"
	SPACE_STRING=" "
	PERIOD="."
	COMMA=","
	num_err=0
	rval=$STS_OK
	local_flag=$?
	non_vf_switch="the switch"

	$ECHO  -n "$(timestamp) TEST $1 "
	if [ $(ha_role) == "STANDBY" ] && [ $(ha_state) == "NOSYNC" ]; then
		$ECHO "skipped - standby out of sync"
	    return $STS_OK
	fi
	if [ $VF_ENABLED -ne $STS_OK ]; then 
		if [ $(ha_role) == "ACTIVE" ]; then
			FID_LIST=${CONTEXTS}
		else
			/bin/ln -s /fabos/cliexec/lscfg_util /fabos/link_sbin/lscfg_test 2> /dev/null
			export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool
			STANDBY_FIDS=`lscfg_test --all | grep -e "[0-9]" | grep -v "Total" | \
							awk '{ print $2 }'`
			FID_LIST=$STANDBY_FIDS
		fi

		for FID in $FID_LIST
		do
			context_switch $FID
			$1
			if [ $? -ne $STS_OK ]; then
				check_failed=1
				num_err=`expr $num_err + 1`
				if [ $num_err -eq 1 ]; then
					FID_CONTEXT=$FID_CONTEXT$SPACE_STRING$FID
				else
					FID_CONTEXT=$FID_CONTEXT$COMMA$FID
				fi
			else
				continue
			fi
		done
	else
		$1
		if [ $? -ne $STS_OK ]; then
			check_failed=1
			FID_CONTEXT=$non_vf_switch
		fi
	fi
	if [ $check_failed -eq 0 ]; then
		$ECHO "passed"
		return $STS_OK
	else
		$ECHO "failed"
		FID_CONTEXT=$FID_CONTEXT$PERIOD
		if [ "$#" -eq 2 ]; then
			add_err_status_fid "$2" "$FID_CONTEXT"
		elif [ "$#" -eq 3 ]; then
			add_err_status_fid "$2" "$3" "$FID_CONTEXT"
		fi
		RET_CODE=$STS_ERR
		return $STS_ERR
	fi

}

TEST_FIDS_ADV()
{
	check_failed=0
	FID_CONTEXT="FID(s)"
	SPACE_STRING=" "
	PERIOD="."
	COMMA=","
	num_err=0
	rval=$STS_OK
	local_flag=$?
	non_vf_switch="switch"


	$ECHO  -n "$(timestamp) TEST $1 "
	if [ $HA_ROLE == "STANDBY" ] && [ $HA_STATE == "NOSYNC" ]; then
		$ECHO "skipped - standby out of sync"
	    return $STS_OK
	fi
	 numOfArgs="$#"; # get the last argument
	 lastArg=${!#}; # get the last argument
	 fArgs="${lastArg/funcArgs=}";
	 # it means user has not passed any function arguments
	 if [ "$fArgs" == "$lastArg" ]
	 then
	     fArgs=""
	 fi
	 arg2=$(eval echo $`echo $2`);
	 let numOfArgs=numOfArgs-1
	 if [ $numOfArgs -eq 3 ]; then
	     arg3=$(eval echo $`echo $3`);
	 fi

	if [ $VF_ENABLED -ne $STS_OK ]; then 
		if [ $HA_ROLE == "ACTIVE" ]; then
			FID_LIST=${CONTEXTS}
		else
			/bin/ln -s /fabos/cliexec/lscfg_util /fabos/link_sbin/lscfg_test 2> /dev/null
			export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool
			STANDBY_FIDS=`lscfg_test --all | grep -e "[0-9]" | grep -v "Total" | \
							awk '{ print $2 }'`
			FID_LIST=$STANDBY_FIDS
		fi

		for FID in $FID_LIST
		do
			context_switch $FID
			$1 $fArgs
			if [ $? -ne $STS_OK ]; then
				check_failed=1
				num_err=`expr $num_err + 1`
				if [ $num_err -eq 1 ]; then
					FID_CONTEXT=$FID_CONTEXT$SPACE_STRING$FID
				else
					FID_CONTEXT=$FID_CONTEXT$COMMA$FID
				fi
			else
				continue
			fi
		done
	else
	    $1 $fArgs
		if [ $? -ne $STS_OK ]; then
			check_failed=1
			FID_CONTEXT=$non_vf_switch
		fi
	fi
	if [ $check_failed -eq 0 ]; then
		$ECHO "passed"
		return $STS_OK
	else
		$ECHO "failed"
		FID_CONTEXT=$FID_CONTEXT$PERIOD
		if [ $numOfArgs -eq 2 ]; then
			add_err_status_fid "$arg2" "$FID_CONTEXT"
		elif [ $numOfArgs -eq 3 ]; then
			add_err_status_fid "$arg2" "$arg3" "$FID_CONTEXT"
		fi
		RET_CODE=$STS_ERR
		# echo "....$numOfArgs  ... $arg2"
		# cat $STATUS_FILE
		return $STS_ERR
	fi

}

CHASSISCMD=""
cliidx=0
export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool
export VFROLEMAP=-1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

context_switch()
{
    if [ $VF_ENABLED -ne $STS_OK ]; then
        if [ "$1" != "chassis" ]
        then
            eval $(/fabos/cliexec/lscfg_util --switch $1 2> /dev/null)
        else
            eval $(/fabos/cliexec/lscfg_util --chassis 2> /dev/null)
            #export CHASSIS_ROLEID=0
        fi
    fi
	glb_vf_id="$CURRENT_VF"
	glb_ls_id="$FABOS_SWITCHNO"
    export ROLE_ID=root
}

cmd_chassis() {

  context_switch chassis

  if [ "$CONFIG" = "TRUE" ]; then
    echo -n . > $TTY
    cliidx=`/usr/bin/expr $cliidx + 1`
    echo "$cliidx $1 $2 $3 $4 $5 $6 $7 $8 $9" >> $cshow
    echo -e "$1 $2 $3 $4 $5 $6 $7 $8 $9:"
      echo "** $1 $2 $3 $4 $5 $6 $7 $8 $9: Command:$rc **" >> $cshow
  else
    echo -e "$1 $2 $3 $4 $5 $6 $7 $8 $9:"
    $1 $2 $3 $4 $5 $6 $7 $8 $9
  fi
}


# Helper function. It sets the global variable CONTEXTS to be a list of fabric
# IDs. Typical usage is seen in the function for_all_contexts, where we use
# CONTEXTS if it is defined, and otherwise call this function. This means we
# only need to do the configshow once for each run of preinst, rather than
# once for each test that wants to run in all contexts
#get_all_contexts(){
#	CONTEXTS=$($CHASSISCMD /fabos/cliexec/configshow -all | sed -n 's/Fabric ID =//p')
#	echo $CONTEXTS
#}
CHASSISCMD=cmd_chassis
	CONTEXTS=$($CHASSISCMD /fabos/cliexec/configshow -all | /bin/sed -n 's/Fabric ID =//p')



glb_ls_id=0
glb_vf_id=128
def_vf_id=128

# This function is the replacement of CONFIGSHOW function.
# This function  returns the configuration from local copy instead of doing RSH
# to active CP and get the configuration
# In the begining copyAllConfigurationFiles function copy all the configuration
# to /tmp directory and expect below function would use that configuration.
CONFIGSHOW_ADV() {
    if [ "$1" = "-chassis"  ]; then 
	cat /tmp/config_chassis
    elif [ "$1" = "-a" ] || [ "$1" = "-all" ] ; then
	cat /tmp/config_all
    else
	if [ $VF_ENABLED -ne $STS_OK ]; then
	    cat /tmp/config_$CURRENT_VF
	else 
	    cat /tmp/config_128
	fi
    fi
}

#This function is being used only by copyAllConfigurationFiles 
#There is no need for the caller to call this function instead call 
#CONFIGSHOW_ADV function


CONFIGSHOW() {
	if [ $ACTIVECP ] ; then
		if [ "$1" = "-chassis"  ]; then 
			cat /tmp/config_chassis
		elif [ "$1" = "-a" ] || [ "$1" = "-all" ] ; then
			cat /tmp/config_all
		else
			if [ $VF_ENABLED -ne $STS_OK ]; then
				cat /tmp/config_$CURRENT_VF
			else 
				cat /tmp/config_128
			fi
		fi
	else
		if [ "$1" = "-chassis"  ]; then 
			cmd="/fabos/cliexec/configshow -chassis"
			glb_ls_id=-1;
			glb_vf_id=255;
		elif [ "$1" = "-a" ] || [ "$1" = "-all" ] ; then
			glb_ls_id=-1;
			glb_vf_id=255;
			cmd="/fabos/cliexec/configshow -all"
		else
			cmd="/fabos/cliexec/configshow"
		fi
	
		if [ $VF_ENABLED -eq $STS_OK ]; then
			# VF disabled
			/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CURRENT_AD=0 "$cmd"
		else
			# VF enabled, for_all_context changed glb_ls_id and glb_vf_id to each logical switch's
			/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CHASSIS_ROLEID=0 FABOS_SWITCHNO=$glb_ls_id CURRENT_VF=$glb_vf_id CURRENT_AD=0 "$cmd"
		fi
	fi

}

# copy all the configuration to tmp files before pre-install script runs.
# this avoids anyone to run RSH

copyAllConfigurationFiles() {
    # checks for active or standby
    if [ $ACTIVECP ] ; then
	#VF enable
	if [ $VF_ENABLED -ne $STS_OK ]; then
	    # iterating through all the FIDs
	    for FID in ${CONTEXTS} ; do
		context_switch $FID
		/fabos/cliexec/configshow -fid $FID > /tmp/config_$FID
	    done
	else
	    # in non FD enviorenment there will be only one configuration - no all, no chassis
	    /fabos/cliexec/configshow > /tmp/config_128
	    
	fi
	/fabos/cliexec/configshow -chassis  > /tmp/config_chassis
	/fabos/cliexec/configshow -all  > /tmp/config_all
    else
	# VF is enabled on standby

	if [ $VF_ENABLED -ne $STS_OK ]; then

	    /bin/ln -s /fabos/cliexec/lscfg_util /fabos/link_sbin/lscfg_test 2> /dev/null
	    local_flag=$?
	    export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool
	    lscfg_test --all | grep -e "[0-9]" | grep -v "Total" |
	    while read glb_ls_id glb_vf_id role
	    do
	        context_switch $glb_vf_id
		CONFIGSHOW > /tmp/config_$glb_vf_id
	    done
	    CONFIGSHOW "-chassis" > /tmp/config_chassis
	    CONFIGSHOW "-all" > /tmp/config_all
	    
	    # deleting the soft link created by ln command above
	    if [ $local_flag -eq 0 ];then 
		/bin/rm /fabos/link_sbin/lscfg_test 2> /dev/null;
	    fi
	else
	    CONFIGSHOW > /tmp/config_128
	    CONFIGSHOW -chassis > /tmp/config_chassis
	    CONFIGSHOW -all > /tmp/config_all
	fi
    fi    
}

# calling to copy configuration files to /tmp directory
copyAllConfigurationFiles

# Helper function. Loop over the valid fabric IDs running the test that is passed as
# a parameter. As soon as one test fails then return $STS_ERR. If all pass then
# return $STS_OK.
# WARNING. This command will change to a random context (The first one that fails
# the test or the last context if all pass). Random terms in case someone is searching
# this file, VF Virtual Fabric AD setcontext FID context and wants to find this warning
for_all_contexts(){
	for FID in ${CONTEXTS} ; do
		context_switch $FID
		glb_vf_id="$CURRENT_VF"
		glb_ls_id="$FABOS_SWITCHNO"
		
		if "$@"
		then	$ECHO -n "$FID-passed "
		else	$ECHO -n "$FID-failed "
			    return $STS_ERR
		fi
	done
	return $STS_OK
}

for_all_contexts_standby(){
	rval=$STS_OK
	/bin/ln -s /fabos/cliexec/lscfg_util /fabos/link_sbin/lscfg_test 2> /dev/null
	local_flag=$?
	export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool
	lscfg_test --all | grep -e "[0-9]" | grep -v "Total" |
	while read glb_ls_id glb_vf_id role
	do
		context_switch $glb_vf_id
		if "$@"
		then	$ECHO -n "$glb_vf_id-passed "
		else	$ECHO -n "$glb_vf_id-failed "
			# note the following return just return from the "|" subshell
			return $STS_ERR
		fi
	done
	if [ $? -ne $STS_OK ]; then rval=$STS_ERR; fi
	if [ $local_flag -eq 0 ];then /bin/rm /fabos/link_sbin/lscfg_test 2> /dev/null; fi
	return $rval
}

# Helper function. Run the passed in test from the default switch context
for_def_context(){
	for FID in ${CONTEXTS} ; do
		context_switch $FID
		glb_vf_id="$CURRENT_VF"
		glb_ls_id="$FABOS_SWITCHNO"

		if "$@"
		then	$ECHO -n "$FID-passed "
				return $STS_OK
		else	$ECHO -n "$FID-failed "
			    return $STS_ERR
		fi
	done
	return $STS_OK
}

for_def_context_standby(){
	rval=$STS_OK
	/bin/ln -s /fabos/cliexec/lscfg_util /fabos/link_sbin/lscfg_test 2> /dev/null
	local_flag=$?
	export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool
	lscfg_test --all | grep -e "[0-9]" | grep -v "Total" |
	while read glb_ls_id glb_vf_id role
	do
		context_switch $glb_vf_id
		if "$@"
		then	$ECHO -n "$glb_vf_id-passed "
			# note the following return just return from the "|" subshell
			return $STS_OK
		else	$ECHO -n "$glb_vf_id-failed "
			# note the following return just return from the "|" subshell
			return $STS_ERR
		fi
	done
	if [ $? -ne $STS_OK ]; then rval=$STS_ERR; fi
	if [ $local_flag -eq 0 ];then /bin/rm /fabos/link_sbin/lscfg_test 2> /dev/null; fi
	return $rval
}

#
# vf_enabled
#
# Check whether VF is enabled
# both Active and Standby have this information
#
check_vf_enabled() {
	/fabos/bin/fosconfig --show | grep "Virtual Fabric" | grep enabled > /dev/null 2>&1

	if [ $? -eq 0 ]; then
        return $STS_ERR
    else
        return $STS_OK
    fi

}

correcthost() {
    if [ $ACTIVECP ]; then
	"$@"
    else
	/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CURRENT_AD=0 "$@"
    fi
}


# get the current firmware version
#CUR_MAJOR=$(/sbin/getfabosver | sed -n -e 's/Major://gp')
CUR_MINOR=$(/sbin/getfabosver | /bin/sed -n -e 's/Minor://gp')
CUR_PATCH=$(/sbin/getfabosver | /bin/sed -n -e 's/Patch://gp')
ACTIVE_MAJOR=$(correcthost /sbin/getfabosver | /bin/sed -n -e 's/Major://gp')
ACTIVE_MINOR=$(correcthost /sbin/getfabosver | /bin/sed -n -e 's/Minor://gp')
ACTIVE_PATCH=$(correcthost /sbin/getfabosver | /bin/sed -n -e 's/Patch://gp')
LOCAL_MAJOR=$(/sbin/getfabosver | /bin/sed -n -e 's/Major://gp')
LOCAL_MINOR=$(/sbin/getfabosver | /bin/sed -n -e 's/Minor://gp')
LOCAL_PATCH=$(/sbin/getfabosver | /bin/sed -n -e 's/Patch://gp')

#
# both Active and Standby have the information of
# VF and logical switches configured.
#
# VF case: on Standby CP, in order to login to each logical switch, 
# we need to set CHASSIS_ROLEID FABOS_SWITCHNO CURRENT_VF in rsh.
#
correcthost_to_curr_vfid() {
	if [ $ACTIVECP ] ; then
		# for_all_context already did "context_switch --switch vfid"
		"$@"
	else
		if [ $VF_ENABLED -eq $STS_OK ]; then
			# VF disabled
			/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CURRENT_AD=0 "$@"
		else
			# VF enabled, for_all_context changed glb_ls_id and glb_vf_id to each logical switch's
			/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CHASSIS_ROLEID=0 FABOS_SWITCHNO=$glb_ls_id CURRENT_VF=$glb_vf_id CURRENT_AD=0 "$@"
		fi
	fi
}

# executes the provided function in the context of all configured virtual
# fabrics, and logical switches on the active and standby CP's to determine
# if a critera is met
correcthost_all_vfs() {
	if [ $VF_ENABLED -ne $STS_OK ]; then
		# VF is enabled
		if [ $ACTIVECP ] ; then
			for_all_contexts correcthost_to_curr_vfid $@
		else
			# this is the standby cp, examine the configuration of the
			# active cp
			for_all_contexts_standby correcthost_to_curr_vfid $@
		fi
	else
		correcthost_to_curr_vfid $@
	fi
	if [ $? -eq 0 ]; then
		return $STS_OK
	else
		return $STS_ERR
	fi
}

# executes the provided function in the default switch context
# on the active and standby CP's to determine if a critera is met
correcthost_def_vf() {
	if [ $VF_ENABLED -ne $STS_OK ]; then
		# VF is enabled
		if [ $ACTIVECP ] ; then
			for_def_context correcthost_to_curr_vfid $@
		else
			# this is the standby cp, examine the configuration of the
			# active cp
			for_def_context_standby correcthost_to_curr_vfid $@
		fi
	else
		correcthost_to_curr_vfid $@
	fi
	if [ $? -eq 0 ]; then
		return $STS_OK
	else
		return $STS_ERR
	fi
}


###################################################
### The messages are for firmwarerestore.	###
###################################################
FWDL_RUNNING_MSG="Firmwaredownload or firmwarecommit is already running. Please wait for it to complete first."
FWRESTORE_DISALLOWED_MSG="No need to run firmwarerestore because firmware has already been committed, or there is no firmwaredownload performed."

###################################################
###################################################
####                                           ####
####                                           ####
####     PRESINSTALL MESSAGES SECTION          ####
####    ------------------------------         ####
####                                           ####
###################################################
###################################################
UNSUPPORTED_DL_VERMSG="Cannot downgrade to 8.2.x or lower. Please downgrade to 9.0.x first and then download the desired firmware version."
UNSUPPORTED_UP_VERMSG="Cannot upgrade directly to 9.1.x. Please upgrade to 9.0.x or higher first and then upgrade to 9.1.x"
UNSUPPORTED_NON_DISRUPTIVE_MODE_FWDL="Non disruptive firmwaredownload is not supported when firmwaredownload with two versions apart. Please try to use \"firmwaredownload\" with single mode option enabled."
DISRUPTIVE_FWDL_AUTOBOOT_DISABLE="Non disruptive firmwaredownload is not supported when firmwaredownload with two versions apart. Disruptive firmware download is disallowed when auto-boot option is enabled. Please disable auto-boot and try again."
UNSUPPORTED_FWDL_AMP="Cannot download the requested firmware because firmware downgrade from version 3.0.0 to 2.1.0 or lower is not supported in AMP."
SWITCH_FAULTY_MSG="Firmwaredownload is not allowed since the switchState is Faulty. Use \"switchShow\" to see the switch state. Please recover the switch before proceeding."
XFCIP_FEATURE_RESTRICTION="Firmwaredownload is not allowed because some extension features did not pass firmwaredownload pre-checks (see above). Please address these issues before proceeding."
EXTN_CERT_UNSUPP_FILENAME="There are extension certificates, CSRs, or private keys whose filenames have unsupported characters. Supported characters are as follows:\na-zA-Z0-9~@%_+:-\nPlease use the cli \"seccertmgmt delete\" to delete these files and then recreate them before upgrading to v8.2.1 or higher."
SNMP_USER_PASSWD_ENCRYPTION_WARN="WARNING: SNMP functionality may be affected if snmpv3 users have authentication and privacy password length lesser than 8. Please use snmpconfig --set snmpv3 to update the authentication and privacy password and it must be between 8 and 32 characters length."
MAPS_82_WARN="In MAPS, user-defined rules are present for IP_EXTN_FLOW. These rules will not be monitored in pre-8.2.0 FOS version."
MAPS_RE_BALANCE_CONFIG_ERR="WARNING: RE_BALANCE action is enabled - it is not supported in pre-FOS8.2.1 release. Please use 'mapsconfig --actions' command to delete this action from FID: "
UNSUPPORTED_OPWHASH_MSG="WARNING !!!! Password hash in the history contains non-MD5 hash for user(s) which must be cleared to proceed with downgrade. Please confirm with [Y/N] to proceed further, when prompted for."
RASLOG_MODE_PRESENT="WARNING: Custom Raslog Mode is not supported in pre-8.2.0. MAPS generates default RASLOGs-1001-4 for all the monitoring systems in default raslog mode"
ISL_RRDY_BS="Downgrade is not allowed because ISL R_RDY mode is enabled on a port in the Base Switch. Please disable using \"portcfgislmode\" before downgrading."
FIPSINSIDE_NOTSUPPORTED="FIPS Inside is enabled and target version is not FIPS Inside compliant. Please disable the same using \"seccryptocfg --apply -group Compliance -attr FIPSInside -value no\" to downgrade."
MAPS_901_SFP_DOWNGRD_WARN="WARNING: The SFP group ALL_64GSWL_SFP and ALL_80Km_8GELWL_SFP are NOT supported in pre FOS9.0.x release. Downgrade to pre FOS9.0.x release will NOT monitor the custom rules on these group(s). The impacted FID(s):"
MAPS_910_DYN_GRP_UPGRD_WARN="WARNING: MAPS dynamic group based on nodewwn is not supported in AG mode in FOS9.1.0 and above. Please remove such groups using \"logicalgroup --delete\". The impacted FID(s):"
CHANGE_DEFAULT_PWD="Password(s) for admin/user are at default. Kindly change the password to non-default value before proceeding."
MAPS_FENCE_ACT_TXP_RXP_ERROR="User defined rules for MS TXP or RXP with actions fence or decom are not supported in pre-FOS9.0.1 release. Please remove these actions using command \"mapsrule --config\" before firmware downgrade. The impacted FID(s):"
MAPS_FENCE_ACT_DEV_LATENCY_ERROR="User defined rules for MS DEV_LATENCY_IMPACT with actions fence or decom are not supported in pre-FOS9.1.0 release. Please remove these actions using command \"mapsrule --config\" before firmware downgrade. The impacted FID(s):"
MAPS_ASC_UPLD_WARN="WARNING: User defined rules are present for ASC_UPLOAD_FAILURE MS and it is not supported in pre-FOS9.0.1 release. The impacted FID(s):"
TI_ZONE_DEPRECATION_ERR="ERROR: Traffic Isolation (TI) Zones are detected on the switch and are no longer supported in the target version of Fabric OS."
RD_ZONE_DEPRECATION_ERR="ERROR: Frame Redirection (RD) Zones are detected on the switch and are no longer supported in the target version of Fabric OS."
BROADCAST_ZONE_DEPRECATION_ERR="ERROR: A Broadcast zone is detected on the switch and is no longer supported in the target version of Fabric OS."
FA_ZONE_DEPRECATION_ERR="ERROR: A Fabric Assist (FA) zone or alias is detected on the switch. Fabric Assist (FA) support is deprecated in the target version of Fabric OS. Please remove these zone objects and try again."
QL_ZONE_DEPRECATION_ERR="ERROR: A Quickloop zone or alias is detected on the switch. Quickloop support is deprecated in the target version of Fabric OS. Please remove these zone objects and try again."
LOCATION_ID_SET="A Location ID is configured. Remove the Location ID and try again."
MAPS_FRU_QT_WARN="WARNING: In FOS9.1.0 and above QT will not be supported for FRU MS's such as PS_STATE, FAN_STATE, BLADE_STATE, WWN, SFP_STATE, ETH_MGMT_PORT_STATE and the configuration will be ignored after upgrade. The impacted FID(s): "
IPSEC_DISABLE_WARN="IPSec feature is enabled. Please disable it by using \"ipsecConfig --disable\" CLI command, as it is deprecated in target release."
IPSEC_DISABLE_WARN_STANDBY="IPSec feature is enabled. Firmware upgrade will disable IPsec as it is deprecated in target release."
PORTSWAP_DISABLE_ERR="Upgrade is not allowed since swapped ports exists.Please use portswap --restore to restore the port address to proceed."
PORTCFGALPA_ERR="Upgrade is not allowed since ports are configured with ALPA. Please use portcfgdefault [SlotNumber/][ge]PortNumber and proceed."
LD_LS_NOEFLICENSE_ERR="Upgrade is not allowed because one or more ports have Dynamic (LD) or Static (LS) long distance configured, without an Extended Fabrics license."
ASC_CA_BUNDLE_UPDATE_WARN="WARNING: HTTPS client ca-bundle is being updated in the target firmware version. Please check HTTPS client connectivity in the new firmware."
HALF_DUPLEX_CONFIG_PRESENT="Firmwaredownload is not allowed because half duplex is configured.  Use ethif --set to clear half duplex configuration before upgrade."
IPFILTER_FORWARD_RULE_PRESENT="Firmwaredownload is not allowed because one or more ipfilter policy is configured with FORWARD rule. IPFilter forwarding is not supported in the target version. Please modify or delete ipfilter policies using \"ipfilter --delete\" or \"ipfilter --delrule\""
MEDIA_PIRACY_VALIDATION_FAILED="Firmware upgrade is not allowed as port\(s\) \$BAD_MEDIA_PORTS have Non Standard Media plugged into them. Please replace those media and validate media using \"sfpshow\" CLI. Then proceed with firmware upgrade."
EXTN_GEN7_MEDIA_VALIDATION_FAILED="Firmware downgrade is not allowed as port\(s\) \$BAD_MEDIA_PORTS have Gen7 Media plugged into them. Please replace those media and validate media using \"sfpshow\" CLI. Then proceed with firmware downgrade"
LDAP_GC_CONFIGURED_WARN_MSG="WARNING: LDAP Global Catalog (default port 3268) is not supported in the target firmware version. Please use \"aaaconfig --change\" CLI to modify the LDAP server configuration to use Domain Controller port (default port 389)."
LDAPS_CONFIGURED_WARN_MSG="WARNING: LDAPS (default port 636) is not supported in the target firmware version. Please change the server configuration to StartTLS (default port 389) instead."
FICON_CUP_ADDR_IN_USE="Firmware download is not allowed since FICON CUP addresses 0xFE or 0xFF are in use. Please use \"portaddress --bind\" command to bind some other address to these ports before proceeding."
FICON_LS_PORT_LIMIT_EXCEEDED="Firmware download is not allowed since the FICON LS has more than 254 physical ports in it. Please move out few ports using \"lscfg --config\" command before proceeding."
DEFAULT_TCP_TIMEOUT_WARN="WARNING: Downgrade may cause current tcptimeoutlevel setting to be reset to default value."
UNSUPPORTED_DC_PSU_ON_DOWNGRADE_ERR="Downgrade is not allowed since DC PSU is not supported in the target firmware"
UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR="Downgrade is not allowed since 64G SFP is present on port\(s\) \$ports_with_64G_sfp. Please remove the 64G SFP and retry firmwaredownload."
UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR="Downgrade is not allowed since 8G SMARTOPTICS SFP is present on port\(s\) \$ports_with_8G_smartoptics_sfp. Please remove the 8G SMARTOPTICS SFP and retry firmwaredownload."
UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR="Upgrade is not allowed since 16G SMARTOPTICS SFP is present on port\(s\) \$ports_with_16G_smartoptics_sfp. Please remove the 16G SMARTOPTICS SFP and retry firmwaredownload."
ICL_EX_PORT_RESTRICTION_ON_NON_VF="Upgrade is not allowed since EX-port on ICL port is present on non-VF switches. Please remove this config and retry firmwaredownload."
RSC_NOT_SUPPORTED="Firmwaredownload is not allowed. since the ESRS RSC feature is enabled. Please disable it using \"esrsconfig --disable rsc\" before downgrade. The RSC is supported from 9.1.0 and above FOS versions"
APP_HDR_CFG_ENABLED="Downgrade is not allowed because App Header configuration is enabled or one or more ports. Please disable the configuration using the portcfgappheader cli."
CFS_V2_PROFILE_ACTIVATED="Firmwaredowngrade is not allowed as Traffic Optimizer Sys_TrafOpt_Version2 is active. Please activate Sys_TrafOpt_Version1 using \"trafopt --activate Sys_TrafOpt_Version1\" before downgrade"
NTP_AUTHENTICATION_CONFIGURED_WARN_MSG="WARNING: NTP authentication is not supported in the target firmware version."
NTP_LEGACY_MODE_DISABLED="Downgrade is not allowed since Time Server legacy mode is disabled. Please enable legacy mode and retry firmwaredownload."
UNSUPPORTED_G610LW_ERR="Firmwaredownload failed. The switch does not support this release."
PDCM_DEPRECATED_ERR_MSG="ERROR: Prohibited connections are detected in the Allow/Prohibit matrix configuration on the switch. The Allow/Prohibit matrix is no longer supported in the target version of Fabric OS, so please remove the Prohibited connections before upgrading to the target version of the Fabric OS."
MAX_PA_FICON_LS_ERR_MSG="ERROR: Port addresses greater than the maximum physical port range are not allowed to bind to port in a FICON logical switch, for the target version of Fabric OS. The impacted FIDS and ports are given below. Please unbind the reported ports or bind them to port address lesser than the maximum physical port range using the CLI \"portaddress\""
ROOT_DISABLED_WARN_MSG="WARNING: Root account is disabled in the target firmware version."
RTA_ENABLED_WARN_MSG="WARNING: RTA feature is enabled in the target firmware version. Please check the system time configuration before proceeding."
ROOT_PASSWORD_RESET_WARN_MSG="WARNING: Root account password will be reset to default in the target firmware version."
SERVICE_SHELL_RESET="Service shell feature is not supported in the target version. Please reset the service shell using \"serviceShell --reset\"."
SERVICE_SHELL_RESET_STANDBY="Service shell feature is not supported in the target version. Please reset the service shell using \"serviceShell --reset\" on Standby CP."
FACTORY_SHELL_RESET="Factory shell feature is not supported in the target version. Please reset the factory shell using \"factoryCfg --reset\"."
FACTORY_SHELL_RESET_STANDBY="Factory shell feature is not supported in the target version. Please reset the factory shell using \"factoryCfg --reset\" on Standby CP."
UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR="Downgrade is not allowed since 4G EPort\(s\) or EXPort\(s\) present on port\(s\) \$ports_with_4g_eports. Please change the speed or disable the port and retry firmwaredownload."
ROOT_USERID_SHELL="User account(s) with invalid attributes detected. Please perform password recovery to default the user accounts."
UNSUPPORTED_ADMLCK_CONACC="Downgrade is not allowed since console access is enabled during admin lockout. Please disable the console access using \"passwdcfg --enableadminlockout -disable consoleaccess\"."
#######################################################
### The messages are for firmwarerestore from BNA.	###
#######################################################
BNA_FWDL_RUNNING_MSG="Firmware download or firmware commit is already running. Please wait for it to complete first."
BNA_FWRESTORE_DISALLOWED_MSG="No need to run firmware restore because firmware has already been committed, or there is no firmware download performed."
###################################################
###################################################
####                                           ####
####                                           ####
####     PRESINSTALL MESSAGES SECTION FOR BNA  ####
####    -------------------------------------  ####
####                                           ####
###################################################
###################################################
BNA_UNSUPPORTED_DL_VERMSG="Cannot downgrade to 8.2.x or lower. Please downgrade to 9.0.x first and then download the desired firmware version."
BNA_UNSUPPORTED_UP_VERMSG="Cannot upgrade directly to 9.1.x. Please upgrade to 9.0.x or higher first and then upgrade to 9.1.x"
BNA_UNSUPPORTED_NON_DISRUPTIVE_MODE_FWDL="Non disruptive firmware download is not supported when firmware download with two versions apart. Please try again from cli with single mode option enabled."
BNA_UNSUPPORTED_FWDL_AMP="Cannot download the requested firmware beacuse Firmware downgrade from version 3.0.0 to 2.1.0 or lower is not supported in AMP."
BNA_SWITCH_FAULTY_MSG="Firmwaredownload is not allowed since the switchState is Faulty. Please recover the switch before proceeding."
BNA_EXTN_CERT_UNSUPP_FILENAME="There are extension certificates, CSRs, or private keys whose filenames have unsupported characters. Supported characters are as follows:\na-zA-Z0-9~@%_+:-\nPlease use the cli \"seccertmgmt delete\" to delete these files and then recreate them before upgrading to v8.2.1 or higher."
BNA_XFCIP_FEATURE_RESTRICTION="Firmwaredownload is not allowed because some extension features did not pass firmwaredownload pre-checks. Please address these issues before proceeding."
BNA_81_RULES_CONFIG_ERR="Downgrade is not allowed, because there are MAPS user-defined rule names with length greater than 40. Please delete these rules in"
BNA_81_ROR_RULES_CONFIG_ERR="Downgrade is not allowed, because there are MAPS ROR rules are present. Please delete these rules in"
BNA_SNMP_USER_PASSWD_ENCRYPTION_WARN="WARNING: SNMP functionality may be affected if snmpv3 users have authentication and privacy password length lesser than 8. Please use snmpconfig --set snmpv3 to update the authentication and privacy password and it must be between 8 and 32 characters length."
BNA_RASLOG_MODE_PRESENT="Custom Raslog Mode is not supported in pre-8.2.0. MAPS generates default RASLOGs-1001-4 for all the monitoring systems in default raslog mode"
BNA_ISL_RRDY_BS="Downgrade is not allowed because ISL R_RDY mode is enabled on a port in the Base Switch. Please disable using \"portcfgislmode\" before downgrading."
BNA_FIPSINSIDE_NOTSUPPORTED="FIPS Inside is enabled and target version is not FIPS Inside compliant. Please disable the same using \"seccryptocfg --apply -group Compliance -attr FIPSInside -value no\" to downgrade."
BNA_UNSUPPORTED_DAA_FEATURE="Downgrade is not allowed since DAA feature is enabled. Please disable the feature using \"fosconfig\" command to downgrade."
FDW_SNMPV1_WARNING="WARNING: SNMPv1 has default community string. Please disable SNMPv1 or reconfigure."
BNA_CHANGE_DEFAULT_PWD="Password(s) for admin/user are at default. Kindly change the password to non-default value before proceeding."
BNA_MAPS_901_SFP_DOWNGRD_WARN="WARNING: The SFP group ALL_64GSWL_SFP and ALL_80Km_8GELWL_SFP are NOT supported in pre FOS9.0.x release. Downgrade to pre FOS9.0.x release will NOT monitor the custom rules on these group(s). The impacted FID(s):"
BNA_MAPS_910_DYN_GRP_UPGRD_WARN="WARNING: MAPS dynamic group based on nodewwn is not supported in AG mode in FOS9.1.0 and above. Please remove such groups using \"logicalgroup --delete\". The impacted FID(s):"
BNA_MAPS_FENCE_ACT_TXP_RXP_ERROR="User defined rules for MS TXP or RXP with actions fence or decom are not supported in pre-FOS9.0.1 release. Please remove these actions using command \"mapsrule --config\" before firmware downgrade. The impacted FID(s):"
BNA_MAPS_FENCE_ACT_DEV_LATENCY_ERROR="User defined rules for MS DEV_LATENCY_IMPACT with actions fence or decom are not supported in pre-FOS9.1.0 release. Please remove these actions using command \"mapsrule --config\" before firmware downgrade. The impacted FID(s):"
BNA_MAPS_ASC_UPLD_WARN="WARNING: User defined rules are present for ASC_UPLOAD_FAILURE MS and it is not supported in pre-FOS9.0.1 release. The impacted FID(s):"
BNA_TI_ZONE_DEPRECATION_ERR="ERROR: Traffic Isolation (TI) Zones are detected on the switch and are no longer supported in the target version of Fabric OS."
BNA_RD_ZONE_DEPRECATION_ERR="ERROR: Frame Redirection (RD) Zones are detected on the switch and are no longer supported in the target version of Fabric OS."
BNA_BROADCAST_ZONE_DEPRECATION_ERR="ERROR: A Broadcast zone is detected on the switch and is no longer supported in the target version of Fabric OS."
BNA_FA_ZONE_DEPRECATION_ERR="ERROR: A Fabric Assist (FA) zone or alias is detected on the switch. Fabric Assist (FA) support is deprecated in the target version of Fabric OS. Please remove these zone objects and try again."
BNA_QL_ZONE_DEPRECATION_ERR="ERROR: A Quickloop zone or alias is detected on the switch. Quickloop support is deprecated in the target version of Fabric OS. Please remove these zone objects and try again."
BNA_MAPS_FLOW_MON_WARN="WARNING:FOS clears MAPS rules or groups to monitor flows upon upgrade to 9.0.0"
BNA_LOCATION_ID_SET="A Location ID is configured. Remove the Location ID and try again."
BNA_MAPS_FRU_QT_WARN="WARNING: In FOS9.1.0 and above QT will not be supported for FRU MS's such as as PS_STATE, FAN_STATE, BLADE_STATE, WWN, SFP_STATE, ETH_MGMT_PORT_STATE and the configuration will be ignored after upgrade. The impacted FID(s): "
BNA_IPSEC_DISABLE_WARN="IPSec feature is enabled. Please disable it by using \"ipsecConfig --disable\" CLI command, as it is deprecated in target release."
BNA_IPSEC_DISABLE_WARN_STANDBY="IPSec feature is enabled. Firmware upgrade will disable IPsec as it is deprecated in target release."
ACT_SYS_FLOW_ALL_VF="\nWARNING: The Predefined flow \"sys_flow_monitor\" will be activated by default in all the LS partitions."
BNA_PORTSWAP_DISABLE_ERR="Upgrade is not allowed since swapped ports exists.Please use portswap --restore to restore the port address to proceed."
BNA_PORTCFGALPA_ERR="Upgrade is not allowed since ports are configured with ALPA. Please use portcfgdefault [SlotNumber/][ge]PortNumber and proceed."
BNA_LD_LS_NOEFLICENSE_ERR="Upgrade is not allowed because one or more ports have Dynamic (LD) or Static (LS) long distance configured, without an Extended Fabrics license."
BNA_ASC_CA_BUNDLE_UPDATE_WARN="WARNING: HTTPS client ca-bundle is being updated in the target firmware version. Please check HTTPS client connectivity in the new firmware."
BNA_HALF_DUPLEX_CONFIG_PRESENT="Firmwaredownload is not allowed because half duplex is configured.  Use ethif --set to clear half duplex configuration before upgrade."
BNA_LDAP_MANDATORY_NOV_VF_MAPROLE_WARN_MSG="WARNING: LDAP authentication is enabled on this switch. LDAP authentication mandates role mapping in the target firmware version. Please map the AD group to a switch role with \"ldapcfg --maprole\" command to avoid probable login failure for LDAP users after upgrade."
BNA_IPFILTER_FORWARD_RULE_PRESENT="Firmwaredownload is not allowed because one or more ipfilter policy is configured with FORWARD rule. IPFilter forwarding is not supported in the target version. Please modify or delete ipfilter policies using \"ipfilter --delete\" or \"ipfilter --delrule\""
BNA_MEDIA_PIRACY_VALIDATION_FAILED=$MEDIA_PIRACY_VALIDATION_FAILED
BNA_LDAP_GC_CONFIGURED_WARN_MSG="WARNING: LDAP Global Catalog (default port 3268) is not supported in the target firmware version. Please use \"aaaconfig --change\" CLI to modify the LDAP server configuration to use Domain Controller port (default port 389)."
BNA_LDAPS_CONFIGURED_WARN_MSG="WARNING: LDAPS (default port 636) is not supported in the target firmware version. Please change the server configuration to StartTLS (default port 389) instead."
BNA_EXTN_GEN7_MEDIA_VALIDATION_FAILED=$EXTN_GEN7_MEDIA_VALIDATION_FAILED
BNA_FICON_CUP_ADDR_IN_USE="Firmware download is not allowed since FICON CUP addresses 0xFE or 0xFF are in use. Please bind some other address to these ports before proceeding."
BNA_FICON_LS_PORT_LIMIT_EXCEEDED="Firmware download is not allowed since the FICON LS has more than 254 ports in it. Please move few ports out of the LS before proceeding."
BNA_UNSUPPORTED_DC_PSU_ON_DOWNGRADE_ERR="Downgrade is not allowed since DC PSU is not supported in the target firmware"
BNA_UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR=$UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR
BNA_UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR=$UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR
BNA_UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR=$UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR
BNA_UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR=$UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR
BNA_ICL_EX_PORT_RESTRICTION_ON_NON_VF=$ICL_EX_PORT_RESTRICTION_ON_NON_VF
BNA_APP_HDR_CFG_ENABLED="Downgrade is not allowed because App Header configuration is enabled or one or more ports. Please disable the configuration using the portcfgappheader cli."
BNA_NTP_AUTHENTICATION_CONFIGURED_WARN_MSG=$NTP_AUTHENTICATION_CONFIGURED_WARN_MSG
BNA_NTP_LEGACY_MODE_DISABLED=$NTP_LEGACY_MODE_DISABLED
BNA_UNSUPPORTED_G610LW_ERR=$UNSUPPORTED_G610LW_ERR
BNA_PDCM_DEPRECATED_ERR_MSG=$PDCM_DEPRECATED_ERR_MSG
BNA_MAX_PA_FICON_LS_ERR_MSG=$MAX_PA_FICON_LS_ERR_MSG
BNA_ROOT_DISABLED_WARN_MSG=$ROOT_DISABLED_WARN_MSG
BNA_RTA_ENABLED_WARN_MSG=$RTA_ENABLED_WARN_MSG
BNA_ROOT_PASSWORD_RESET_WARN_MSG=$ROOT_PASSWORD_RESET_WARN_MSG
BNA_SERVICE_SHELL_RESET=$SERVICE_SHELL_RESET
BNA_SERVICE_SHELL_RESET_STANDBY=$SERVICE_SHELL_RESET_STANDBY
BNA_FACTORY_SHELL_RESET=$FACTORY_SHELL_RESET
BNA_FACTORY_SHELL_RESET_STANDBY=$FACTORY_SHELL_RESET_STANDBY
BNA_RSC_NOT_SUPPORTED="Firmwaredownload is not allowed. since the ESRS RSC feature is enabled. Please disable it using \"esrsconfig --disable rsc\" before downgrade. The RSC is supported from 9.1.0 and above FOS versions"
BNA_ROOT_USERID_SHELL=$ROOT_USERID_SHELL
BNA_UNSUPPORTED_ADMLCK_CONACC=$UNSUPPORTED_ADMLCK_CONACC
#######################################################
#######################################################
###################################################
###################################################
####                                           ####
####                                           ####
####       PRESINSTALL CHECK SECTION           ####
####    ------------------------------         ####
####                                           ####
###################################################
###################################################


#
# Check if Application Server-Header supported on this platform:
#   If supported, then disruptive downgrade is required - returns STS_ERR
#   If not supported, then non-disruptive downgrade is allowed - return STS_OK
#
check_app_server_disruptive_downgrade_required() {


	# If on standby CP then before you attempt to run appserver (which may not exists) to do this check
	# first check if the Actve CP has appserver
	if [ ! $ACTIVECP ] ; then
		appserverDoesNotExist=$(correcthost ls -al /fabos/cliexec/appserver  2> ${NULL} | grep -c "No such file or directory")
		if [ $appserverDoesNotExist ]; then
			return $STS_OK;
		fi
	fi

       correcthost_all_vfs /fabos/cliexec/appserver --show -domain local | /bin/grep "Entity ID" > $APPSERVER_STATUS_FILE

       app_server_check=`cat $APPSERVER_STATUS_FILE | /bin/grep -c "Entity ID"`

	if [ "$app_server_check" -ne "0" ]; then
		is_fwdl_arg "s"
		if [ $? -ne 0 ]; then
               	rm $APPSERVER_STATUS_FILE >/dev/null 2>&1
			return $STS_ERR
		fi
	fi

	rm $APPSERVER_STATUS_FILE >/dev/null 2>&1
	return $STS_OK
}

#
# ag_mode_enabled
#
# Check whether the switch is currently in AG mode
#
# JOE
ag_mode_enabled() {

	ag_mode=$(correcthost /fabos/link_bin/switchshow | grep -c "Access Gateway Mode")
	return $ag_mode

}

# is_extn_platform()
#
# Return true if this is an extension platform
is_extn_platform()
{
	case ${SWBD##SWBD} in

	'165' | '166' | '178' | '179' | '180')
		return 1
		;;
	esac

	return 0
}

# is_psu_dc()
#
# Returns true if DC PSU is used
is_psu_dc()
{
	dc_count=`/fabos/link_bin/chassisshow | /bin/grep "Power Source" | /bin/grep -c "DC"`
	if [[ $dc_count -ne 0 ]]; then
		return 1
	fi
	return 0
}

check_sfp_8G_smartoptics()
{
	# Get list of port which have 8G SmartOptics media plugged in
	media_identifier="Serial No: UGC"
	ports_with_unsupported_media=`correcthost_all_vfs /fabos/cliexec/sfpshow | grep "$media_identifier" | sed '/Slot[ ]*/s///g' | sed '/Port[ ]*/s///g' | cut -f1 -d ":"`
	ports_with_8G_smartoptics_sfp=`echo $ports_with_unsupported_media | sed '/ /s//,/g'`

	if [ "$ports_with_8G_smartoptics_sfp" = "" ]; then
		# There are no 8G SmartOptics plugged in
		return $STS_OK
	else
		$ECHO "8G SMARTOPTICS SFP exist on ports $ports_with_8G_smartoptics_sfp"
		UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR=$(eval echo "$UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR")
		BNA_UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR=$(eval echo "$BNA_UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR")
		# Explicit call to add_err_status since error strings were changed
		add_err_status "$UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR" "$BNA_UNSUPPORTED_8G_SFP_ON_DOWNGRADE_ERR"
		return $STS_ERR
	fi
}

check_sfp_16G_smartoptics()
{
	# This check is applicable only for Cassian and Rey
	# TODO - Confirm whether Rey blade is supported in Gen6 chassis (165 | 166)
	# Return Success for all other platforms

	rey_blade_id=216
	rey_blade_slots=""

	case ${SWBD##SWBD} in
	'181')
	    ;;
	'165' | '166' | '179' | '180')
		rey_blade_slots=$(correcthost /fabos/cliexec/slotshow -m 2>${NULL} | grep -w $rey_blade_id | awk '{print $1}')
		if [ "$rey_blade_slots" = "" ]; then
			# Rey blade is not present
			return $STS_OK
		fi
	    ;;
	*)
	    return $STS_OK
	    ;;
	esac

	# Get list of port which have 16G SmartOptics media plugged in
	media_identifier="Serial No: HFC"
	ports_with_unsupported_media=`correcthost_all_vfs /fabos/cliexec/sfpshow | grep "$media_identifier" | sed '/Slot[ ]*/s///g' | sed '/Port[ ]*/s///g' | cut -f1 -d ":"`

	# In case of chassis check if any 16G SmartOptics is present on Rey blade
	if [ "$SWBD" != "SWBD181" ]; then
		for port in $ports_with_unsupported_media
		do
			slot=`echo $port | sed '/\/.*/s///g'`
			# Check if this slot# corresponds to that of Rey blade
			echo $rey_blade_slots | grep -w $slot 1> ${NULL} 2>&1
			if [ $? -eq 1 ]; then
				continue
			fi
			if [ -z "$ports_with_16G_smartoptics_sfp" ]; then
				ports_with_16G_smartoptics_sfp=$port
			else
				ports_with_16G_smartoptics_sfp=$ports_with_16G_smartoptics_sfp,$port
			fi
		done
	else
		ports_with_16G_smartoptics_sfp=`echo $ports_with_unsupported_media | sed '/ /s//,/g'`
	fi

	if [ "$ports_with_16G_smartoptics_sfp" = "" ]; then
		# There are no 16G SmartOptics plugged in
		return $STS_OK
	else
		$ECHO "16G SMARTOPTICS SFP exist on ports $ports_with_16G_smartoptics_sfp"
		UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR=$(eval echo "$UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR")
		BNA_UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR=$(eval echo "$BNA_UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR")
		# Explicit call to add_err_status since error strings were changed
		add_err_status "$UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR" "$BNA_UNSUPPORTED_16G_SFP_ON_UPGRADE_ERR"
		return $STS_ERR
	fi
}

# Returns an error if 64G SFP is plugged in
check_sfp_64G()
{
	# Get list of port which have 64G media plugged in
	media_identifier="64_Gbps"
	ports_with_unsupported_media=`correcthost_all_vfs /fabos/cliexec/sfpshow | grep "$media_identifier" | grep -v GE | sed '/Slot[ ]*/s///g' | sed '/Port[ ]*/s///g' | cut -f1 -d ":"`
	ports_with_64G_sfp=`echo $ports_with_unsupported_media | sed '/ /s//,/g'`

	if [ "$ports_with_64G_sfp" = "" ]; then
		# There are no 64G media plugged in
		return $STS_OK
	else
		$ECHO "64G SFP exist on ports $ports_with_64G_sfp"
		UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR=$(eval echo "$UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR")
		BNA_UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR=$(eval echo "$BNA_UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR")
		# Explicit call to add_err_status since error strings were changed
		add_err_status "$UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR" "$BNA_UNSUPPORTED_64G_SFP_ON_DOWNGRADE_ERR"
		return $STS_ERR
	fi
}

#
#Block firmware upgrade from 9.0.0/9.0.0x to higher version if there is any ICL EX-port on non-VF switches
#has been configured on the GEN6+/GEN7 chassis.
#Core blade port index range of GEN6+/GEN7 4 slot chassis - 384 to 447
#Core blade port index range of GEN6+/GEN7 8 slot chassis - 768 to 895
#
check_ex_ports_ICL_configured()
{
	EX_port_configured=0
	slot_count=0
	slot_show_count=0

	case ${SWBD##SWBD} in
	'179' | '180')
		if [ $VF_ENABLED -eq $STS_OK ]; then
			for EX_port_configured in `/fabos/bin/configshow -chassis | grep "xport" | grep "ENABLE" | cut -d '.' -f 3`
			do
			# As ICL port indexes for 4 and 8 slot chassis will be different, using the slot show count to determine the correct
			# port index range to block the EX-port on ICL in non-VF mode.
			# As slotshow word count will provide the header lines, 2 CP blades and 2 core blades in the output,
			# we are skipping them to determine the correct slot count for the chassis.
				slot_show_count=`/fabos/cliexec/slotshow -m | wc -l`
				slot_count=`expr $slot_show_count - 8`
				if [ "$slot_count" -eq "4" -a "$EX_port_configured" -ge "384" -a "$EX_port_configured" -le "447" ] || [ "$slot_show_count" -eq "8" -a "$EX_port_configured" -ge "768" -a "$EX_port_configured" -le "895" ]; then
					$ECHO "In non VF mode, EX_PORT is configured on ICL port $EX_port_configured in slot$slot_count chassis"
					ICL_EX_PORT_RESTRICTION_ON_NON_VF=$(eval echo "$ICL_EX_PORT_RESTRICTION_ON_NON_VF")
					BNA_ICL_EX_PORT_RESTRICTION_ON_NON_VF=$(eval echo "$BNA_ICL_EX_PORT_RESTRICTION_ON_NON_VF")
					add_err_status "$ICL_EX_PORT_RESTRICTION_ON_NON_VF" "$BNA_ICL_EX_PORT_RESTRICTION_ON_NON_VF"
					return $STS_ERR
				fi
			done
		fi
	esac
	return $STS_OK
}

# is_extn_hcl_platform()
#
# Return true if this an HCL capable extension platform
is_extn_hcl_platform()
{
	case ${SWBD##SWBD} in

	'165' | '166' | '179' | '180')
		return 1
		;;
	esac

	return 0
}

# extn_check_field()
#
# Check field parameter for invalid chars
extn_check_field()
{
	field=$@

	if [[ $field == *[';']* ]]; then
		return 1
	fi
}

# extn_check_binary_field()
#
# Check binary field parameter for invalid chars
extn_check_binary_field()
{
	field=$1
	out=""

	# get length of the string
	str_len=${#field}

	# sanity check for binary strings
	mod=$((str_len%2))
	if [ $mod -ne 0 ]; then
		return 0
	fi

	for ((i=0; i<$str_len; i+=2)); do
		out=$out`echo -e "\\x${field:$i:2}" | cat`
	done

	extn_check_field $out
	if [ $? -ne 0 ]; then
		return 1
	fi
}

# extn_check_psk_field()
#
# check portshow output for psk with semi-colons
extn_check_psk_field()
{
	obj_name=$1
	TMP_FILE=/tmp/extnipsec.txt

	echo "" > $TMP_FILE
	str_name=""
	for ((j=0; j<${#obj_name}; j+=2)); do
		str_name=$str_name`echo -e "\\x${obj_name:$j:2}" | cat`
	done

	if [ $CUR_MAJOR -gt 8 ]; then
		set_p=1
	elif [ $CUR_MAJOR -eq 8 -a $CUR_MINOR -ge 1 ]; then
		set_p=1
	else
		set_p=0
	fi

	if [ $set_p -eq 1 ]; then
		pstring="$str_name -d -p"
		correcthost_all_vfs /fabos/link_bin/portshow ipsec-policy ${pstring} >> $TMP_FILE
	else
		pstring="$str_name -d"
		correcthost_all_vfs /fabos/link_bin/portshow ipsec-policy ${pstring} >> $TMP_FILE
	fi

	data=`cat $TMP_FILE | grep Preshared-Key`

	pos=16
	limit=${#data}

	while [ "${data:$pos:1}" == " " ]; do
		if [ $pos -eq $limit ]; then
			break
		fi
		pos=$((pos+1))
	done

	extn_check_field ${data:$pos}
	if [ $? -ne 0 ]; then
		return 1
	fi
}

extn_print_obj_string()
{
	str_in=$1
	obj_type=$2
	field_type=$3
	field_name=$4
	out_str=""
	pos=0

	if [ "${str_in:0:7}" != "extnCfg" ]; then 
		return 1
	fi

	type_str=""
	if [ "$obj_type" == "SLA" ]; then
		type_str=$obj_type
		cmd_str="'portcfg sla <name>'"
	elif [ "$obj_type" == "SBTCL" ]; then
		type_str="TCL"
		cmd_str="'portcfg tcl <name>'"
	elif [ "$obj_type" == "SBLAG" ]; then
		echo "LAG TYPE FOUND!"
		type_str="LAG"
		cmd_str="'portcfg lag <name>'"
	elif [ "$obj_type" == "IPSECPOLICY" ]; then
		type_str="IPSec Policy"
		cmd_str="'portcfg ipsec-policy <name>'"
	elif [ "$obj_type" == "FILTERSET" ]; then
		type_str="Filter Set"
		cmd_str="'portcfg filter <name>'"
	elif [ "$obj_type" == "APPINFO" ]; then
		type_str="App-Type"
		cmd_str="'portcfg app-type <name>'"
	elif [ "$obj_type" == "SBTUNNEL" ]; then
		type_str="Tunnel"
		cmd_str="'portcfg fciptunnel <VE>'"
	fi

	# Check for name based objects and print an error
	if [[ "$obj_type" == "SLA" || "$obj_type" == "SBTCL" ||
			"$obj_type" == "IPSECPOLICY" || "$obj_type" == "FILTERSET" ||
			"$obj_type" == "APPINFO" ]]; then

		IFS=,
		for i in $str_in; do
			if [[ "${i:0:4}" == "name" || "${i:0:4}" == "Name" ]]; then

				if [ $field_type == "string" ]; then
					pstring=${i:5}
				elif [ $field_type == "binary" ]; then
					tmp=${i:5}
					pstring=""
					for ((j=0; j<${#tmp}; j+=2)); do
						pstring=$pstring`echo -e "\\x${tmp:$j:2}" | cat`
					done
				else
					echo "Error parsing string (${str_in:0:32}...)"
				fi

				# SEND ERROR OUTPUT STRING
				if [[ $pstring == *[';']* ]]; then
					out_str="$type_str $pstring has semi-colon(s) in its name. Please use $cmd_str to delete and recreate without any semi-colons."
				else
					out_str="$type_str $pstring has semi-colon(s) in its $field_name field. Please remove them using $cmd_str"
				fi
				echo $out_str >> $FCIP_STATUS_FILE
			fi
		done
		unset IFS

		# We do not need to continue from here
		return 0
	fi

	# ignore 'extnCfg.' and move on
	pos=8

	# get slot information
	regex_match=`echo "${str_in:$pos:2}" | sed -n '/^S[0-9]/p'`
	if [ "$regex_match" != "" ]; then
		slot_based=1
		pos=$((pos+1))
		slot=${str_in:$pos:1}

		# if the next char is a number we must append it to the slot
		pos=$((pos+1))
		if [ "${str_in:$pos:1}" != "." ]; then
			slot="$slot${str_in:$pos:1}"
			pos=$((pos+1))
		fi
		pos=$((pos+1))
	else
		slot=0
	fi

	if [ "$obj_type" == "SBTUNNEL" ]; then
		regex_match=`echo "${str_in:$pos:4}" | sed -n '/^VE[0-9][0-9]/p'`
		if [ "$regex_match" != "" ]; then
			pos=$((pos+2))
			ve_num=${str_in:$pos:2}
		fi

		# SEND ERROR OUTPUT STRING
		if [ $slot -ne 0 ]; then
			out_str="$type_str $slot/$ve_num has semi-colon(s) in its $field_name field. Please remove them all with $cmd_str."
		else
			out_str="$type_str $ve_num has semi-colon(s) in its $field_name field. Please remove them all with $cmd_str."
		fi
		echo $out_str >> $FCIP_STATUS_FILE
		return 0
	fi
}

extn_obj_char_check()
{
	input_str=$1
	obj_type=$2
	rc=0
	field_name=""
	obj_name=""
	check_psk=0
	psk_string=""
	LAG_NAME=""

	IFS=,
	for i in $input_str; do
		unset IFS

		# check lag name separately since its the very first field
		if [ "$obj_type" == "SBLAG" ]; then
			if [ "${i:18:4}" == "name" ]; then 
				field_name="name"
				extn_check_field ${i:23}
				if [ $? -ne 0 ]; then
					LAG_NAME=${i:23}
					rc=3
					break
				fi
			fi
			# need to handle varying prefix string lengths (ID values >= 10)
			if [ "${i:19:4}" == "name" ]; then 
				field_name="name"
				extn_check_field ${i:24}
				if [ $? -ne 0 ]; then
					LAG_NAME=${i:24}
					rc=3
					break
				fi
			fi
		fi

		# Check NAME
		if [ "${i:0:4}" == "name" ]; then 
			field_name="name"
			extn_check_field ${i:5}
			if [ $? -ne 0 ]; then
				rc=1
				break
			fi
			extn_check_binary_field ${i:5}
			if [ $? -ne 0 ]; then
				rc=2
				break
			fi
		fi
		# Check NAME
		if [ "${i:0:4}" == "Name" ]; then 
			field_name="name"
			tmp_str=${i:5}
			extn_check_field ${i:5}
			if [ $? -ne 0 ]; then
				rc=1
				break
			fi
			extn_check_binary_field ${i:5}
			if [ $? -ne 0 ]; then
				rc=2
				break
			fi
			# handle preshared key case for ipsec-policy
			if [ "$obj_type" == "IPSECPOLICY" ]; then
				field_name="preshared-key"
				extn_check_psk_field "$tmp_str"
				if [ $? -ne 0 ]; then
					rc=2
					break
				fi
			fi
		fi
		# Check DESCRIPTION
		if [ "${i:0:11}" == "description" ]; then 
			field_name="description"
			extn_check_field ${i:12}
			if [ $? -ne 0 ]; then
				rc=1
				break
			fi
			extn_check_binary_field ${i:12}
			if [ $? -ne 0 ]; then
				rc=2
				break
			fi
		fi
		IFS=,
	done
	unset IFS

	if [ $rc -eq 1 ]; then
		extn_print_obj_string "$input_str" "$obj_type" "string" "$field_name"
	elif [ $rc -eq 2 ]; then
		extn_print_obj_string "$input_str" "$obj_type" "binary" "$field_name"
	elif [ $rc -eq 3 ]; then
		out_str="LAG $LAG_NAME has semi-colon(s) in its name. Please use 'portcfg lag <name>'  to delete and recreate without any semi-colons."
		echo $out_str >> $FCIP_STATUS_FILE
	fi

	return $rc
}

#
# 7840/SX6
# Check HCL readiness of extension tunnels
# Does not actually return a failure. Will just print any messages and treat
# them as warnings. Then will use the normal FWDL prompt to confirm from the
# user if they want to proceed.
#
check_extn_hcl()
{
	if [ ! $ACTIVECP ] ; then
		return $STS_OK
	fi

	is_extn_hcl_platform
	if [ $? -ne 1 ]; then
		return $STS_OK
	fi

	allow_disruptive_single_mode_fwdl
	if [ $? -eq $STS_OK ]; then
		return $STS_OK
	fi

	# Only perform the HCL checks if doing a non-disruptive download on
	# active CP and extension blades/platorm is present. This command
	# only prints output if any warnings are found. Otherwise it will be
	# an empty string.
	HCL_TUNNEL_CHECK=`correcthost_to_curr_vfid /fabos/link_bin/portshow fciptunnel all --hcl-status --preinst`
	add_warn_status "$HCL_TUNNEL_CHECK"

	return $STS_OK
}

#
# check_extn_certs
#
# Check if extn related certificates are present in the switch.
# if present, we need to block downgrade to v8.0 and/or below.
# This check can be removed after 8.3
#
check_extn_certs ()
{
	extn_cert_found=0
	ret=$STS_OK

	/fabos/cliexec/seccertmgmt show -csr extn 2>&1 | grep -e "No  *CSR  *found." -e "This is not supported in non-extension platforms" -e "command not found" > /dev/null 2>&1
	if [ $? -ne 0 ]; then
		ret=$STS_ERR
	fi
	/fabos/cliexec/seccertmgmt show -cert extn 2>&1 | grep -e "No  *CERT  *found." -e "This is not supported in non-extension platforms" -e "command not found" > /dev/null 2>&1
	if [ $? -ne 0 ]; then
		ret=$STS_ERR
	fi
	/fabos/cliexec/seccertmgmt show -ca extn 2>&1 | grep -e "No  *CA  *found." -e "This is not supported in non-extension platforms" -e "command not found" > /dev/null 2>&1
	if [ $? -ne 0 ]; then
		ret=$STS_ERR
	fi
	return $ret
}

check_extn_certs_name()
{
	ROOT_DIR=/etc/fabos
	EXTN_DIR=$ROOT_DIR/certs/extn

	is_extn_platform
	if [ $? -eq 1 ]; then

		if [ ! -d "$EXTN_DIR" ]; then
			return $STS_OK
		fi

		for file in $EXTN_DIR/*.csr $EXTN_DIR/*.pvt_key $EXTN_DIR/*.pem $EXTN_DIR/*.hash $EXTN_DIR/*.crt $EXTN_DIR/*.cer $EXTN_DIR/*.psk; do
			[ -f "$file" ] || continue
			filename=${file##*/}
			echo "${filename%.*}" | grep -v "[^a-zA-Z0-9~@%_+:.-]" > /dev/null 2>&1
			if [ ! $? -eq 0 ]; then
				return $STS_ERR	
			fi
		done
	fi

	return $STS_OK
}			

check_extn_chars()
{
	CHAR_TMP_FILE=/tmp/extnchars.txt

	is_extn_platform
	if [ $? -eq 1 ]; then

	# Fixed invalid characters in v8.1.2. If upgradeing from pre v8.1.2 to v8.1.2+
	# perform checks to ensure strings are ok
	if [ ${TO_MAJOR} -gt 8 ] || [ ${TO_MAJOR} -eq 8 -a ${TO_MINOR} -gt 1 ] || [ ${TO_MAJOR} -eq 8 -a ${TO_MINOR} -eq 1 -a ${TO_PATCH} -ge 2 ]; then
	if [ ${ACTIVE_MAJOR} -lt 8 ] || [ ${ACTIVE_MAJOR} -eq 8 -a ${ACTIVE_MINOR} -lt 1 ] || [ ${ACTIVE_MAJOR} -eq 8 -a ${ACTIVE_MINOR} -eq 1 -a ${ACTIVE_PATCH} -lt 2 ]; then

	CONFIGSHOW -all | grep "^extnCfg" > $CHAR_TMP_FILE
	ALL_ENTRIES=`cat $CHAR_TMP_FILE`

	# Loop on respective entry type and call handler
	# to check for invalid chars and to throw an error
	# if necessary

	# Check Tunnels
	echo "$ALL_ENTRIES" | grep SBTUNNEL | while read line; do
		extn_obj_char_check "$line" "SBTUNNEL"
	done
	# Check SLA
	echo "$ALL_ENTRIES" | grep SLA | while read line; do
		extn_obj_char_check "$line" "SLA"
	done
	# Check LAG
	echo "$ALL_ENTRIES" | grep SBLAG | while read line; do
		extn_obj_char_check "$line" "SBLAG"
	done
	# Check IpSec Policies
	echo "$ALL_ENTRIES" | grep IPSECPOLICY | while read line; do
		extn_obj_char_check "$line" "IPSECPOLICY"
	done
	# Check TCLs
	echo "$ALL_ENTRIES" | grep SBTCL | while read line; do
		extn_obj_char_check "$line" "SBTCL"
	done
	# Check filterset 
	echo "$ALL_ENTRIES" | grep FILTERSET | while read line; do
		extn_obj_char_check "$line" "FILTERSET"
	done
	# Check app-types
	echo "$ALL_ENTRIES" | grep APPINFO | while read line; do
		extn_obj_char_check "$line" "APPINFO"
	done

	fi
	fi
	fi
}

#
# 7840/SX6
# Check TCL limit to see if per-DP limit is exceeded. Fixed in FOS-802403, so we
# need to prevent upgrade if per-DP limit is currently exceeded.
#
check_extn_tcl_limit()
{
	is_extn_platform
	if [ $? -eq 1 ]; then

		# Only perform TCL check when upgrading to v8.2.1 from prior version
		if [ ${TO_MAJOR} -gt 8 ] || [ ${TO_MAJOR} -eq 8 -a ${TO_MINOR} -gt 2 ] || [ ${TO_MAJOR} -eq 8 -a ${TO_MINOR} -eq 2 -a ${TO_PATCH} -ge 1 ]; then
		if [ ${ACTIVE_MAJOR} -lt 8 ] || [ ${ACTIVE_MAJOR} -eq 8 -a ${ACTIVE_MINOR} -lt 2 ] || [ ${ACTIVE_MAJOR} -eq 8 -a ${ACTIVE_MINOR} -eq 2 -a ${ACTIVE_PATCH} -lt 1 ]; then
			# For some reason, the configs can show up in both the default LS and
			# the chassis configDB. So first we need to sort them and get all unique
			# entries, then we can extract the info we need to count the totals
			PER_DP_TCLS=`CONFIGSHOW -all | grep extnCfg.SBTCL | grep AdminStatus=1 | sort | uniq | sed -e 's/.*Dp=\([0-9]*\),.*/\1/' | sort -n | uniq -c | awk '{print $1}' | sort -n | tail -n 1`
			ALL_DP_TCLS=`CONFIGSHOW -all | grep extnCfg.SBTCL | grep AdminStatus=1 | sort | uniq | grep Action=1 | grep Dp=4294967295 | wc -l`
			#echo "PER_DP:$PER_DP_TCLS"
			#echo "ALL_DP:$ALL_DP_TCLS"
			#echo "TOTAL:$(( PER_DP_TCLS + ALL_DP_TCLS ))"
			if [ $(( PER_DP_TCLS + ALL_DP_TCLS )) -gt 128 ]; then
				echo "There are more than 128 TCLs configured and enabled on at least one DP. Unable to upgrade. Please disable or remove TCLs to be under the per-DP limit of 128 enabled TCLs using the 'portcfg tcl <name> modify --admin-status disable' or the 'portcfg tcl <name> delete' command." >> $FCIP_STATUS_FILE
			fi
		fi
		fi
	fi
}

#
# Check if any extension restrictions are exceeded.
#
check_extn_features()
{
    ret=$STS_OK

	extn_fwdl_new_validate=0

	if [ $VF_ENABLED -ne $STS_OK ]; then
		# VF is enabled
		if [ $ACTIVECP ] ; then
			extn_fwdl_new_validate=`grep -c "EXTN_FWDL_NEW_VALIDATE" $CHECK_FEATURES_FILE`
		fi
	fi

	is_extn_platform
	if [ $? -eq 1 ]; then

	if [ "$extn_fwdl_new_validate" = "0" ]; then
		correcthost_def_vf /fabos/link_bin/portShow fciptunnel all --validate ${TO_MAJOR}.${TO_MINOR}.${TO_PATCH} > $FCIP_STATUS_FILE
	else
		correcthost_def_vf /fabos/sbin/extnCfg --validate -version ${TO_MAJOR}.${TO_MINOR}.${TO_PATCH} > $FCIP_STATUS_FILE
	fi

	check_extn_chars

	check_extn_tcl_limit

	err_output=`wc -l $FCIP_STATUS_FILE | awk '{ print $1 }'`

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

		ret=$STS_ERR
		cat $FCIP_STATUS_FILE >> $STATUS_FILE
		cat $FCIP_STATUS_FILE >> $BNA_STATUS_FILE
	fi
	fi

	rm $FCIP_STATUS_FILE >/dev/null 2>&1
    return $ret
}

# FX8-24, 7840, SX6
# Prep systems for FWDL to specified version
#
prep_extn_features()
{
	if [ ! -f $CHECK_FEATURES_FILE ]; then
		# no check features file
		return $STS_OK
	fi

	extn_fwdl_prep_supported=`grep -c "EXTN_FWDL_PREP_SUPPORTED" $CHECK_FEATURES_FILE`
	if [ "$extn_fwdl_prep_supported" = "0" ]; then
		# fwdl_prep command not supported
		return $STS_OK
	fi

	# v8.1.0+ prep systems for FWDL
	is_extn_platform
	if [ $? -eq 1 ]; then
		if [ $ACTIVE_MAJOR -gt 8 ] || [ $ACTIVE_MAJOR -ge 8 -a $ACTIVE_MINOR -ge 1 ]; then
			correcthost_to_curr_vfid /fabos/link_sbin/extncfg --fwdl-prep --version ${TO_MAJOR}.${TO_MINOR}.${TO_PATCH} --preinst
		fi
	fi

	return $STS_OK
}

# FX8-24, 7840, SX6
# [Abort] Prep systems for FWDL to specified version
#
prep_extn_features_abort()
{
	if [ ! -f $CHECK_FEATURES_FILE ]; then
		# no check features file
		return $STS_OK
	fi

	extn_fwdl_prep_supported=`grep -c "EXTN_FWDL_PREP_SUPPORTED" $CHECK_FEATURES_FILE`
	if [ "$extn_fwdl_prep_supported" = "0" ]; then
		# fwdl_prep command not supported
		return $STS_OK
	fi

	# v8.2.0+ ABORT prep systems operations for FWDL
	if [ $ACTIVE_MAJOR -gt 8 ] || [ $ACTIVE_MAJOR -ge 8 -a $ACTIVE_MINOR -ge 2 ]; then

		is_extn_platform
		if [ $? -eq 1 ]; then

			correcthost_to_curr_vfid /fabos/link_sbin/extncfg --fwdl-prep --version ${TO_MAJOR}.${TO_MINOR}.${TO_PATCH} --preinst --abort
		fi
	fi

	return $STS_OK
}


convert_hex2ascii()
{
	str=`echo $1 | tr -d \\x`
	pos=1
	len=$(( ${#str} + 1 ))

	while [ $pos -lt $len ]
	do
    	    hex='\x'`echo $str | cut -c $pos-$(( pos + 1 ))`
	        strhex=$strhex$hex
	        pos=$(( pos + 2 ))
	done
	echo -e $strhex
}


#
# check_hcl_switchstate
#
# Check the switchState if it is Faulty to block HCL
#
check_hcl_switchstate()
{
	hashow_cmd="/fabos/bin/hashow"

	case "$($hashow_cmd | ( read a; echo $a ))" in
		*"Not supported"*)
		;;
		*)
		return $STS_OK
		;;
	esac

	switch_state=`/fabos/bin/switchshow | sed -n -e 's/switchState://gp' | tr -d '\t'`
	switch_state=`echo $switch_state  | sed $'s/[ \t]//g'`

	if [ "$switch_state" == "Faulty" ]; then
		is_fwdl_arg "s"
		if [ $? -ne 0 ]; then
			return $STS_ERR
		fi
	fi

	return $STS_OK

}


#
# maps_enabled_check
#
# Check whether the switch is currently in auto csctl mode
#
maps_enabled_check() {
 # on active cp we need diffrent command than the stand by. dont know the reason why?
	ret=`CONFIGSHOW -chassis | grep maps.migrated:1 |wc -l`
	# need to truncate all the leading blank characters 
	last=`echo $ret | tr -d ' '`
	# ret will have command plus the result so we just need result. result will be 
	# either zero or 1 so we just need last character from the end
	last=${ret: -1:1}
	# this is check for debugging 
	#if  [ $last -eq 1 ]; then
	#echo "1: maps is enabled $last"
    #else
	#echo "1: maps is disabled $last"
    #fi
    # return the status
    return $last
}


# check if there is decom action configured in any logical switch.
# If decom is present, the firmwaredownload should not be allowed.

check_for_maps_action_config()
{
	actions=''
	action_bitmask=$1
	maps_enabled_check
	if [ $? -le 0 ]; then
		return $STS_OK
	fi
	
	CONFIGSHOW_ADV > xxx

	actions=`cat xxx |grep '^maps\.actions:' 2> /tmp/.fwdl_mapsconfig_out.txt`
	ret=$?
	if [ $ret -eq 0 ]; then
		actions=`echo $actions| cut -f2 -d":"`
	else
		return $STS_OK
	fi
	let ret="$actions & $action_bitmask"
	if [ $ret -ne 0 ]; then
	    return $STS_ERR
	fi

	rm -f /tmp/.fwdl_mapsconfig_out.txt
	return $STS_OK
}

# check if user defined rules have decom action.
# If so, the firmwaredownload should not be allowed.


# check if user defined rules have decom action.
# If so, the firmwaredownload should not be allowed.

check_for_actions_present_in_maps_rules_cfg()
{
    actionStr=$1
    maps_enabled_check
    if [ $? -le 0 ]; then
	return $STS_OK
    fi
    CONFIGSHOW > /tmp/.fwdl_configshow_out1.txt
    # get the list of rule names.
    awk '/^maps\.rule\./' /tmp/.fwdl_configshow_out1.txt >/tmp/.fwdl_configshow2.txt

    if [ ! -f "/tmp/.fwdl_configshow2.txt" ]; then
	return $STS_OK
    fi
    if [ ! -s "/tmp/.fwdl_configshow2.txt" ]; then
	return $STS_OK
    fi
    rule_check_failed=0
    echo $rule_check_failed > /tmp/.fwdl_decom_rule_err.txt
    cat /tmp/.fwdl_configshow2.txt|
    while read line
    do
      action_list=`echo $line| cut -f2 -d" "`
      echo $action_list | grep -i $actionStr > /dev/null
      if [ $? -eq 1 ]; then
	continue
      fi
      rule_check_failed=1
      echo $rule_check_failed > /tmp/.fwdl_decom_rule_err.txt
    done

    check_return_val=`cat /tmp/.fwdl_decom_rule_err.txt`
    rm -f /tmp/.fwdl_*.txt
    if [ $check_return_val -eq 1 ]; then
	return $STS_ERR
    else
	return $STS_OK
    fi
}

warnTokenList=""

# check one token or MAPS feature in the configuration if it is present then 
# add that token in the tokenList
# Arguments to this function as follows - 
# token, FOS version, configuration Buffer
check_maps_one_810_feature_to_give_warning() {
	result=""
	listOfTokens=""
	ret=$STS_OK
	configBuffer=`CONFIGSHOW`
	token=$1
	version=$2
	warningDisplayed=0
	result=`echo $configBuffer | grep $token`

    if [ -n "$result" ]
    then
        if [ $token == "qt=" ]
        then
           token="Quiet time"
		fi
		if [ $token == "severity=" ]
        then
           token="Severity"
        fi
        if [ -n "$listOfTokens" ]
        then
           listOfTokens="$token, $listOfTokens"
        else
           listOfTokens="$token"
        fi
    fi
    if [ -n "$listOfTokens" ]
    then
        let "warningDisplayed=warningDisplayed+1"
        if [ $warningDisplayed -eq 1 ]
        then
			if [ ! -f "/tmp/.warningDisplayed_810" ]
			then
              warnStr="MAPS user defined rules for $token will not be monitored in pre-FOS $version. Please delete these rules from FID: $glb_vf_id"
			  touch /tmp/.warningDisplayed_810
			else
			  warnStr=" ,$glb_vf_id"
			fi
        fi
        if [ $warningDisplayed -ge 1 ]
           then
           echo -n $warnStr >> ${MAPS_WARN_FILE}
        fi
    fi
    return $ret
}

check_maps_ror_length_to_block() {

	CONFIGSHOW > /tmp/x1

	# The maximum rule name len in 8.0.1 is 40 and maps.rule. takes 10 chars.
	# So if length is 50 or more, block the firmware. 
	awk '{FS=":"} {print $1}' /tmp/x1 | grep "maps\.rule\." > /tmp/x2
	file="/tmp/x2"
	while read line
	do
		rule_name_key="$line"
		rule_name_key_len=${#rule_name_key}
		if [ -n "$rule_name_key_len" ]
		then
			if [ $rule_name_key_len -gt 50 ]
			then
				return $STS_ERR
			fi
		fi
	done < $file
	return $STS_OK
}

check_821_maps_re_imbalance_present()
{
	funcArgs="1048576"
	check_for_maps_action_config $funcArgs
	if [ $? -eq $STS_ERR ]
	then
	    warnStr="$MAPS_RE_BALANCE_CONFIG_ERR$glb_vf_id"
	   
	    echo $warnStr >> ${MAPS_WARN_FILE}
	fi
	return $STS_OK
}


check_821_maps_rule_length_check()
{
	ruleTh=`/fabos/cliexec/configshow -a | grep -i "maps.rule\." | cut  -d '/' -f2 | cut -d ')' -f1 | tr ">" " " | tr "<" " " | tr "=" " " | tr -s " " | cut -d " " -f2`
	for i in $ruleTh; do
		len=`echo $i | wc -c`
		if [ $len -gt 17 ]; then
			return $STS_ERR
		fi
	done
	return $STS_OK
}

check_maps_marg_sfps_rule() {

	# If there are any user defined rules with MARG_SFPS MS, then we need to warn the user as
	# it is not supported in pre-9.0.0 releases.
	buf=`CONFIGSHOW_ADV | grep "maps.rule" | grep -i "MARG_SFPS"`
	if [ ! -z "$buf" ]
	then
		if [ -f $MAPS_WARN_VFID_FILE ]
		then
			# if entry is already present, then start with comma
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		fi
	fi
}

check_maps_fel_exp_rule() {

	# If there are any user defined rules with FEL_EXPIRED MS, then we need
	# to warn the user as it is not supported in pre-9.0.0 releases.
	buf=`CONFIGSHOW_ADV | grep "maps.rule" | grep -i "FEL_EXPIRED"`
	if [ ! -z "$buf" ]
	then
		if [ -f $MAPS_WARN_VFID_FILE ]
		then
			# if entry is already present, then start with comma
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		fi
	fi
}

check_maps_fel_not_installed_rule() {

	# If there are any user defined rules with FEL_NOT_INSTALLED MS,then we need
	# to warn the user as it is not supported in pre-9.0.0 releases.
	buf=`CONFIGSHOW_ADV | grep "maps.rule" | grep -i "FEL_NOT_INSTALLED"`
	if [ ! -z "$buf" ]
	then
		if [ -f $MAPS_WARN_VFID_FILE ]
		then
			# if entry is already present, then start with comma
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		fi
	fi
}

check_maps_fen_decom_act_in_dev_latency_rule_cfg() {

	# Check if any user defined rule for MS DEV_LATENCY_IMPACT is
	# configured with FENCE/DECOM actions.
	buf=`CONFIGSHOW_ADV | grep "maps.rule" | grep -iwE "dev_latency_impact" | grep -iwE "fence|decom"`
	if [ ! -z "$buf" ]
	then
		if [ -f $MAPS_WARN_VFID_FILE ]
		then
			# if entry is already present, then start with comma
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		fi
	fi
}

check_maps_fen_decom_act_in_txp_rxp_rule_cfg() {

	# Check if any user defined rule for MS TXP/RXP is configured with
	# FENCE/DECOM actions.
	buf=`CONFIGSHOW_ADV | grep "maps.rule" | grep -iwE "txp|rxp" | grep -iwE "fence|decom"`
	if [ ! -z "$buf" ]
	then
		if [ -f $MAPS_WARN_VFID_FILE ]
		then
			# if entry is already present, then start with comma
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		fi
	fi
}

check_maps_fel_days_to_exp_rule() {

	# If there are any user defined rules with FEL_DAYS_TO_EXPIRE MS,then we
	# need to warn the user as it is not supported in pre-9.0.0 releases.
	buf=`CONFIGSHOW_ADV | grep "maps.rule" | grep -i "FEL_DAYS_TO_EXPIRE"`
	if [ ! -z "$buf" ]
	then
		if [ -f $MAPS_WARN_VFID_FILE ]
		then
			# if entry is already present, then start with comma
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		fi
	fi
}

check_maps_asc_upload_failure_rule() {

       # If there are any user defined rules with ASC_UPLOAD_FAILURE MS, then we need to warn the user as
       # it is not supported in pre-9.0.1 releases.
       buf=`CONFIGSHOW_ADV | grep "maps.rule" | grep -i "ASC_UPLOAD_FAILURE"`
       if [ ! -z "$buf" ]
       then
               if [ -f $MAPS_WARN_VFID_FILE ]
               then
                       # if entry is already present, then start with comma
                       echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
               else
                       echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
               fi
       fi
}

#This function will check if QT is configured for FRU MS in custom rules.
#if QT is configured for custom rules for specific FRU MS, then print a warning message.
#this function gets called while migrating from FOS9.0.x release to FOS9.1.0 and above.
check_maps_qt_configured_for_fru() {
    bnaErr=0
    rm -f ${MAPS_WARN_FILE}

    if [ $VF_ENABLED -ne $STS_OK ]; then
        if [ $ACTIVECP ] ; then
            for_all_contexts check_maps_all_fru_rules_for_qt_configured
        else
            for_all_contexts_standby check_maps_all_fru_rules_for_qt_configured
        fi
    else
        check_maps_all_fru_rules_for_qt_configured
    fi

    if [ -f "${MAPS_WARN_FILE}" ]
    then
	BNA_ERR=`cat ${MAPS_WARN_FILE}`
        rm ${MAPS_WARN_FILE}
        bnaErr=1
    fi

    if [ $bnaErr -ne 0 ]
    then
        add_warn_status "$BNA_ERR"
    fi
}

check_pre910_maps_nodewwn_dyn_grp_in_ag_mode() {

       # Dynamic group based on nodewwn is no more supported in AG mode in 9.1.0 so warn the users while
       # firmware is downgraded to pre-9.1.0 releases.
       ag_mode_enabled
       if [ $? -eq 0 ]
       then
               return $STS_OK
       fi

       buf=`CONFIGSHOW_ADV | grep "maps.group.feature" | grep -i "3 3"`
       if [ ! -z "$buf" ]
       then
               if [ -f $MAPS_WARN_VFID_FILE ]
               then
                       # if entry is already present, then start with comma
                       echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
               else
                       echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
               fi
       fi
}

check_maps_global_qt_config() {

	for qt in `CONFIGSHOW_ADV | grep "maps.config.quietTime" | cut -d ':' -f 2`
	do
		# If Global Quiet Time is Configured in any LS we need to warn the user
		if [ $qt -gt 0 ]
		then
			if [ -f $MAPS_WARN_VFID_FILE ]
			then
				# if entry is already present, then start with comma
				echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
			else
				echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
			fi
		fi
	done
}

check_warning_for_maps_pause() {

	buf=`CONFIGSHOW_ADV | grep "maps.group.pauselist" | grep -i "all"`
	if [ ! -z "$buf" ]
	then
		warnStr="WARNING: Either Switch or Complete group paused in FID:$glb_vf_id. It is not supported in pre FOS9.0.0 release "
		if [ -f $MAPS_WARN_VFID_FILE ]
		then
			# if entry is already present, then start with comma
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		fi
	fi
}

# function to check MAPS FPI profile feature ud configuration
check_maps_fpi_profile () {

	for p in `CONFIGSHOW_ADV | grep "maps.fpiactive." | cut -d':' -f 2`
	do

		# if custom profile is enabled on atleast one port type
		# then need to warn user
		if [ "$p" != "dflt_fpi_profile" ]; then

			if [ -f $MAPS_WARN_VFID_FILE ]; then
				# if entry is already present, then start with comma
				echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
			else
				echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
			fi
			return $STS_OK
		fi
	done
}

# function to check 9.0 supported SFP groups are present which are not valid in older releases
check_maps_90_sfp_grps() {

	# any custom rules on these groups are NOT supported in pre FOS9.0 releases
	udcfg=`CONFIGSHOW_ADV | grep "maps\.rule\." | grep -Ei 'ALL_40Km_16GELWL_SFP|ALL_40Km_32GELWL_SFP|ALL_GEN7SWL_QSFP'`

	if [ ! -z "$udcfg" ]
	then
		echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
	fi

	return $STS_OK
}

# function to check 9.0.1 supported SFP groups are present which are not valid in older releases
maps_901_sfp_mon() {

	# any custom rules on these groups are NOT supported in pre FOS9.0 releases
	udcfg=`CONFIGSHOW_ADV | grep "maps\.rule\." | grep -Ei 'ALL_64GSWL_SFP|ALL_80Km_8GELWL_SFP'`

	if [ ! -z "$udcfg" ]
	then
		echo -n " $glb_vf_id" >> $MAPS_WARN_VFID_FILE
	fi

	return $STS_OK
}

# generic function to execute either in VF enabled
# active/standby CP's or in a pizza box context
check_maps_features_vf() {

	/bin/rm -f $MAPS_WARN_VFID_FILE

	if [ $# -ne 4 ]
	then
		echo -e "Error: check_maps_features_vf called with unexpected arguments"
		return $STS_ERR
	fi

	fos_msg=$2
	bna_msg=$3
	opcode=$4
	DEF_FID=128
	maps_vfid=""

	if [ $VF_ENABLED -ne $STS_OK ]; then
		if [ $ACTIVECP ] ; then
			for_all_contexts $1
		else
			for_all_contexts_standby $1
		fi
	else
		$@
	fi
	if [ -f $MAPS_WARN_VFID_FILE ]; then

		maps_vfid=`cat $MAPS_WARN_VFID_FILE`
	fi

	/bin/rm -f $MAPS_WARN_VFID_FILE

	# if error/warning is present then display
	if [ ! -z "$maps_vfid" ]; then
		if [ "$opcode" == "$MAPS_OPC_WARN" ]
		then
			add_warn_status "$fos_msg$maps_vfid" "$bna_msg$maps_vfid"
			return $STS_OK
		else
			add_err_status "$fos_msg$maps_vfid" "$bna_msg$maps_vfid"
			return $STS_ERR
		fi
	fi

	return $STS_OK
}

check_ldap_gc_configured() {
	CUT=`/usr/bin/which cut`
	GREP=`/usr/bin/which grep`
	# If GC port 3268 configured, warn that GC will not work after downgrade
	portlist=`/fabos/cliexec/configshow -c | $GREP "ldap" | $GREP "port" | $CUT -d ":" -f 2` 
	for i in $portlist; do 
			if [ $i -eq 3268 ]; then
				add_warn_status "$LDAP_GC_CONFIGURED_WARN_MSG" "$BNA_LDAP_GC_CONFIGURED_WARN_MSG"
				break
			fi
		done
}

check_ldaps_configured() {
	CUT=`/usr/bin/which cut`
	GREP=`/usr/bin/which grep`
	# If LDAPS mode configured, warn that LDAP authentication will not work after downgrade
	ldap_tls_mode_list=`/fabos/cliexec/configshow -c | $GREP "ldap" | $GREP "tlsMode" | $CUT -d ":" -f 2` 
	for i in $ldap_tls_mode_list; do 
			if [ $i -eq 1 ]; then
				add_warn_status "$LDAPS_CONFIGURED_WARN_MSG" "$BNA_LDAPS_CONFIGURED_WARN_MSG"
				break
			fi
		done
}

check_ntp_legacy_mode() {
	CUT=`/usr/bin/which cut`
	GREP=`/usr/bin/which grep`
	CAT=`/usr/bin/which cat`

	# Block downgrade if legacy mode is disabled
	legacy_mode=`/fabos/cliexec/configshow | $GREP "ts.clockServerLegacyMode" | $CUT -d ":" -f 2` 
	if [ $legacy_mode -eq 0 ]; then
		add_err_status "$NTP_LEGACY_MODE_DISABLED" "$BNA_NTP_LEGACY_MODE_DISABLED"
		return $STS_ERR
	fi	

	return $STS_OK
}

check_ntp_auth_configured() {
	CUT=`/usr/bin/which cut`
	GREP=`/usr/bin/which grep`
	CAT=`/usr/bin/which cat`
	config_found=0

	# If NTP authentication is configured or server key indexes configured, 
	# warn that NTP authentication will not work after downgrade
	for ntp_key_indexes in `CONFIGSHOW -all | $GREP "ts.clockServerIndexList" | $CUT -d: -f2`;
	do
		IFS=';' 
		for key_index in $ntp_key_indexes;
		do	
			if [ "$key_index" != "-1" ]; then
				config_found=1
				break 
			fi		
		done
		unset IFS
	done
			
	for ntp_authspec_mode in `CONFIGSHOW -all | $GREP "ts.clockServerAuthSpec" | $CUT -d: -f2`;
	do
		if [ $ntp_authspec_mode -eq 1 ]; then
			config_found=1
		fi
	done

	if [ $config_found -eq 1 ]; then
		add_warn_status "$NTP_AUTHENTICATION_CONFIGURED_WARN_MSG" "$BNA_NTP_AUTHENTICATION_CONFIGURED_WARN_MSG"
	fi

	return $STS_OK
}

check_ipfilter_forward_rules() {

	fwd_rule_present=$(correcthost_to_curr_vfid /fabos/abin/ipfilter --show -a | grep -wc " FWD " 2>/dev/null)
	if [ $fwd_rule_present -gt 0 ]; then
		return $STS_ERR
	fi

	return $STS_OK
}
check_pre_v9_0_ciphers() {

	#***** Handle TLS ciphers

	cipher_list_not_supported_v9_0=( "DH-DSS-AES256-GCM-SHA384:0x00,0xA5" "DH-RSA-AES256-GCM-SHA384:0x00,0xA1" "DH-RSA-AES256-SHA256:0x00,0x69" "DH-DSS-AES256-SHA256:0x00,0x68" "DH-RSA-AES256-SHA:0x00,0x37" "DH-DSS-AES256-SHA:0x00,0x36" "DH-RSA-CAMELLIA256-SHA:0x00,0x86" "DH-DSS-CAMELLIA256-SHA:0x00,0x85" "AECDH-AES256-SHA:0xC0,0x19" "ADH-AES256-GCM-SHA384:0x00,0xA7" "ADH-AES256-SHA256:0x00,0x6D" "ADH-AES256-SHA:0x00,0x3A" "ADH-CAMELLIA256-SHA:0x00,0x89" "ECDH-RSA-AES256-GCM-SHA384:0xC0,0x32" "ECDH-ECDSA-AES256-GCM-SHA384:0xC0,0x2E" "ECDH-RSA-AES256-SHA384:0xC0,0x2A" "ECDH-ECDSA-AES256-SHA384:0xC0,0x26" "ECDH-RSA-AES256-SHA:0xC0,0x0F" "ECDH-ECDSA-AES256-SHA:0xC0,0x05" "DH-DSS-AES128-GCM-SHA256:0x00,0xA4" "DH-RSA-AES128-GCM-SHA256:0x00,0xA0" "DH-RSA-AES128-SHA256:0x00,0x3F" "DH-DSS-AES128-SHA256:0x00,0x3E" "DH-RSA-AES128-SHA:0x00,0x31" "DH-DSS-AES128-SHA:0x00,0x30" "DH-RSA-SEED-SHA:0x00,0x98" "DH-DSS-SEED-SHA:0x00,0x97" "DH-RSA-CAMELLIA128-SHA:0x00,0x43" "DH-DSS-CAMELLIA128-SHA:0x00,0x42" "AECDH-AES128-SHA:0xC0,0x18" "ADH-AES128-GCM-SHA256:0x00,0xA6" "ADH-AES128-SHA256:0x00,0x6C" "ADH-AES128-SHA:0x00,0x34" "ADH-SEED-SHA:0x00,0x9B" "ADH-CAMELLIA128-SHA:0x00,0x46" "ECDH-RSA-AES128-GCM-SHA256:0xC0,0x31" "ECDH-ECDSA-AES128-GCM-SHA256:0xC0,0x2D" "ECDH-RSA-AES128-SHA256:0xC0,0x29" "ECDH-ECDSA-AES128-SHA256:0xC0,0x25" "ECDH-RSA-AES128-SHA:0xC0,0x0E" "ECDH-ECDSA-AES128-SHA:0xC0,0x04" "AECDH-RC4-SHA:0xC0,0x16" "ADH-RC4-MD5:0x00,0x18" "ECDH-RSA-RC4-SHA:0xC0,0x0C" "ECDH-ECDSA-RC4-SHA:0xC0,0x02" "DH-RSA-DES-CBC3-SHA:0x00,0x10" "DH-DSS-DES-CBC3-SHA:0x00,0x0D" "AECDH-DES-CBC3-SHA:0xC0,0x17" "ADH-DES-CBC3-SHA:0x00,0x1B" "ECDH-RSA-DES-CBC3-SHA:0xC0,0x0D" "ECDH-ECDSA-DES-CBC3-SHA:0xC0,0x03" )

	default_9_ciphers="ECDSA:ECDH:RSA:AES:3DES:!RSAPSK:!DHEPSK:!PSK:!DSS:!AESCCM8:!AESCCM:!ARIAGCM:!CAMELLIA:!CHACHA20:!SEED:!RC4"
	default_9_strong_ciphers="ECDSA:ECDH:RSA:AES:3DES:!RSAPSK:!DHEPSK:!PSK:!DSS:!AESCCM8:!AESCCM:!ARIAGCM:!CAMELLIA:!CHACHA20:!SEED:!RC4:!AEAD:!SHA1:!AESGCM"

	### Validate ciphers for each application
	
	apps=("ldap" "https" "radius" "syslog")
	IFS_=${IFS}
	for i in "${apps[@]}"
	do
		cipher_string=`CONFIGSHOW -chassis | /bin/grep cipher.$i | /bin/sed -e "s/cipher.$i://g"`
		
		if [ "$default_9_ciphers" == "$cipher_string" ] || [ "$default_9_strong_ciphers" == "$cipher_string" ]; then
			continue
		fi

		cipher_configured=`/usr/bin/openssl ciphers "$cipher_string" 2>/dev/null`
		IFS=$':'
		for cipher in $cipher_configured;do
			cipher_hex_value=`/usr/bin/openssl ciphers -V "$cipher" 2>/dev/null | /bin/awk '{print $1}'`
			for key_value in "${cipher_list_not_supported_v9_0[@]}" ; do
				if [ "${key_value##*:}" == "$cipher_hex_value" ]; then
			
					app_name=`/bin/echo $i | /bin/awk '{print toupper($0)}'`
					if [ -z $cipher_block ]; then
						cipher_block="$app_name"
					else
						cipher_block="$cipher_block $app_name"
					fi
					break 2
				fi
			done 	
		done
	done
	IFS=${IFS_}

	if [ ! -z "$cipher_block" ]; then
		add_err_status "Configured cryptographic ciphers are not supported in target FOS version for $cipher_block. Please change the cipher configuration to default using command \"seccryptocfg --apply default_generic\". Refer to FOS administration guide to choose cipher(s) supported in the target version for a custom template and apply those configurations using \"secCryptoCfg --apply <template>\"."
		return $STS_ERR
	fi

	return $STS_OK
}


check_910_maps_features_for_blocking() {

	ret=$STS_OK

	$ECHO "check_910_maps_features_for_blocking"

	# Block downgrade if user defined rules for MS DEV_LATENCY is configured with FENCE/DECOM actions
	check_maps_features_vf check_maps_fen_decom_act_in_dev_latency_rule_cfg "$MAPS_FENCE_ACT_DEV_LATENCY_ERROR" "$BNA_MAPS_FENCE_ACT_DEV_LATENCY_ERROR" "$MAPS_OPC_ERR"

	ret=$?
	if [ $ret -eq $STS_ERR ]
	then
		return $ret
	fi

	return $ret
}

# MAPS
# Generic function for checking MAPS feautre during downgrade to 9.0.0 and below
check_901_blocking_maps_features() {

	ret=$STS_OK

	$ECHO "check_901_blocking_maps_features"

	# Block downgrade if user defined rules for MS TXP/RXP is configured with FENCE/DECOM actions
	check_maps_features_vf check_maps_fen_decom_act_in_txp_rxp_rule_cfg "$MAPS_FENCE_ACT_TXP_RXP_ERROR" "$BNA_MAPS_FENCE_ACT_TXP_RXP_ERROR" "$MAPS_OPC_ERR"

	ret=$?
	if [ $ret -eq $STS_ERR ]
	then
		return $ret
	fi

	return $ret
}

# MAPS
# Generic function for checking MAPS feautre during downgrade to 9.0.0 and below
check_901_warning_maps_features() {

	ret=$STS_OK

	# Check if user defined rules are created for ASC_UPLOAD_FAILURE MS.
	check_maps_features_vf check_maps_asc_upload_failure_rule "$MAPS_ASC_UPLD_WARN" "$BNA_MAPS_ASC_UPLD_WARN" "$MAPS_OPC_WARN"

	check_maps_features_vf maps_901_sfp_mon "$MAPS_901_SFP_DOWNGRD_WARN" \
											"$BNA_MAPS_901_SFP_DOWNGRD_WARN" \
											"$MAPS_OPC_WARN"
	return $ret
}

	


# The configBuffer is sent in pre 8.1.0 and in 
# release 8.1.0, we have to call check_maps_one_810_feature_to_give_warning
# to create the buffer and processes the tokens.
check_maps_one_feature_to_give_warning() {
	result=""
	ret=$STS_OK

	token=$1
	version=$2
	configBuffer=$3


	if [ -n "$configBuffer" ]
	then
	result=`echo $configBuffer | grep $token`
	#echo "result,$result"
	if [ -n "$result" ]
	then
		if [ $token == "qt=" ]
		then
		    token="Quiet time"
		fi
		if [ $token == "severity=" ]
		then
		    token="Severity"
		fi

		if [ -n "$warnTokenList" ]
		then
		    warnTokenList="$token, $warnTokenList"
		else
		    warnTokenList="$token"
		fi
	#echo "warnTokenList",   $warnTokenList,$token
	fi
	else
	    check_maps_one_810_feature_to_give_warning $token $version
	fi
    
    return $ret
}

prepare_list_for_fru_if_qt_configured() {
    ret=$STS_OK
    warnTokenList=""

    #configuration for each logical switch
    CONFIGSHOW_ADV>xxx

    tokenList=$1

    for token in $tokenList
    do
        configBuffer=`cat xxx | grep "maps.rule" | grep $token`
            if [ ! -z "$configBuffer" ]
            then
                isQt=`echo $configBuffer | grep "qt="`
                if [ ! -z "$isQt" ]
                then
		    if [ -n "$warnTokenList" ]
		    then
		        warnTokenList="$token, $warnTokenList"
                    else
		        warnTokenList="$token"
		    fi
                fi
            fi
    done

    return $ret
}

prepare_token_list_for_maps_rules_and_groups() {
    ret=$STS_OK

    #configuration for each logical switch
    CONFIGSHOW_ADV>xxx

    configBuffer=`awk '/^maps\.rule\./' xxx`
    
	# in 9.1.1 removed udgroup list parsing since it was added only to
	# check sys_mon_all_fports flow while migrating from
	# 8.2.x to 90x.
	# ud policy list check was missing. It is need to check the default
	# rule in ud policy. This is with assumption that default rule
	# definition has default group name and group name is passed as token
	configBuffer+=`awk '/^maps\.policy\./' xxx`

	if [ -z "$configBuffer" ]
	then
	  return $ret  
	fi

    tokenList=$1
    version=$2

    for token in $tokenList
    do 
        check_maps_one_feature_to_give_warning $token $version "$configBuffer"
    done
}

check_maps_all_fru_rules_for_qt_configured() {
    ret=$STS_OK
    tokenList="PS_STATE FAN_STATE BLADE_STATE WWN SFP_STATE ETH_MGMT_PORT_STATE"

    prepare_list_for_fru_if_qt_configured "$tokenList"

    if [ ! -z "$warnTokenList" ]
    then
		if [ -f $MAPS_WARN_VFID_FILE ]; then
			echo -n ", $glb_vf_id" >> $MAPS_WARN_VFID_FILE
		else
			echo -n "$glb_vf_id" > $MAPS_WARN_VFID_FILE
		fi
    fi

	warnTokenList=""
    return $ret
}

# this function checks for each token and add error string to a file for each
# logical switch
# Arguments to this function as follows - tokenList, FOS version

check_all_features_of_maps_for_warning() {

	$ECHO ${FUNCNAME[ 0 ]}

    # if token has been found then add the error string to a file and reset 
    # warnTokenList buffer

	feature=$3

    prepare_token_list_for_maps_rules_and_groups "$1" "$2"

    # This section is specific to 9.0.0

    if [[ ! -z "$warnTokenList" && "$TO_MAJOR" -eq 9 ]]
    then
		if [[ "$feature" == "flow" ]]
		then
			warnStr="WARNING:MAPS user defined rules or groups for $warnTokenList will not be monitored in $version release. These will be deleted from FID: $glb_vf_id"
		else
			warnStr="WARNING:MAPS user defined rules or default rules in user defined policy for $warnTokenList will not be monitored in pre-$version release. Please delete these from FID: $glb_vf_id"
		fi
		echo $warnStr >> ${MAPS_WARN_FILE}
		warnTokenList=""
    else
		if [[ ! -z "$warnTokenList" ]]
		then
		    warnStr="WARNING:MAPS user defined rules or default rules in user defined policy for $warnTokenList will not be monitored in pre-$version release. Please delete these from FID: $glb_vf_id"
	    	echo $warnStr >> ${MAPS_WARN_FILE}
		    warnTokenList=""
		fi
    fi
    return $ret
}


check_maps_821_features_ip_extn_flow() {
    ret1=0
    version="8.2.1"
    bnaErr=0
    #configuration for each logical switch
    CONFIGSHOW_ADV>xxx

    ruleBuffer=`cat xxx | grep "maps.rule" | grep "IP_EXTN_FLOW"`
    if [ -z "$ruleBuffer" ]
    then
          return $ret1
    else
        warnStr="WARNING: MAPS user defined rules for IP_EXTN_FLOW will be monitored as absolute number prior $version. Version $version and above IP_EXTN_FLOW rules are monitored as percentage. Please delete these rules and create them post firmware installation, from FID: $glb_vf_id"
	echo $warnStr >> ${MAPS_WARN_FILE}
    fi
}


check_maps_820_features_to_give_warning()
{
    version="8.2.0"
    bnaErr=0
    warningDisplayed=0
    tokenList="IP_EXTN_FLOW ALL_ETH_PORTS ALL_FCOE_40G_QSFP ALL_FCOE_10G_SFP ALL_FCOE_25G_SFP"
    tokenList="$tokenList RD_IOPS_LT_8K RD_IOPS_8_64K RD_IOPS_64_512K RD_IOPS_GE_512K WR_IOPS_LT_8K"
    tokenList="$tokenList WR_IOPS_8_64K WR_IOPS_64_512K WR_IOPS_GE_512K RD_RATE_LT_8K RD_RATE_8_64K RD_RATE_64_512K"
    tokenList="$tokenList RD_RATE_GE_512K WR_RATE_LT_8K WR_RATE_8_64K WR_RATE_64_512K WR_RATE_GE_512K ALL_FCOE_100G_SR4_QSFP sys_mon_all_fports"
	tokenList_amp="IP_EXTN_FLOW ALL_ETH_PORTS ALL_FCOE_40G_QSFP ALL_FCOE_10G_SFP ALL_FCOE_25G_SFP"
	tokenList_amp="$tokenList_amp ALL_FCOE_100G_SR4_QSFP"
    rm -f ${MAPS_WARN_FILE}

    if [ $VF_ENABLED -ne $STS_OK ]; then
        if [ $ACTIVECP ] ; then
            for_all_contexts check_all_features_of_maps_for_warning "$tokenList" $version
        else
            for_all_contexts_standby check_all_features_of_maps_for_warning  "$tokenList" $version
        fi
    else
        check_all_features_of_maps_for_warning $tokenList $version
    fi

    if [ -f "${MAPS_WARN_FILE}" ]
    then
        cat ${MAPS_WARN_FILE}
        rm ${MAPS_WARN_FILE}
        bnaErr=1
    fi

    if [ $bnaErr -ne 0 ]
    then
        add_warn_status  "$MAPS_82_WARN"
    fi

    #raslog mode key does not fit in our existing infra structure so need to handle sepratly
    #and generates warning if the 'custom' raslog mode is enabled
    CONFIGSHOW_ADV -chassis>xxx
    configBuffer=`awk '/^maps\.raslogMode:1/' xxx`

    # buffer must not be NULL and should not be default
    if [ -z "$configBuffer" ]
    then
	return $ret
    fi

     add_warn_status "$RASLOG_MODE_PRESENT" "$BNA_RASLOG_MODE_PRESENT"
}

#check if opassword hash of any user is set to SHA2
check_801_opw_hash()
{
	type=3
	/fabos/cliexec/userhashchk $type 
	stat=$?
	if [ $stat -ne 0 ]; then
		add_warn_status "$UNSUPPORTED_OPWHASH_MSG" "$UNSUPPORTED_OPWHASH_MSG"
	fi
	return $STS_OK
}

#
# Check for Encryption and Trunking configuration enable on Skywalker blade before
# downgrading to lower firmware version 8.1.x and 8.2.0 from 9.0. 8.2.1 version
# supports Encryption and Trunking on Skywalker and hence handle accordingly.
#
check_encryption_trunking_on_skywalker() {
	# Downgrade case to 8.2.0
	if [ $TO_MAJOR -eq 8 -a $TO_MINOR -eq 2 -a $TO_PATCH -lt 1 ]; then
		case ${SWBD##SWBD} in
			'165' | '166')
			if `correcthost_to_curr_vfid /fabos/rbin/encr_trunk_fwdl_check | grep -q "Encryption"`; then
				return $STS_ERR
			else
				return $STS_OK
			fi
		esac
	fi

	# Downgrade case to 8.1.x and below as applicable
	if [ $TO_MAJOR -eq 8 -a $TO_MINOR -le 1 ]; then
		case ${SWBD##SWBD} in
			'165' | '166')
			if `correcthost_to_curr_vfid /fabos/rbin/encr_trunk_fwdl_check | grep -q "Encryption"`; then
				return $STS_ERR
			else
				return $STS_OK
			fi
		esac
	fi
}

#
# Check for Encryption enable on C4 ports before downgrading to lower version 8.1.x
#
check_encryption_on_wedge64_fwdl() {
	# For Gen6 chassis block downgrade to 8.1.x when Encryption is enabled
	case ${SWBD##SWBD} in
	'162')
	if [ "$TO_MAJOR.$TO_MINOR" == "8.1" ]; then
		if `correcthost_to_curr_vfid /fabos/rbin/enccomp_fwdl_check | grep -q "Encryption"`; then
			return $STS_ERR
		else
			return $STS_OK
		fi
	fi
	esac
}


#This function checks if the switch is a base switch, and if so,
#whether any port is configured ISL R_RDY mode.
check_isl_rrdy_bs()
{
	# Optimizing the API to decrease the time delay taken in
	# preinstall checks when checking for every FID for existence of ISL R_RDY mode configured on its ports.
	ISL_RRDY_PORT_CFG_CNT=0
	BASE=`correcthost_to_curr_vfid /fabos/bin/switchshow | grep "Base Switch:" | cut -d ' ' -f 6 | cut -d ',' -f 1`
	if [ "$BASE" == "Yes" ]; then
		ISL_RRDY_PORT_CFG_CNT=`correcthost_to_curr_vfid /fabos/cliexec/portcfgshow | grep "ISL R_RDY" | grep ON | wc -l`
		if [ $ISL_RRDY_PORT_CFG_CNT -ne $STS_OK ]; then
			add_warn_status_fid "$ISL_RRDY_BS" "$BNA_ISL_RRDY_BS" "FID:$glb_vf_id"
			return $STS_ERR
		fi
	fi
	return $STS_OK
}

check_ficon_portaddress_range_all_contexts()
{
	if [ $VF_ENABLED -eq $STS_OK ]; then
		return $STS_OK
	fi

	paddr_err_status=""
	print_paddr_err_msg=""
	AWK_SCRIPT_FILE="/tmp/paddr.awk.$$"

	echo "{if ((\$3 ~ /^0x/) && ((\$6 == \"Y\"))) {pa_str=substr(\$3, 3, 2);pa_int=strtonum(\"0x\" pa_str);if (pa_int > max_port) { print \$2}}}" > $AWK_SCRIPT_FILE

	TEST_FIDS check_ficon_portaddress_range

	if [ "$print_paddr_err_msg" != "" ]; then
		paddr_err_status="$MAX_PA_FICON_LS_ERR_MSG  $print_paddr_err_msg"
		add_err_status "$paddr_err_status" "$paddr_err_status"
		return $STS_ERR
	fi

	rm -rf $AWK_SCRIPT_FILE

	return $STS_OK
}

check_ficon_portaddress_range() {
	CUT="/usr/bin/cut"
	GREP="/bin/grep"
	AWK="/bin/awk"

	FICON_LS_PA=`correcthost_to_curr_vfid /fabos/bin/switchshow | $GREP "Ficon Switch:" | $CUT -d ' ' -f 12 | $CUT -d ',' -f 1`
	FICON_LS_PA_CMD="/fabos/cliexec/ficucmd dump pdcm"

	if [ "$FICON_LS_PA" == "No" ]; then
		return $STS_OK
	fi

	FICON_LS_PA_MAXPORT=`$FICON_LS_PA_CMD | $GREP e_area | $CUT -f 2 -d '(' | $CUT -f 1 -d ')'`

	if [ $FICON_LS_PA_MAXPORT -ge 255 ]; then
		return $STS_OK
	fi

	port_addr_show="portaddress --show"

	paddr_err_show=`$port_addr_show | $AWK -v max_port=$FICON_LS_PA_MAXPORT -f $AWK_SCRIPT_FILE`
	paddr_err=`echo $paddr_err_show | $GREP ^[0-9] | /usr/bin/wc -l`

	if [ $paddr_err -gt 0 ]; then
		port_indexes=`echo $paddr_err_show | tr '\n' ' '`
		print_paddr_err_msg=$print_paddr_err_msg"\nFID:$glb_vf_id \n\tImpacted Port indexes: $port_indexes\n"
	fi
}

check_pdcm_prohibit_all_contexts()
{

	if [ $VF_ENABLED -eq $STS_OK ]; then
		return $STS_OK
	fi

	CACHE_ERR_STATUS="The FID(s) impacted due to Active configuration: "
	IPL_ERR_STATUS="The FID(s) impacted due to IPL configuration: "
	CACHE_AWK="/tmp/pdcm_cache.awk.$$"
	IPL_AWK="/tmp/pdcm_ipl.awk.$$"
	echo "{prohibit=substr(\$4, 1, 1); if (and(prohibit, 0x02)) {print \"prohibit found\"}}" > $CACHE_AWK
	echo "{prohibit=substr(\$2, 10, 1);if (and(prohibit, 0x02)) {print \"prohibit found\"}}" > $IPL_AWK

	err_status=""
	print_cache_fids=""
	print_ipl_fids=""

	TEST_FIDS check_pdcm_prohibit

	/bin/rm -f $CACHE_AWK $IPL_AWK

	if [[ "$print_cache_fids" != "" ]] || [[ "$print_ipl_fids" != "" ]]; then
		err_status=$PDCM_DEPRECATED_ERR_MSG"\n"
	fi

	if [ "$print_cache_fids" != "" ]; then
		err_status=$err_status"$CACHE_ERR_STATUS $print_cache_fids \n"
	fi
	if [ "$print_ipl_fids" != "" ]; then
		err_status=$err_status"$IPL_ERR_STATUS $print_ipl_fids \n"
	fi

	if [ "$err_status" != "" ]
	then
		add_err_status "$err_status" "$err_status"
		return $STS_ERR
	fi
	return $STS_OK
}

check_pdcm_prohibit()
{
	CUT="/usr/bin/cut"
	GREP="/bin/grep"
	AWK="/bin/awk"

	FICON_LS_PDCM=`correcthost_to_curr_vfid /fabos/bin/switchshow | $GREP "Ficon Switch:" | $CUT -d ' ' -f 12 | $CUT -d ',' -f 1`

	if [ "$FICON_LS_PDCM" == "No" ]; then
		return $STS_OK
	fi

	DUMP_CACHE="/fabos/cliexec/ficucmd dump cache"
	DUMP_IPL="/fabos/cliexec/ficucmd dump -I"
	DUMP_CACHE_CORRECT_HOST="correcthost_to_curr_vfid /fabos/cliexec/ficucmd dump cache"
	DUMP_IPL_CORRECT_HOST="correcthost_to_curr_vfid /fabos/cliexec/ficucmd dump -I"
	WC_LINE="/usr/bin/wc -l"

	prohibit_standby_err=0
	prohibit_cache_err=0
	prohibit_ipl_err=0

	if [ $HA_ROLE == "STANDBY" ] && [ $HA_STATE == "NOSYNC" ]; then
		prohibit_standby_cache_all=`$DUMP_CACHE | $GREP "^.[0-9A-F][0-9A-F] " | $AWK -f $CACHE_AWK | $GREP "prohibit found" | $WC_LINE`
		prohibit_standby_cache_ff=`$DUMP_CACHE | $GREP "^.[0-9A-F][0-9A-F] " | tail -1 | $AWK -f $CACHE_AWK | $GREP "prohibit found" | $WC_LINE`
		prohibit_standby_ipl_err=`$DUMP_IPL | $GREP PA | $GREP -v C_PA\(FF\)  | $AWK -f $IPL_AWK | $GREP "prohibit found" | $WC_LINE`
		if [ $prohibit_standby_cache_ff -eq 1 ]; then
			if [ $prohibit_standby_cache_all -gt 1 ]; then
				prohibit_standby_err=1
			else
				prohibit_standby_err=0
			fi
		else
			if [ $prohibit_standby_cache_all -gt 0 ]; then
				prohibit_standby_err=1
			else
				prohibit_standby_err=0
			fi
		fi
	else
		prohibit_cache_err=`$DUMP_CACHE_CORRECT_HOST | $GREP "^.[0-9A-F][0-9A-F] " | $AWK -f $CACHE_AWK | $GREP "prohibit found" | $WC_LINE`
		prohibit_ipl_err=`$DUMP_IPL_CORRECT_HOST | $GREP PA | $GREP -v C_PA\(FF\) | $AWK -f $IPL_AWK | $GREP "prohibit found" | $WC_LINE`
	fi

	if [[ $prohibit_cache_err -gt 0 ]] || [[ $prohibit_standby_err -gt 0 ]]; then
		print_cache_fids=$print_cache_fids"FID:$glb_vf_id "
	fi

	if [ $prohibit_ipl_err -gt 0 ]; then
		print_ipl_fids=$print_ipl_fids"FID:$glb_vf_id "
	fi

	return $STS_OK
}


check_TI_MAX_ZONENAME_exists() {
	correcthost_all_vfs /fabos/cliexec/zone --show | /bin/grep "TI Zone Name" | /bin/awk '{ len=length($4); if (len >= 64) {exit 1} }'
	return $?
}

# -Added the 'warn' version in FOS 9.0.0 for Traffic Isolation (TI) and Frame Redirection (RD)
# Zone deprecation.
# -Modified in FOS 9.0.1 to also check for Broadcast Zones.
# -Modified in FOS 9.1.0 to error out instead of warning. 
# This function checks all VFs to see if any TI/RD/Broadcast Zones exist on the switch.
# If so, post an error message at the beginning of the firmwaredownload operation.
check_TI_RD_BCAST_zone_deprecation_all_contexts() {
    if [ $VF_ENABLED -ne $STS_OK ]; then
        if [ $ACTIVECP ] ; then
	    for_all_contexts check_TI_RD_BCAST_zone_deprecation
        else
	    for_all_contexts_standby check_TI_RD_BCAST_zone_deprecation
        fi
    else
        check_TI_RD_BCAST_zone_deprecation
     fi

    if [ "$?" -eq $STS_OK ]; then
    	return $STS_OK
    else
    	return $STS_ERR
    fi
}

check_TI_RD_BCAST_zone_deprecation() {

	error=0
	# Check TI Cfg. The TI Cfg exists if any TI Zone exists.
	# Also check for TI Prop Zones. This is to cover case of a user deleting the last
	# ** TI Zone but doesn't perform a commit. In this scenario the TI Prop Zone will still exist
	ti_zones_exist=`/fabos/cliexec/zoneshow | /bin/grep -e "t_r_a_f_f_i_c_i_s_o_c__fg" -e "t_r_a_f_f_i_c_i_s_o_prop__zn" | wc -l`
	# ** If any TI Zones exist, print an error message.
	if [ "$ti_zones_exist" -ne 0 ];then
	    err_str="$TI_ZONE_DEPRECATION_ERR"
	    bna_err_str="$BNA_TI_ZONE_DEPRECATION_ERR"
	    # Only append VF_ID if VF is Enabled.
	    if [ $VF_ENABLED -ne $STS_OK ]; then
	        err_str=$err_str" (FID $glb_vf_id)"
	        bna_err_str=$bna_err_str" (FID $glb_vf_id)"
	    fi
	    add_err_status  "$err_str" "$bna_err_str"
	    error+=1
	fi

	# Check for RD Zones.
	# rd_zones_exist=`/fabos/cliexec/cfgshow | /bin/grep "r_e_d_i_r_c__fg" | wc -l`
	rd_zones_exist=`/fabos/cliexec/cfgshow --transdiffs | /bin/grep -w "r_e_d_i_r_c__fg" | wc -l`
	# ** If any RD Zones exist, print an error message.
	if [ "$rd_zones_exist" -ne 0 ];then
	    err_str="$RD_ZONE_DEPRECATION_ERR"
	    bna_err_str="$BNA_RD_ZONE_DEPRECATION_ERR"
	    # Only append VF_ID if VF is Enabled.
	    if [ $VF_ENABLED -ne $STS_OK ]; then
	        err_str=$err_str" (FID $glb_vf_id)"
	        bna_err_str=$bna_err_str" (FID $glb_vf_id)"
	    fi
	    add_err_status  "$err_str" "$bna_err_str"
	    error+=1
	fi

	# Check for Broadcast Zone
	# The search is done using Extended regular expressions (-E) and will match any
	# of the following: " broadcast ", " -broadcast ", " +broadcast "
	#
	# The combination of 'cfgshow' and the '--transdiffs' option is done to cover
	# the case of a user either creating or deleting a broadcast zone without saving
	# the change prior to performing firmwaredownload. The '--transdiffs' option will
	# show what changes are pending in a zone transaction, if any.
	bcast_zone_exist=`/fabos/cliexec/cfgshow --transdiffs | /bin/grep -E "(\s|\s\+|\s\-)broadcast($|\s)" | /bin/grep "zone:" | wc -l`

	# ** If any Broadcast Zone exists, print an error message.
	if [ "$bcast_zone_exist" -ne 0 ];then
	    err_str="$BROADCAST_ZONE_DEPRECATION_ERR"
	    bna_err_str="$BNA_BROADCAST_ZONE_DEPRECATION_ERR"
	    # Only append VF_ID if VF is Enabled.
	    if [ $VF_ENABLED -ne $STS_OK ]; then
	        err_str=$err_str" (FID $glb_vf_id)"
	        bna_err_str=$bna_err_str" (FID $glb_vf_id)"
	    fi
	    add_err_status  "$err_str" "$bna_err_str"
	    error+=1
	fi

	if [ $error -ne 0 ];then
	    return $STS_ERR
	else
	    return $STS_OK
	fi
}

# This function checks all VFs to see if any FabricAssist (FA), QuickLoop (QL),
# and Inverse Phantom Operation (IPO) Zones exist on the switch.
# If so, post an error message at the beginning of the firmwaredownload operation.
check_FA_QL_IPO_zone_deprecation_all_contexts() {
    if [ $VF_ENABLED -ne $STS_OK ]; then
        if [ $ACTIVECP ] ; then
	    for_all_contexts check_FA_QL_IPO_zone_deprecation
        else
	    for_all_contexts_standby check_FA_QL_IPO_zone_deprecation
        fi
    else
        check_FA_QL_IPO_zone_deprecation
     fi

    if [ "$?" -eq $STS_OK ]; then
    	return $STS_OK
    else
    	return $STS_ERR
    fi
}

check_FA_QL_IPO_zone_deprecation() {
	error=0
	# Check if any FA/IPO Zones/aliases exist
	fa_zones_exist=`/fabos/cliexec/cfgshow --transdiffs | /bin/grep "{" | wc -l`
	# ** If any FA/IPO Zones/aliases exist, print an error message.
	if [ "$fa_zones_exist" -ne 0 ];then
	    err_str="$FA_ZONE_DEPRECATION_ERR"
	    bna_err_str="$BNA_FA_ZONE_DEPRECATION_ERR"
	    # Only append VF_ID if VF is Enabled.
	    if [ $VF_ENABLED -ne $STS_OK ]; then
	        err_str=$err_str" (FID $glb_vf_id)"
	        bna_err_str=$bna_err_str" (FID $glb_vf_id)"
	    fi
	    add_err_status  "$err_str" "$bna_err_str"
	    error=1
	fi

	# Check if any Quickloop Zones/aliases exist
	ql_zones_exist=`/fabos/cliexec/cfgshow --transdiffs | /bin/grep "\[" | wc -l`
	# ** If any Quickloop Zones/aliases exist, print an error message.
	if [ "$ql_zones_exist" -ne 0 ];then
	    err_str="$QL_ZONE_DEPRECATION_ERR"
	    bna_err_str="$BNA_QL_ZONE_DEPRECATION_ERR"
	    # Only append VF_ID if VF is Enabled.
	    if [ $VF_ENABLED -ne $STS_OK ]; then
	        err_str=$err_str" (FID $glb_vf_id)"
	        bna_err_str=$bna_err_str" (FID $glb_vf_id)"
	    fi
	    add_err_status  "$err_str" "$bna_err_str"
	    error=1
	fi

	if [ $error -ne 0 ];then
	    return $STS_ERR
	else
	    return $STS_OK
	fi
}

check_au_license_installed()
{
	# Check for Analytics Upgrade License
	au_lic=`/fabos/sbin/license --show | grep "Analytics Upgrade license" | wc -l`

	if [ $au_lic -eq 0 ]; then
		return $STS_ERR
	fi

	return $STS_OK
}

check_fcoe_config_exist()
{
		is_fcoe_config_exist=`CONFIGSHOW_ADV | grep -e "fcoed.fabmap" -e "fcoed.numberof.enodes" -e "fcoed.numberof.fcoeports" -e "fcoed.port.provision" -e "fcoed.port.lag" | wc -l`

		if [ $is_fcoe_config_exist -ne 0 ]; then
				return $STS_ERR
		fi

		return $STS_OK
}


lag_name_char_check(){
	input_str=$1
	obj_type=$2
	rc=-1
	vlan_string="vlan"
	LAG_NAME=""

	IFS=,
	for i in $input_str; do
		unset IFS

 		if [ "$obj_type" == "SBLAG" ]; then
			if [ "${i:18:4}" == "name" ]; then
				LAG_NAME=${i:23:4}
				if [ `echo $LAG_NAME | tr [:upper:] [:lower:]` =  `echo $vlan_string | tr [:upper:] [:lower:]` ]; then
					rc=1
				else
					rc=0
				fi

 				if [ $rc -eq 1 ]; then
					return $rc
				fi
			fi

 			# need to handle varying prefix string lengths (ID values >= 10)
			if [ "${i:19:4}" == "name" ]; then
				LAG_NAME=${i:24:4}
				if [ `echo $LAG_NAME | tr [:upper:] [:lower:]` =  `echo $vlan_string | tr [:upper:] [:lower:]` ]; then
					rc=1
				else
					rc=0
				fi

 				if [ $rc -eq 1 ]; then
					return $rc
				fi
			fi
		fi
		IFS=,
	done
	unset IFS

 	return $rc
}

check_location_id()
{
	if [ $ACTIVECP ] ; then
		locIdCnt=`switchshow | grep -c "Location ID"`
		if [ ${locIdCnt} -ne 0 ]; then
			return $STS_ERR
		fi
	else
		if [ -x /fabos/cliexec/config ]; then
			locId=`/fabos/cliexec/config get route.locationid 2`
			if [[ $? -eq 0 ]] && [[ $locId -gt 0 ]]; then
				return $STS_ERR
			fi
		fi
	fi

	return $STS_OK
}

check_location_id_all_contexts()
{
	if [ $VF_ENABLED -ne $STS_OK ]; then
		# TODO: SMB needed? CHASSISCMD="cmd_chassis"
		if [ $ACTIVECP ] ; then
			for_all_contexts check_location_id
		else
			for_all_contexts_standby check_location_id
		fi
	else
		check_location_id
	fi

	if [ "$?" -eq $STS_OK ]; then
		return $STS_OK
	else
		return $STS_ERR
	fi
}

check_910_maps_features_for_warning()
{
    version="9.1.0"
    bnaErr=0
    warningDisplayed=0

    tokenList="MAX_RD_PENDING_IO MAX_WR_PENDING_IO WR_1stXFER_RDY_VIOL RD_1stDATA_TIME_VIOL"
    tokenList="$tokenList WR_STATUS_TIME_VIOL RD_STATUS_TIME_VIOL IO_TIMEOUT"
    tokenList="$tokenList IO_ERROR NVME_SLER"

	tokenList="$tokenList ALL_N_PORTS sys_flow_monitor_scsi sys_flow_monitor_nvme"
	tokenList="$tokenList ROUTING_ERR ALL_64GSWL_SFP_DD ALL_2Km_GEN7LWL_QSFP TRUFOS_CERT_INSTALLED"

    rm -f ${MAPS_WARN_FILE}

    if [ $VF_ENABLED -ne $STS_OK ]; then
        if [ $ACTIVECP ] ; then
            for_all_contexts check_all_features_of_maps_for_warning "$tokenList" $version
        else
            for_all_contexts_standby check_all_features_of_maps_for_warning  "$tokenList" $version
        fi
    else
        check_all_features_of_maps_for_warning "$tokenList" $version
    fi

    if [ -f "${MAPS_WARN_FILE}" ]
    then
	BNA_ERR=`cat ${MAPS_WARN_FILE}`
        rm ${MAPS_WARN_FILE}
        bnaErr=1
    fi

    if [ $bnaErr -ne 0 ]
    then
        add_warn_status "$BNA_ERR"
    fi
}

check_911_maps_features_for_warning()
{
    version="9.1.1"
    bnaErr=0
    warningDisplayed=0

	$ECHO ${FUNCNAME[ 0 ]}

	tokenList="ALL_25Km_32GELWL_JBA_SFP ALL_64GLWL_SFP ALL_25Km_64GELWL_SFP"
	tokenList="$tokenList ALL_32GLWL_JDB_SFP"
	tokenList="$tokenList IO_ABORT RESERVE"

    rm -f ${MAPS_WARN_FILE}

    if [ $VF_ENABLED -ne $STS_OK ]; then
        if [ $ACTIVECP ] ; then
            for_all_contexts check_all_features_of_maps_for_warning "$tokenList" $version
        else
            for_all_contexts_standby check_all_features_of_maps_for_warning  "$tokenList" $version
        fi
    else
        check_all_features_of_maps_for_warning "$tokenList" $version
    fi

    if [ -f "${MAPS_WARN_FILE}" ]
    then
	BNA_ERR=`cat ${MAPS_WARN_FILE}`
        rm ${MAPS_WARN_FILE}
        bnaErr=1
    fi

    if [ $bnaErr -ne 0 ]
    then
        add_warn_status "$BNA_ERR"
    fi
}

# Function to check amp30 collection config and block the downgrade if any
#
check_amp30_collection_configs()
{
	$ECHO check_amp30_collection_configs

	# check for mgmt server ip
	for app_ip in `CONFIGSHOW -all | /bin/grep "http.BoundApplication" | cut -d":" -f 2`;
	do
		if [ -n "$app_ip" ]; then
			return $STS_ERR
		fi
	done

	return $STS_OK
}

handle_snmp() {
	declare -a snmpv1_community=("Secret\ C0de" "OrigEquipMfr" "private" "public" "common" "FibreChannel")

	CONFIGSHOW_ADV -all > /tmp/snmp_config_v1.txt

	v1_enable=`/bin/cat /tmp/snmp_config_v1.txt | /bin/grep "snmp.v1Enable" | /bin/grep -v "snmp.v1Enable.default"| /usr/bin/cut -d ':' -f2`
	if [ "$v1_enable" == 0 ] ; then
		rm -rf /tmp/snmp_config_v1.txt 2>/dev/null
		return
	fi

	for (( i = 0; i < 6; i++ ))
	do
		name=`/bin/cat /tmp/snmp_config_v1.txt | /bin/grep "snmp.agtParty.$i.authPrivSecret" |/usr/bin/cut -d ':' -f2| head -n 1`
		for v1 in "${snmpv1_community[@]}"
		do
			if [ "$v1" == "$name" ] ; then
				add_warn_status "$FDW_SNMPV1_WARNING" "$FDW_SNMPV1_WARNING"
				rm -rf /tmp/snmp_config_v1.txt 2>/dev/null
				return 1
			fi
		done
	done
	rm -rf /tmp/snmp_config_v1.txt 2>/dev/null
}


check_amp30_mp_config()
{
	if [ -f /fabos/rbin/esmcmd ]; then
		mp_count=`/fabos/rbin/esmcmd dbg0 solo mp -resource | grep Total | awk {'print $3'}`
	else
		mp_count=`/fabos/cliexec/esmcmd dbg0 solo mp -resource | grep Total | awk {'print $3'}`
	fi

	if [ $mp_count -gt $AMP_22_CONFIG_SIZE ]
	then
		return $STS_ERR
	fi

	return $STS_OK

}

# check for default password 
#
check_default_password()
{
	#
	# Block upgrade to 9.0 if admin and/or user have not changed default passwords
	#
	chkCmd=`find /fabos/ -iname chkpasswd`
	$chkCmd admin > /dev/null 2>&1
	ret=$?
	if [ $ret != $STS_OK ]; then
		return $ret
	fi

	$chkCmd user > /dev/null 2>&1
	ret=$?
	return $ret
}


check_for_ipsec_feature()
{
	SPMD_FILE=/var/run/spmd.pid
	PS=/bin/ps
	WC=/usr/bin/wc
	CHKCONFIG=`/usr/bin/which chkconfig`
	GREP=`/usr/bin/which grep`
	#check if spmd file is present
	if [[ $(ls $SPMD_FILE 2>/dev/null) ]]; then
		content=`cat $SPMD_FILE 2>null`
		spmd_pid=`$PS -A | $GREP $content 2>/dev/null | $GREP spmd 2>/dev/null  | $WC -c`
		#if spmd_pid is not empty then IPSec is enabled
		if [[ $spmd_pid -gt 0 ]]; then
			# If current cp is stanby then warn user and continue with firmwarae upgrade 
			if [ $HA_ROLE == "STANDBY" ]; then
				add_warn_status "$IPSEC_DISABLE_WARN_STANDBY" "$BNA_IPSEC_DISABLE_WARN_STANDBY"
				return $STS_OK
			fi
			# Block firmware upgrade as ipsec is enabled
			return $STS_ERR
		fi
	fi
	# For internal testing purpose. if upgrading from 9.0 to 9.0 and chkconfig ipsec is 
	# "on" then disabale it and continue with upgrade.
	if [ $CUR_MAJOR -eq 9 ] ; then
		ipsec_state=`$CHKCONFIG | grep ipsec | sed -n 's/.*\(on\|off\).*/\1/p'`
		if [ "$ipsec_state" != "off" ] ; then
			$CHKCONFIG ipsec off >& /dev/null
		fi
	fi
	return $STS_OK
}

check_for_portswap()
{
	result=`correcthost_to_curr_vfid /fabos/bin/portswapshow | cut -d "P" -f1 |  cut -d "E" -f1 | cut -d  "O" -f1 | cut -d "N" -f1 | cut -d "p" -f1 | awk '$2' | wc -l`
	result1=`correcthost_to_curr_vfid /fabos/bin/portswapshow | grep -E [0-9] | wc -l`
	if [ $result -ne 0 -o $result -ne 0 ]; then
		return $STS_ERR
	else
		return $STS_OK
	fi
}


check_for_portcfgalpa()
{
	result=`correcthost_to_curr_vfid /fabos/bin/portcfgshow | grep "AL_PA Offset 13" | grep -c "ON"`
	if [ $result -ne 0 ]; then
		# Block firmware upgrade as portcfgalpa is enabled
		return $STS_ERR
	fi

	return $STS_OK
}

check_for_ld_ls_noeflicense()
{
	result=`correcthost_to_curr_vfid /fabos/bin/portcfgshow | grep "Long Distance" | grep -c -e "LS" -e "LD"`
	if [ $result -gt 0 ]; then
		# Block upgrade if any LD/LS ports present without Extended Fabrics license
		return $STS_ERR
	fi

	return $STS_OK
}

check_ca_bundle_update()
{
	new_ca_bundle_dt="Tue Apr 13 03:12:04 2021 GMT"
	cabundlefile="/usr/share/curl/ca-bundle-default.crt"
	dt_str=""

	# Get certificate date.
	if [ -f $cabundlefile ]; then
		switch_ca_bundle_dt=$(/bin/grep "Certificate data from" $cabundlefile)
		dt_str=`echo $switch_ca_bundle_dt | cut -d ':' -f 2-`
		dt_str="${dt_str:1}"
	fi
	# Print warning message if dates are different
	if [ "$dt_str" != "$new_ca_bundle_dt" ]; then
		add_warn_status "$ASC_CA_BUNDLE_UPDATE_WARN" "$BNA_ASC_CA_BUNDLE_UPDATE_WARN"
	fi
	return $STS_OK
}


check_ethif_hd_config(){
	slot_based=`/fabos/bin/slotshow | grep "Not supported on this platform"`
	if [ "$slot_based" == "" ]; then
		if [ $VF_ENABLED -eq $STS_OK ]; then
			RSH_CMD="/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CHASSIS_ROLEID=0 CURRENT_AD=0"
		else
			RSH_CMD="/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CHASSIS_ROLEID=0 FABOS_SWITCHNO=$glb_ls_id CURRENT_VF=$glb_vf_id CURRENT_AD=0"
		fi

		mycpbond0=`/fabos/cliexec/ethif --show bond0 | grep "Link mode:" | grep -cE "half duplex|HD"`
		othcpbond0=`$RSH_CMD 2>/dev/null /fabos/cliexec/ethif --show bond0 | grep "Link mode:" | grep -cE "half duplex|HD"`

		if [ "$mycpbond0" -gt 0 -o "$othcpbond0" -gt 0 ]; then
			return $STS_ERR
		fi
	else
		ethzero=`/fabos/cliexec/ethif --show eth0 | grep "Link mode:" | grep -cE "half duplex|HD"`
		if [ $ethzero -gt 0 ]; then
			return $STS_ERR
		fi
	fi
	return $STS_OK
}

check_fcoe_enodes() {
        total_enodes=0
        #VF enable
        if [ $VF_ENABLED -ne $STS_OK ]; then
            result=`CONFIGSHOW_ADV -all | /bin/grep fcoed.numberof.enodes.configured | cut -d ':' -f2`
        else
            result=`CONFIGSHOW_ADV | /bin/grep fcoed.numberof.enodes.configured | cut -d ':' -f2`
        fi
        if [ "$result" = "" ]; then
            return $STS_OK
        fi

        #Get sum total of all configured enodes
        for num in ${result[*]}
        do
            total_enodes=$((total_enodes + num))
        done

        #Total enodes in full chassis should not exceed 1000
        if [ $total_enodes -gt 1000 ]; then
            return $STS_ERR
        else
            return $STS_OK
        fi
}

check_ficon_cup_addr_use()
{
	cup_addr_in_use=0
	rc=0
	count=0

	if [ $VF_ENABLED -ne $STS_OK ]; then
		FICON_LS=`correcthost_to_curr_vfid /fabos/bin/switchshow | grep "Ficon Switch:" | cut -d ' ' -f 12 | cut -d ',' -f 1`
	else
		FICON_LS="No"
	fi

	if [ "$FICON_LS" == "Yes" ] ; then
		slot_based=`/fabos/bin/slotshow | grep "Not supported on this platform"`
		if [ "$slot_based" == "" ]; then
			col=4
		else
			col=3
		fi

		for i in `correcthost_to_curr_vfid /fabos/bin/switchshow | sed '1,/=====/d' | awk -v column=$col '{print $column}'`
		do
			# Get the port count, includes LISL ports too.
			let "count++"

			# Check if FMS address is in use.
			if [ "${i:2:2}" == "ff" -o "${i:2:2}" == "fe" ]; then
				cup_addr_in_use=1
			fi
		done

		if [ $count -gt 254 ]; then
			# Skip LISL and ICL ports in port count. This case will be hit only in chassis based systems.
			for j in `correcthost_to_curr_vfid /fabos/bin/switchshow | sed '1,/=====/d' | grep "\-\-\-\-\-\-" | awk '{print $2}'`
			do
				# LISL port have slot numbers -1
				if [ "$j" == "-1" ]; then
					let "count--"
				else
					# Skip ICL port count
					for sl in `/fabos/cliexec/slotshow | grep CORE | awk '{print $1}'`
					do
						if [ "$j" == "$sl" ]; then
							let "count--"
						fi
					done
				fi
			done

			# Skip ge port count as they do not need area
			ge=`correcthost_to_curr_vfid /fabos/bin/switchshow | sed '1,/=====/d' | awk '{print $2}' | grep ge | wc -l`
			if [ "$ge" != "0" ]; then
				let "count=count-ge"
			fi
		fi

		if [ $cup_addr_in_use == 1 ]; then
			add_err_status_fid "$FICON_CUP_ADDR_IN_USE" "$BNA_FICON_CUP_ADDR_IN_USE" "FID:$glb_vf_id"
			rc=1
		fi

		if [ $count -gt 254 ]; then
			add_err_status_fid "$FICON_LS_PORT_LIMIT_EXCEEDED" "$BNA_FICON_LS_PORT_LIMIT_EXCEEDED" "FID:$glb_vf_id"
			rc=1
		fi

		if [ $rc == 1 ]; then
			return $STS_ERR
		fi
	fi

	return $STS_OK
}

FLOW_9X_ALL_FIDS_FILE="/tmp/flow_9x_active_fid.txt"

check_9x_flows_active()
{
	if [ $ACTIVECP ] ; then
		pd_flows=`/fabos/cliexec/flow --show | grep -Ev "Flow Name|----|Denotes feature|sys_ de" | grep sys_ | grep -v sys_flow_monitor | grep + | wc -l`
		ud_flows=`/fabos/cliexec/flow --show | grep -Ev "Flow Name|----|Denotes feature|sys_" | grep + | wc -l`
	else
		pd_flows=`correcthost_to_curr_vfid /fabos/cliexec/flow --show | grep -Ev 'Flow Name|----|Denotes feature|sys_ de' | grep sys_ | grep -v sys_flow_monitor | grep + | wc -l`
		ud_flows=`correcthost_to_curr_vfid /fabos/cliexec/flow --show all| grep 'Name' | cut -d ':' -f2| grep -v 'sys_' | grep + | wc -l`
	fi

	if [ $pd_flows -ne 0 -o $ud_flows -ne 0 ]
	then
		echo -n "$glb_vf_id " >> $FLOW_9X_ALL_FIDS_FILE
	fi
}
#
# This function to check any user defined / Predefined flows are active
#

check_is_all_9x_flows_deactivated()
{
	$ECHO check_is_all_9x_flows_deactivated

	if [ $CUR_MAJOR -eq 9 -a $CUR_MINOR -eq 0 ]; then
		# Iterate all NP config files and create firmwareupgrade config key if any flow other than sys_flow_monitor is active
		# firmwareupgrade config key would used in NPD to decide whether sys_flow_monitor can be activated in all LS after the upgrade
		if [ $VF_ENABLED -ne $STS_OK ]; then
			if [ $ACTIVECP ] ; then
				for_all_contexts check_9x_flows_active
			else
				for_all_contexts_standby check_9x_flows_active
			fi
		else
			check_9x_flows_active
		fi

		if [ -e $FLOW_9X_ALL_FIDS_FILE ]
		then
			handle_9x_flow_error
			/bin/rm $FLOW_9X_ALL_FIDS_FILE
		else
			add_warn_status "$ACT_SYS_FLOW_ALL_VF"
		fi
	fi
	return $STS_OK
}

check_fclag_configured() {
        #VF enable
        if [ $VF_ENABLED -ne $STS_OK ]; then
            result=`CONFIGSHOW_ADV -all | /bin/grep fclagd.numberof.fclag.configured | wc -l`
        else
            result=`CONFIGSHOW_ADV | /bin/grep fclagd.numberof.fclag.configured | wc -l`
        fi
        if [ $result -eq 0 ]; then
            return $STS_OK
        else
            return $STS_ERR
        fi
}


FLOW_9X_TMP_CONF="/tmp/np.9x_tmp.conf"

handle_9x_flow_error()
{
	# get all FIDS in the switch
	FIDS=$(CONFIGSHOW -all | sed -n 's/Fabric ID =//p')
	sw=`echo $FIDS | wc -w`
	for ((npfile=0;npfile<sw;npfile++))
	do
		file="/mnt/etc/fabos/np."$npfile".conf"
		if [ -e "$file" ]
		then
			/bin/cat $file | sed 's@np\.meta\.ver:*[0-9]@np\.meta\.ver:2@g'  > $FLOW_9X_TMP_CONF
			/bin/cp $FLOW_9X_TMP_CONF $file
			echo -n "" > $FLOW_9X_TMP_CONF
		fi
	done

	if [ -e $FLOW_9X_TMP_CONF ]
	then
		/bin/rm $FLOW_9X_TMP_CONF
	fi
}


V8X_EULA_FAIL_MSG="This operation requires User acceptance of the End User License Agreement (EULA) for the product.\n"\
"Firmwaredownload failed due to non-acceptance of  End User License Agreement (EULA) for this product."

confirm_eula_acceptance() {
	CUR_PREINST_FILE=/sbin/preinst
	EULA_ACCEPTANCE_FILE=/etc/config/EULAaccepted

	if [ $RET_CODE != $STS_OK ]; then
		#
		# If fwdl is already failing due to other errors then
		# do not bother to prompt for EULA acceptance
		#
		return $RET_CODE
	fi

	#
	# If this is a FOS9.x to FOS 9.x upgrade/downgrade
	# Then Bail out. FOS9.x manages this in code.
	# This check in preinst is only for non-EULA FOS8.x to FOS9.x migration.
	#
	if [ ${TO_MAJOR} -ge 9 ] && [ ${LOCAL_MAJOR} -ge 9 ]; then
		return $STS_OK
	fi


	#
	# If firmwaredownload specified with --acceptEULA option
	# Then permit it to go through without prompting for EULA acceptance
	#
	if [ -f $EULA_ACCEPTANCE_FILE ]; then
		# User has specified -acceptEULA option
		# Or the request has come from CAL for webtools/BNA/SANNav
		# So no need to prompt to accept EULA
		return $STS_OK
	fi

	#
	# Check here if invoked from an APP (webtools, BNA, SANNav)
	# via non-EULA aware FOS (<= v8.2.1c or <= v8.2.2a)
	# If so then Fail without Prompting for EULA.
	# non-EULA aware FOS cannot provide acceptance via APP
	# AND migration to v9.0 is not permitted without EULA acceptance.
	#
	cur_fos_supports_eula=`grep -c "V8X_SUPPORTING_EULA" $CUR_PREINST_FILE`
	if [ $cur_fos_supports_eula -eq 0 ]; then
		#
		# The Current v8x is not EULA aware.
		# Check next if invoked from APP
		# if so FAIL fwdl wit/hout prompting for EULA

		case "$GEPS_APP_NAME" in
		"WebTools" | "Fabric Manager" | "SANnavMP" | "SANnavGV")
			# add_err_status "$UNSUPPORTED_EULA_MSG" "$BNA_UNSUPPORTED_EULA"
			add_err_status "$V8X_EULA_FAIL_MSG" "$V8X_EULA_FAIL_MSG"
			RET_CODE=$STS_ERR
			return $STS_ERR
		;;

		*)
		;;
		esac
	fi

	#
	# This is one of the following upgrades
	# - Upgrade from non-EULA FOS (does not have --acceptEULA, hence need to prompt
	# - Upgrade from EULA FOS but --acceptEULA not specified, hence need to prompt
	#

	validResponse=0
	while [ $validResponse -eq 0 ]; do
		echo "Do you accept and agree to the terms outlined in the End User License Agreement (EULA) for this product?"
		read -p "Please respond with (Y/y) to Accept, (N/n) to Not accept, (D/d) to display  the EULA :" eulaResponse
		if [ "$eulaResponse" == "y" ] || [ "$eulaResponse" == "Y" ]; then
			return $STS_OK
		fi

		if [ "$eulaResponse" == "n" ] || [ "$eulaResponse" == "N" ]; then
			add_err_status "$V8X_EULA_FAIL_MSG" "$V8X_EULA_FAIL_MSG"
			RET_CODE=$STS_ERR
	        return $STS_ERR
		fi

		if [ "$eulaResponse" == "d" ] || [ "$eulaResponse" == "D" ]; then
			eula_pattern=$(awk '/NEW_EULA_TEXT/ {print NR}' $0)
			eula_start=$(echo $eula_pattern | awk '{print $2}')
			eula_end=$(echo $eula_pattern | awk '{print $3}')

			if [[ -n $eula_start ]]; then
				if [[ -n "$eula_end" ]]; then
					echo "" > tempfile
					awk -v s="$eula_start" -v e="$eula_end" '{if (NR > s && NR < e) print $0}' $0 >> tempfile
					EULA_FILE=tempfile
				fi
			fi

			if [ -f $EULA_FILE ]; then
				/usr/bin/less $EULA_FILE
			else
				echo "End User License Agreement (EULA) not found!"
			fi
		else
			echo
			echo "Invalid response: $eulaResponse"
		fi

	done
}

check_tcptolevel ()
{
        cmd=`cat /etc/fabos/fabos.0.conf | grep "ipadm.tcptimeoutlevel"`
        if [ "$cmd" != "" ]; then
                tlevel="${cmd: -1}"
                if [ $tlevel -ne 5 ]; then
                     add_warn_status "$DEFAULT_TCP_TIMEOUT_WARN"
                fi
        fi

	

}

check_dc_psu_error ()
{
	# if wedge2 and using DC psu, don't allow downgrade
	case ${SWBD##SWBD} in
	'183')
		is_psu_dc	
		if [ $? -eq 1 ]; then
			$ECHO "psu is dc"
			return $STS_ERR
		fi
		;;
	esac
	return $STS_OK
}

###########################################################
# This section contains logic for media piracy validation #
#             Media Piracy section - Start                #
###########################################################

# All blank spaces need to be removed from Vendor Name string
VENDOR_BROCADE="BROCADE"

# Since HP branded media have different kinds of Vendor Name string, check for
# only HP* Below are few examples of HP's Vendor Name strings
# HPE-F    BROCADE
# HP-A     BROCADE
# HP-A     BROCAD
VENDOR_HP="HP"

# Below is supported media matrix for pre-Gen7 platforms. This matrix contains
# Brocade branded pre-Gen7 legacy media, HP media & Gen7 media as well as
# non-Brocade branded SmartOptics media. Gen7 media are backward compatible
# pre-Gen7 platforms.
# This matrix is used to block upgrade to 9.0.0 if any ports have pirated media
# plugged into them. Pirated media means whose PN, SN doesn't match with those
# white listed in support matrix.
# In this matrix, 1st column contains Brocade Part Number and subsequent
# columns contain supported Serial Number (first 3 letters) for that Part Number

# Brocade pre-Gen7 media support list for FC ports
brcd_gen6_media_fc_port=( \
"57-1000333-** JAA JAF JAP" \
"57-1000332-** JDA JDF JDP" \
"57-1000335-** JBF" \
"57-0000088-** HAA HAF" \
"57-0000089-** HDA HDF" \
"57-1000262-** HBA HBF" \
"57-1000114-** KAA" \
"57-1000115-** KDA" \
"57-1000351-** ZUA" \
"57-1000480-** ZMA ZMJ" \
"57-1000331-** ZTA ZTF" \
"57-1000267-** HTA" \
"57-1000294-** HUA" \
"57-1000310-** HME" \
)

# Brocade pre-Gen7 media support list for FCoE ports
brcd_gen6_media_fcoe_port=( \
"57-1000128-** LTA LTF LTJ" \
"57-1000129-** ATA ATJ" \
"57-1000263-** LDF LDJ" \
"57-1000326-** YTA YTF" \
"57-1000339-** LKA" \
"57-1000327-** LFF" \
)

# Brocade pre-Gen7 media support list for GE ports
brcd_gen6_media_ge_port=( \
"57-1000042-** TZA" \
"33210-100 TAA TAF" \
"33211-100 TDA TDF" \
"57-1000311-** TRF" \
"57-1000312-** TRF" \
"57-1000313-** TRF" \
"57-1000314-** TRF" \
"57-1000315-** TRF" \
"57-1000316-** TRF" \
"57-1000317-** TRF" \
"57-1000318-** TRF" \
"57-1000013-** WAA VAF" \
"57-1000014-** WCA VCF" \
"57-1000015-** WDA VDF" \
"57-1000020-** VEF" \
"57-0000075-** AAA AAF" \
"57-0000076-** ADA ADF" \
"57-1000130-** ALA ALF" \
"57-1000266-** AJJ" \
"57-1000128-** LTA LTF LTJ" \
"57-1000263-** LDF LDJ" \
"57-1000327-** LFF" \
"57-1000339-** LKA" \
)

# Brocade Gen7 media support list for FC ports
brcd_gen7_media_fc_port=( \
"57-1000481-** BAR" \
"57-1000485-** JAA JAF" \
"57-1000486-** JDA JDF" \
"57-1000487-** HAA HAF" \
"57-1000488-** HDA HDF" \
"57-1000489-** HBA HBF" \
"57-1000490-** ZUA" \
"57-1000491-** ZMA" \
"57-1000492-** KAA" \
"57-1000493-** KDA" \
"57-1000494-** JBF" \
)

# HP branded media support list for FC ports
hp_media_fc_port=( \
"P9H32A JAA JAF" \
"P9H29A JDA JDF" \
"QK724A HAA HAF" \
"QK725A HDA HDF" \
"H6Z29A HBA HBF" \
"QK726A KAA" \
"QK727A KDA" \
)

# HP branded media support list for GE ports
hp_media_ge_port=( \
"AP823A AAA AAF" \
"AP824A ADA ADF" \
"AW537A CZA TZA TZH" \
)

# Media from Smartoptics vendor are not Brocade branded. Also one 16G DWDM optic
# from Finisar is not Brocade branded. So threat them as exception.
# Add supported serial numbers for Smartoptics & Finisar media here.
non_brcd_media=( \
"32G-IR-D***-BR JFC HFC" \
"16G-ER-D***-BR1 JFC HFC" \
"16G-ER-D***-BR2 JFC HFC" \
"16G-ER-BR2 JFC HFC" \
"8G-ZR-D***-BR1 UGC" \
"FTLX3670SCC**B16 \*" \
)

mediatrc()
{
	message="$@"
	if [ "$MEDIA_TRC" = 1 ]; then
	$ECHO $message
	fi
}

medialog()
{
	message="$@"
	echo $message
}

skip_ge_port_media=1	# Do Not validate media on GE ports of Extn platforms
skip_fcoe_port_media=0	# Validate media on ALL ports of FCoE blade
fcoe_blade_id=204
fcoe_blade_slots=""
extn_blade_id=186
extn_blade_slots=""

validate_media_bpn_serial()
{
	bpn=$1
	serial=$2
	vendor=$3
	port=$4
	extn_gen7med_chk=$5
	valid=0
	mediatrc "Validating $bpn $serial $vendor plugged into $port ..."

	# Check if ge_port media validation needs to be skipped
	if [ $skip_ge_port_media -eq 1 ]
	then
		# If port is GE-port, then skip validation
		echo $port | grep ge 1> ${NULL} 2>&1
		if [ $? -eq 0 ]
		then
			mediatrc "Skipping media validation on GE port $port"
			valid=1
			return $valid
		fi
	fi

	# Check if fcoe_port media validation needs to be skipped
	if [ $skip_fcoe_port_media -eq 1 ]
	then
		# Check if fcoe blade is present in the system
		if [ "$fcoe_blade_slots" != "" ]
		then
			# Get slot number
			slot=`echo $port | sed '/\/.*/s///g'`
			# Check if this slot# corresponds to that of fcoe blade
			echo $fcoe_blade_slots | grep -w $slot 1> ${NULL} 2>&1
			if [ $? -eq 0 ]
			then
				mediatrc "Skipping media validation on FCoE port $port"
				valid=1
				return $valid
			fi
		fi
	fi

	# Validate Brocade branded media
	if [[ "$vendor" == "$VENDOR_BROCADE"* ]]
	then
		# Validate Brocade pre-Gen7 branded media
		for (( i = 0; i < ${#brcd_gen6_media_fc_port[@]}; i++ ))
		do
			itr=(${brcd_gen6_media_fc_port[$i]})

			# Remove ** from PN
			pn=`echo ${itr[0]} | sed '/\**/s///g'`
			if [[ "$bpn" == "$pn"* ]]
			then
				mediatrc "Got media details ${itr[@]} - ${#itr[@]}"
				for (( j = 1; j <  ${#itr[@]}; j++ ))
				do
					if [ "${itr[$j]}" = "$serial" ]
					then
						mediatrc "Valid media ${itr[0]} ${itr[$j]}"
						valid=1
						return $valid
					fi
				done
			fi
		done

		if [ $skip_fcoe_port_media -eq 0 ]
		then
			for (( i = 0; i < ${#brcd_gen6_media_fcoe_port[@]}; i++ ))
			do
				itr=(${brcd_gen6_media_fcoe_port[$i]})
	
				# Remove ** from PN
				pn=`echo ${itr[0]} | sed '/\**/s///g'`
				if [[ "$bpn" == "$pn"* ]]
				then
					mediatrc "Got media details ${itr[@]} - ${#itr[@]}"
					for (( j = 1; j <  ${#itr[@]}; j++ ))
					do
						if [ "${itr[$j]}" = "$serial" ]
						then
							mediatrc "Valid media ${itr[0]} ${itr[$j]}"
							valid=1
							return $valid
						fi
					done
				fi
			done
		fi

		if [ $skip_ge_port_media -eq 0 ]
		then
			for (( i = 0; i < ${#brcd_gen6_media_ge_port[@]}; i++ ))
			do
				itr=(${brcd_gen6_media_ge_port[$i]})
	
				# Remove ** from PN
				pn=`echo ${itr[0]} | sed '/\**/s///g'`
				if [[ "$bpn" == "$pn"* ]]
				then
					mediatrc "Got media details ${itr[@]} - ${#itr[@]}"
					for (( j = 1; j <  ${#itr[@]}; j++ ))
					do
						if [ "${itr[$j]}" = "$serial" ]
						then
							mediatrc "Valid media ${itr[0]} ${itr[$j]}"
							valid=1
							return $valid
						fi
					done
				fi
			done
		fi

		# Validate Brocade Gen7 branded media
		for (( i = 0; i < ${#brcd_gen7_media_fc_port[@]}; i++ ))
		do
			itr=(${brcd_gen7_media_fc_port[$i]})

			# Remove ** from PN
			pn=`echo ${itr[0]} | sed '/\**/s///g'`
			if [[ "$bpn" == "$pn"* ]]
			then
				mediatrc "Got media details ${itr[@]} - ${#itr[@]}"
				for (( j = 1; j <  ${#itr[@]}; j++ ))
				do
					if [ "${itr[$j]}" = "$serial" ]
					then
						# If the flag to check Gen7 media on extn platform, then
						# inverse the return value. i.e. in such a case treat
						# Gen7 media as invalid media.
						if [ "$extn_gen7med_chk" = "EXTN_GEN7MED_CHK" ]
						then
							mediatrc "Invalid media ${itr[0]} ${itr[$j]}"
							valid=0
						else
							mediatrc "Valid media ${itr[0]} ${itr[$j]}"
							valid=1
						fi
						return $valid
					fi
				done
			fi
		done
	fi

	# Validate HP branded media
	# Since HP branded media have different kinds of Vendor Name string, check
	# for only HP* which will cover all those Vendor Name strings
	if [[ "$vendor" == "$VENDOR_HP"* ]]
	then
		for (( i = 0; i < ${#hp_media_fc_port[@]}; i++ ))
		do
			itr=(${hp_media_fc_port[$i]})
			if [ "${itr[0]}" = "$bpn" ]
			then
				mediatrc "Got media details ${itr[@]} - ${#itr[@]}"
				for (( j = 1; j <  ${#itr[@]}; j++ ))
				do
					if [ "${itr[$j]}" = "$serial" ]
					then
						mediatrc "Valid media ${itr[0]} ${itr[$j]}"
						valid=1
						return $valid
					fi
				done
			fi
		done

		if [ $skip_ge_port_media -eq 0 ]
		then
			for (( i = 0; i < ${#hp_media_ge_port[@]}; i++ ))
			do
				itr=(${hp_media_ge_port[$i]})
				if [ "${itr[0]}" = "$bpn" ]
				then
					mediatrc "Got media details ${itr[@]} - ${#itr[@]}"
					for (( j = 1; j <  ${#itr[@]}; j++ ))
					do
						if [ "${itr[$j]}" = "$serial" ]
						then
							mediatrc "Valid media ${itr[0]} ${itr[$j]}"
							valid=1
							return $valid
						fi
					done
				fi
			done
		fi
	fi

	# Validate non-Brocade branded media - from exception list
	for (( i = 0; i < ${#non_brcd_media[@]}; i++ ))
	do
		itr=(${non_brcd_media[$i]})

		# Remove any * from PN and break PN into 2 parts
		# i.e. 1st part before * and 2nd part after * (if any)
		pn1=`echo ${itr[0]} | awk -F"**" '{print $1}'`
		pn2=`echo ${itr[0]} | awk -F"**" '{print $2}'`
		if [[ "$bpn" == "$pn1"*"$pn2" ]]
		then
			mediatrc "Got media details ${itr[@]} - ${#itr[@]}"
			for (( j = 1; j <  ${#itr[@]}; j++ ))
			do
				# If SN prefix contains wild char "\*", then remove it before
				# doing comparision with Serial Number
				if [[ "$serial" == "$(echo ${itr[$j]} | sed '/\\\*/s///g')"* ]]
				then
					mediatrc "Valid media ${itr[0]} ${itr[$j]}"
					valid=1
					return $valid
				fi
			done
		fi
	done

	mediatrc "Invalid media $bpn $serial"
	return $valid
}

validate_media()
{
	extn_gen7med_chk=$1

	# Gether media info across all VFs on this system. Collect Brocade Part
	# Number, Serial Number & Vendor Name corresponding to all media plugged
	# into this system. Also get port number where media has been plugged into.
	#
	# Note - This script may fail to get media info if media or port or blade or
	#        switch is in Faulted state or blade is in powered Off state.
	#

	# If extn_gen7med_chk is set to EXTN_GEN7MED_CHK, then this function is
	# intended to check if any Gen7 media has been plugged into extn platforms
	# such as Awing, Harpoon etc. This is set, when downgrade from 9.x to 8.x
	# is attempted and hence downgrade may need to be blocked since 8.x may
	# not have support for Gen7 secured media.
	#
	# If extn_gen7med_chk is not set, then this function is invoked for media
	# validation on all platforms as part of upgrade from 8.x to 9.x
	#
	if [ "$extn_gen7med_chk" = "EXTN_GEN7MED_CHK" ]
	then
		# Check if this chassis has any extension blade or
		# if this is an extension pizzabox
		extn_blade_slots=$(correcthost /fabos/cliexec/slotshow -m 2>${NULL} | grep -w $extn_blade_id | awk '{print $1}')

		# If neither extn pizza box nor extn blade present then return success
		if [ "$SWBD" != "SWBD178" -a "$extn_blade_slots" = "" ]
		then
			mediatrc "Not an extension platform"
			return $STS_OK
		fi
	fi

	medialog "Gathering info of all media plugged into this system ..."
	media_info=(`correcthost_all_vfs /fabos/cliexec/sfpshow -all 2>${NULL} | grep -e Port -e Name -e PN -e Serial | grep -B1 -A2 Name | grep -v "^--" | sed '/Slot[ ]*/s///g' | sed '/GE/s/Port[ ]*/ge/g' | sed '/ GE: /s///g' | sed '/Port[ ]*/s///g' | sed '/ id/s///g' | awk '{for (i=3; i<NF; i++) printf $i; print $NF}' | sed '/:/s///g'`)

	media_info_sz=${#media_info[@]}
	per_port_media_info=4
	num_media=`expr $media_info_sz \/ $per_port_media_info`

	# Cross check num_media calculated above by re-issuing sfpshow
	num_valid_media=`correcthost_all_vfs /fabos/cliexec/sfpshow 2>${NULL} | grep Vendor | wc -l`
	if [ $num_media -ne $num_valid_media ]
	then
		mediatrc "Warning: Some issue encountered while gathering media info"
		mediatrc "Warning: num_media=$num_media and num_valid_media=$num_valid_media"
	fi

	# If no media plugged in, then return
	if [ $num_media -eq 0 ]
	then
		medialog "No media found"
		return $STS_OK
	fi

	# If media validation for fcoe port needs to be skipped, then check if
	# system has any fcoe blades
	fcoe_blade_slots=$(correcthost /fabos/cliexec/slotshow -m 2>${NULL} | grep -w $fcoe_blade_id | awk '{print $1}')

	# Now parse media info corresponding to each port and validate the same
	# against media support matrix
	# Each port's media info is in following order
	#    port-number
	#    media-vendor-name - All blank space are removed in vendor name
	#    media-part-number
	#    media-serial-number - We are interested in first 3 letters

	medialog "Validating $num_media ports which have media plugged in "
	bad_media=0

	for (( m_itr = 0; m_itr < $media_info_sz; ))
	do
		pt=${media_info[$m_itr+0]}
		pt_bpn=${media_info[$m_itr+2]}
		pt_serial=(${media_info[$m_itr+3]})
		pt_serial=`echo ${pt_serial:0:3}`
		pt_vendor=${media_info[$m_itr+1]}

		# Skip Gen7 media validation for non-extn blades
		if [ "$extn_gen7med_chk" = "EXTN_GEN7MED_CHK" -a "$SWBD" != "SWBD178" ]
		then
			# Get slot number
			slot=`echo $pt | sed '/\/.*/s///g'`
			# Check if this slot# corresponds to that of extn blade
			echo $extn_blade_slots | grep -w $slot 1> ${NULL} 2>&1
			if [ $? -eq 1 ]
			then
				mediatrc "Skipping port $pt media validation on non-extn blade"
				m_itr=`expr $m_itr + $per_port_media_info`
				continue
			fi
		fi

		validate_media_bpn_serial $pt_bpn $pt_serial $pt_vendor $pt $extn_gen7med_chk
		if [ $? -eq 0 ]
		then
			mediatrc "Port $pt does not contain valid Brocade media"
			mediatrc "Port $pt, BPN $pt_bpn, Serial Prefix $pt_serial, Vendor $pt_vendor"
			if [ -z "$BAD_MEDIA_PORTS" ]
			then
				BAD_MEDIA_PORTS=$pt
			else
				BAD_MEDIA_PORTS=$BAD_MEDIA_PORTS,$pt
			fi
			bad_media=`expr $bad_media + 1`
		fi

		m_itr=`expr $m_itr + $per_port_media_info`
	done

	if [ $bad_media -ne 0 -a ! -z "$BAD_MEDIA_PORTS" ]
	then
		# Error string is different for generic media validation than that for
		# gen7 media validation on extnesion platform.
		if [ "$extn_gen7med_chk" != "EXTN_GEN7MED_CHK" ]
		then
			medialog "WARNING: Total $bad_media ports do not have valid Brocade Media."
			MEDIA_PIRACY_VALIDATION_FAILED=$(eval echo "$MEDIA_PIRACY_VALIDATION_FAILED")
			BNA_MEDIA_PIRACY_VALIDATION_FAILED=$(eval echo "$BNA_MEDIA_PIRACY_VALIDATION_FAILED")
			# Explicit call to add_err_status since error strings were changed
			add_err_status "$MEDIA_PIRACY_VALIDATION_FAILED" "$BNA_MEDIA_PIRACY_VALIDATION_FAILED"
		else
			medialog "WARNING: Total $bad_media ports have Gen7 Brocade Media."
			EXTN_GEN7_MEDIA_VALIDATION_FAILED=$(eval echo "$EXTN_GEN7_MEDIA_VALIDATION_FAILED")
			BNA_EXTN_GEN7_MEDIA_VALIDATION_FAILED=$(eval echo "$BNA_EXTN_GEN7_MEDIA_VALIDATION_FAILED")
			# Explicit call to add_err_status since error strings were changed
			add_err_status "$EXTN_GEN7_MEDIA_VALIDATION_FAILED" "$BNA_EXTN_GEN7_MEDIA_VALIDATION_FAILED"
		fi
		return $STS_ERR
	fi

	return $STS_OK
}


###########################################################
#             Media Piracy section - End                  #
###########################################################

G620="183.0"
G630="184.1"
check_4g_eport()
{
	$ECHO check_4g_eport
	if [ -n "$TYPE" ]; then
		$ECHO "Running firmwarerestore"
		return $STS_OK
	fi
	# Check for REY32_BLADE_ID
	rey32=`correcthost /fabos/cliexec/slotshow -m | awk '{if ($4 == 218) print $1}'`
	swtype=`correcthost /fabos/bin/switchshow | awk '/switchType/ {print $2}'`
	# Check the switch type is G620 or G630 or Rey32 slot
	if [[ $swtype == $G620 || $swtype == $G630 || $rey32 ]]; then
		if [[ "$rey32" != "" ]]; then
			ports_with_4g_eports=`correcthost_all_vfs /fabos/bin/switchshow -slot $rey32 | grep -i "online" | grep -i "E-Port\|EX-Port" | grep -i "N4\|4G" | awk '{print $1 }'`
		else
			ports_with_4g_eports=`correcthost_all_vfs /fabos/bin/switchshow | grep -i "online" | grep -i "E-Port\|EX-Port" | grep -i "N4\|4G" | awk '{print $1 }'`
		fi
		if [[ "$ports_with_4g_eports" == "" ]]; then
			return $STS_OK;
		else
			$ECHO "4G EPorts configured on ports $ports_with_4g_eports"
			UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR=$(eval echo "$UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR")
			BNA_UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR=$(eval echo "$BNA_UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR")
			# Explicit call to add_err_status since error strings were changed
			add_err_status "$UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR" "$BNA_UNSUPPORTED_4G_EPORT_ON_DOWNGRADE_ERR"
			return $STS_ERR;
		fi
	else
		return $STS_OK;
	fi
}

check_rsc_enabled() {
   rsc=`cat /etc/fabos/fabos.0.conf| grep "cal.esrs.rscstatus" | /usr/bin/cut -d':' -f 2`
   if [ ! -z "$rsc" ]; then
     if [ "$rsc" -eq "1" ];then
      add_err_status "$RSC_NOT_SUPPORTED" "$BNA_RSC_NOT_SUPPORTED"
      return $STS_ERR
    fi
   fi
      return $STS_OK

}

check_app_hdr_cfg() {
	app_hdr=`/fabos/cliexec/portcfgshow| grep -i "app header"| grep -i "ON"`
	if [ "$?" -eq "0" ]; then
		return $STS_ERR
	else
		return $STS_OK
	fi	
}

check_app_header_config() {
	if [ $VF_ENABLED -ne $STS_OK ]; then
		for_all_contexts check_app_hdr_cfg
	else
		check_app_hdr_cfg
	fi
	if [ "$?" -eq "0" ]; then
		return $STS_OK
	else
		return $STS_ERR
	fi
}

check_cfs_v2_profile_active() {

	ag_mode_enabled
	if [ $? -ne 0 ]
	then
		return $STS_OK
	fi

	case ${SWBD##SWBD} in
	'179' | '180' | '181' | '189')
			cfsver=`cat /etc/fabos/cfs.0.conf| grep -i "cfs.profile_type" | cut -d ':' -f 2`
			if [ $cfsver -eq 2 ]; then
				add_err_status "$CFS_V2_PROFILE_ACTIVATED"
				return $STS_ERR
			else
				return $STS_OK
			fi
		;;
	esac
	return $STS_OK
}

check_maintenance_service_shell()
{
	if [ -z $TYPE ]; then
		service_shell_supported=`/bin/grep -c "SERVICE_SHELL_SUPPORTED" $NEW_PREINST_FILE`
	else
		service_shell_supported=`/bin/grep -c "SERVICE_SHELL_SUPPORTED" /mnt/sbin/preinst`
	fi

	if [ $service_shell_supported -ne 0 ]; then
		# The new firmware supports this feature so ok to proceed.
		return $STS_OK
	fi

	err_ret=0
	FILE="/fabos/users/maintenance/.service.db"
	if [ -f $FILE ]; then
		add_err_status "$SERVICE_SHELL_RESET" "$BNA_SERVICE_SHELL_RESET"
		err_ret=1
	fi

	pizza=`/fabos/bin/slotshow | grep -c "Not supported on this platform"`
	is_fwdl_arg "s"
	local singlemode=$?

	if [ $pizza -eq 0 -a $singlemode -ne 0 ]; then
		if [ $ACTIVECP ]; then
			isActiveCp=1
		else
			isActiveCp=0
		fi
		if [ "$isActiveCp" -eq 1 ]; then
			rshret=`/usr/bin/rsh -n $(otherhost) 'if [ -f /fabos/users/maintenance/.service.db ]; then echo 1; else echo 0; fi || echo $?' 2>/dev/null`
			if [ "$rshret" -eq 1 ]; then
				add_err_status "$SERVICE_SHELL_RESET_STANDBY" "$BNA_SERVICE_SHELL_RESET_STANDBY"
				err_ret=1
			fi
		fi
	fi
	if [ $err_ret -ne 0 ]; then
		return $STS_ERR
	else
		return $STS_OK
	fi
}

check_maintenance_factory_shell()
{
	err_ret=0
	FILE="/var/log/factoryauth_file"

	if [ -f $FILE ]; then
		add_err_status "$FACTORY_SHELL_RESET" "$BNA_FACTORY_SHELL_RESET"
		err_ret=1
	fi

	pizza=`/fabos/bin/slotshow | grep -c "Not supported on this platform"`
    is_fwdl_arg "s"
    local singlemode=$?

    if [ $pizza -eq 0 -a $singlemode -ne 0 ]; then
		if [ $ACTIVECP ]; then
			isActiveCp=1
		else
			isActiveCp=0
		fi
		if [ "$isActiveCp" -eq 1 ]; then
			rshret=`/usr/bin/rsh -n $(otherhost) 'if [ -f /var/log/factoryauth_file ]; then echo 1; else echo 0; fi || echo $?' 2>/dev/null`
			if [ "$rshret" -eq 1 ]; then
				add_err_status "$FACTORY_SHELL_RESET_STANDBY" "$BNA_FACTORY_SHELL_RESET_STANDBY"
				err_ret=1
			fi
		fi
	fi
	if [ $err_ret -ne 0 ]; then
		return $STS_ERR
	else
		return $STS_OK
	fi
}

check_userid_shell_status()
{
	inv_user=0
	inv_shell=0
	for l in `/usr/bin/cut -d ':' -f 1,3,7 /etc/passwd`
	do
		uname=`/bin/echo $l | awk -F ':' {'print $1'}`
		uid=`/bin/echo $l | awk -F ':' {'print $2'}`
		shell=`/bin/echo $l | awk -F ':' {'print $3'}`;
		if [[ $inv_user -eq 0 ]]
		then
			if [[ "$uid" == "0" ]]
			then
				if [[ "$uname" != "root" ]]
				then
					inv_user=1 
				fi
			fi
		fi
		if [[ $inv_shell -eq 0 ]]
		then
			if [[ "$shell" == "/bin/bash" || "$shell" == "/bin/sh" ]]
			then
				if [[ "$uname" != "root" ]]
				then
					inv_shell=1
				fi	
			fi
		fi
	done
	if [[ $inv_user -ne 0 || $inv_shell -ne 0 ]]; then
		add_err_status "$ROOT_USERID_SHELL" "$BNA_ROOT_USERID_SHELL"
		return $STS_ERR
	else
		return $STS_OK
	fi
	
}

check_fips_inside_support()
{
   FIPSINSIDE=`CONFIGSHOW -all | /bin/grep "fips\.inside" | /usr/bin/cut -d ':' -f2`
   if [ "$FIPSINSIDE" == "" ];then
       return $STS_OK # handle cases where the fips.inside key does not exist
   fi
   if [ "$FIPSINSIDE" -ne "0" ];then
       return $STS_ERR # block if fips.inside config set to 1
   fi
   return $STS_OK
}

check_passwdcfg_adminlockout_consoleaccess()
{
   ADMINLOCKOUTCONACC=`CONFIGSHOW -all | /bin/grep "passwdcfg\.adminlockoutconsoleaccess" | /usr/bin/cut -d ':' -f2`
   if [ "$ADMINLOCKOUTCONACC" == "" ];then
      return $STS_OK
   fi
   if [ "$ADMINLOCKOUTCONACC" -ne "0" ];then
       return $STS_ERR # block if consoleaccess is enabled
   fi
   return $STS_OK
}

remove_webldebug_log()
{   
    if /bin/ls /var/log/weblsocket.txt* 1> /dev/null 2>&1; then
        /bin/rm -rf /var/log/weblsocket.txt* 2>/dev/null
    fi
    if /bin/ls /mnt/var/log/weblsocket.txt* 1> /dev/null 2>&1; then
        /bin/rm -rf /mnt/var/log/weblsocket.txt* 2>/dev/null
    fi
}

####################################################################
####################################################################
####################################################################
####################################################################
####################################################################
#                                                                  #
#     ALL FEATURE CHECK FUNCTIONS SHOULD BE ABOVE THIS SECTION     #
#                                                                  #
####################################################################
####################################################################
####################################################################
####################################################################
####################################################################

#
#
#
check_91_features()
{
	$ECHO check_91_features 
	TEST check_4g_eport

	# Block the user if any 9.1.1 legacy mode is disabled
	TEST check_ntp_legacy_mode

	# Warn user if any 9.1.0 NTP authentication features are present
	TEST check_ntp_auth_configured

	# warn the user if any 9.1.0 MAPS features are present
	check_910_maps_features_for_warning
	TEST check_910_maps_features_for_blocking

	# warn the user for v9.1.1 MAPS features while downgrading to v9.0x or v82x
	check_911_maps_features_for_warning

	# Only if we are downgrading to v9.0.0 and below, not for v9.0.1
	if [ $TO_MAJOR -eq 8 -o \( $TO_MAJOR -eq 9 -a $TO_MINOR -eq 0 -a $TO_PATCH -eq 0 \) ]; then
		# block the user if any 64G SFP is plugged-in
		TEST check_sfp_64G
		# warn the user if any 9.0.1 MAPS features are present
		check_901_warning_maps_features
		# block the user if any 9.0.1 MAPS features are present
		TEST check_901_blocking_maps_features
		# display warning message for tcptimeoutlevel
		TEST check_tcptolevel
		# warn the user if DC PSU is used (for wedge2)
		TEST check_dc_psu_error "$UNSUPPORTED_DC_PSU_ON_DOWNGRADE_ERR" "$BNA_UNSUPPORTED_DC_PSU_ON_DOWNGRADE_ERR"
	fi

	# warn the user if any 9.1 FC-LAG features are present
	TEST check_fclag_configured "FC-LAG is configured in the system, please delete the FC-LAG configuration first"

	TEST check_rsc_enabled

	TEST check_app_header_config "$APP_HDR_CFG_ENABLED" "$BNA_APP_HDR_CFG_ENABLED"

	TEST check_cfs_v2_profile_active 

	# warn the user if FIPS inside mode is enabled
	TEST check_fips_inside_support "$FIPSINSIDE_NOTSUPPORTED" "$BNA_FIPSINSIDE_NOTSUPPORTED"

	TEST check_maintenance_factory_shell

	TEST check_passwdcfg_adminlockout_consoleaccess "$UNSUPPORTED_ADMLCK_CONACC" "$BNA_UNSUPPORTED_ADMLCK_CONACC"
	return $STS_OK
}

#
# This is upgrade to 9.1 from 9.0 or 8.x case
#
check_pre_91_features()
{
    $ECHO check_pre_91_features

    TEST check_ethif_hd_config "$HALF_DUPLEX_CONFIG_PRESENT" "$BNA_HALF_DUPLEX_CONFIG_PRESENT"

    TEST check_fcoe_enodes "FCOE NUMBER OF ENODES is larger than 1000 in the system, please modify the configuration first"

    #
    # Block upgrade to 9.0 if any 8.1/8.2 common features are enabled.
    #
    check_pre_90_features

	check_is_all_9x_flows_deactivated


	# Added in FOS 9.1.0 for Traffic Isolation (TI) Zone, 
	# Frame Redirection (RD), and Broadcast zone deprecation check.
	# Check all VFs. If TI/RD/Broadcast Zones exist, post a warning message
	TEST check_TI_RD_BCAST_zone_deprecation_all_contexts

    # Check all VFs. If FA/QL/IPO Zones exist, fail the upgrade
    TEST check_FA_QL_IPO_zone_deprecation_all_contexts

	TEST check_pdcm_prohibit_all_contexts
	TEST check_ficon_portaddress_range_all_contexts
    confirm_eula_acceptance
    return $RET_CODE

}

#
# This function checks pre 9.0.0 features common to 8.1/8.2 to block upgrade
#
check_pre_90_features()
{
    $ECHO check_pre_90_features

	#Warning message for Chewbacca and Tom2 platforms
	if [ $CUR_PATCH -ne 1 ]; then
		 case ${SWBD##SWBD} in
       			'170')
			add_warn_status "$FDW_82_CHEWBACCA_WARN" "$FDW_82_CHEWBACCA_WARN"
		esac
	fi

	SNMP_USER_PASSWD_ENC=`CONFIGSHOW -all | /bin/grep "snmp.usmUserPaswdEncFlag" | /usr/bin/cut -d ':' -f2`
    if [ "$SNMP_USER_PASSWD_ENC" == "1" ];then
	    add_warn_status "$SNMP_USER_PASSWD_ENCRYPTION_WARN" "$BNA_SNMP_USER_PASSWD_ENCRYPTION_WARN"
            return $STS_OK
    fi


	check_maps_features_vf check_pre910_maps_nodewwn_dyn_grp_in_ag_mode "$MAPS_910_DYN_GRP_UPGRD_WARN" \
									"$BNA_MAPS_910_DYN_GRP_UPGRD_WARN" \
									"$MAPS_OPC_WARN"

	check_maps_features_vf check_maps_all_fru_rules_for_qt_configured "$MAPS_FRU_QT_WARN" "$BNA_MAPS_FRU_QT_WARN" "$MAPS_OPC_WARN"

	# Check to make sure Location ID is not set for any partition
	TEST check_location_id_all_contexts "$LOCATION_ID_SET" "$BNA_LOCATION_ID_SET"

	TEST check_default_password "$CHANGE_DEFAULT_PWD" "$BNA_CHANGE_DEFAULT_PWD"
	# Block upgrade to >=8.2.1 if extension certs filenames have
	# unsupported chars.
	TEST check_extn_certs_name "$EXTN_CERT_UNSUPP_FILENAME" "$BNA_EXTN_CERT_UNSUPP_FILENAME"

        # If IPSec is enabled in Active cp or pizza box, block upgrade and prompt user to disable it first
        # If IPSec is enabled in Standby cp, warn user that firmware upgrade will disable ipsec.
        TEST check_for_ipsec_feature "$IPSEC_DISABLE_WARN" "$BNA_IPSEC_DISABLE_WARN"

	TEST check_pre_v9_0_ciphers
	TEST check_userid_shell_status
	TEST_FIDS check_ficon_cup_addr_use
	TEST check_ipfilter_forward_rules "$IPFILTER_FORWARD_RULE_PRESENT" "$BNA_IPFILTER_FORWARD_RULE_PRESENT"
	handle_snmp

	# Block upgrade if swapped ports exists
	# Since we deprecated portswap feature in 9.0
	if [ $ACTIVE_MAJOR -lt 9 ]; then
		TEST_FIDS check_for_portswap "$PORTSWAP_DISABLE_ERR" "$BNA_PORTSWAP_DISABLE_ERR"
	fi

	# Block upgrade if portcfgalpa is configured on ports as the feature is deprecated in 9.0
	if [ $ACTIVE_MAJOR -lt 9 ]; then
		TEST_FIDS check_for_portcfgalpa "$PORTCFGALPA_ERR" "$BNA_PORTCFGALPA_ERR"
        fi
		
    # Block upgrade if any LD/LS ports present without Extended Fabrics license
    if [ $CUR_MAJOR -lt 9 ]; then
            eflicense=`/fabos/bin/licenseshow | grep -c "Extended Fabric"`
    else
        eflicense=`/fabos/sbin/license --show | grep -c "Extended Fabric"`
    fi
    if [ $eflicense -lt 1 ]; then
        TEST_FIDS check_for_ld_ls_noeflicense "$LD_LS_NOEFLICENSE_ERR" "$BNA_LD_LS_NOEFLICENSE_ERR"
    fi

	check_ca_bundle_update
}

#
# This function check all 9.0.1 features for downgrade to 9.0 or 8.2 or 8.1
#
check_901_features()
{
	$ECHO check_901_features
	TEST check_tcptolevel
	TEST check_sfp_8G_smartoptics
	return $STS_OK
}


G610LW_SWITCH_TYPE="170.5"

check_G610LW()
{   
	if [ -n "$TYPE" ]; then
		$ECHO "Running firmwarerestore"
		return $STS_OK
	fi

	tgt_fw_name=`(od --strings $RELEASE_FILE | grep "Fabric OS" | awk '{print $4}')`
	swtype=`/fabos/bin/switchshow | awk '/switchType/ {print $2}'`
	# HW is not G610LW platform, firmware version is *_lw FOS. block it
	# *_lw FOS can only be loaded on G610LW
	if [[ $tgt_fw_name == *"_lw"* ||  $tgt_fw_name == *"_LW"* ]]; then
		if [ $swtype != $G610LW_SWITCH_TYPE ]; then
			return $STS_ERR;
		else
		# all other cases, download can continue
			return $STS_OK;
		fi
	else
		return $STS_OK;
	fi
}


#
# This function checks 9.0.1 features to block downgrade to 9.0.0.
#
check_901_to_900_features()
{
	$ECHO check_901_to_900_features

	# warn the user if any 9.0.1 MAPS features are present
	TEST check_901_warning_maps_features

	# warn the user if DC PSU is used (for wedge2)
	TEST check_dc_psu_error "$UNSUPPORTED_DC_PSU_ON_DOWNGRADE_ERR" "$BNA_UNSUPPORTED_DC_PSU_ON_DOWNGRADE_ERR"

	TEST check_sfp_64G

	# Warn user if LDAP GC port configuration exists
	check_ldap_gc_configured
	
	# Warn user if LDAPS configuration exists
	check_ldaps_configured

	return $STS_OK
}

#
# This is to handle features downgrade from v9.1.1 to v9.1.0x
#
handle_911_to_910()
{
	$ECHO handle_911_to_910

	check_911_maps_features_for_warning

	TEST check_passwdcfg_adminlockout_consoleaccess $UNSUPPORTED_ADMLCK_CONACC $BNA_UNSUPPORTED_ADMLCK_CONACC
}

#
# This is to handle feature downgrade form v9.1.1x to v9.1.1
#
handle_911x_to_911()
{
	$ECHO handle_911x_to_911
	# applicable to fwdl not firmwarerestore
	if [ -z "$TYPE" ]; then
		# FWNAME is of "FabricOS9.1.1a" format
		patch=`echo $FWNAME | cut -f3 -d"."`
		if [ "$patch" == "1" ];then
			TEST check_passwdcfg_adminlockout_consoleaccess "$UNSUPPORTED_ADMLCK_CONACC" "$BNA_UNSUPPORTED_ADMLCK_CONACC"
		fi
	fi
}

#
# This is upgrade to 9.1 case
#
handle_to_91()
{
	$ECHO handle_to_91

	# downgrading from v911x to v911
	if [ \( $TO_MAJOR -eq 9 -a $TO_MINOR -eq 1 -a $TO_PATCH -eq 1 \) ]; then
		handle_911x_to_911
		remove_webldebug_log 
	fi

	# downgrading from v911 to v910x
	if [ \( $TO_MAJOR -eq 9 -a $TO_MINOR -eq 1 -a $TO_PATCH -eq 0 \) ]; then
		handle_911_to_910
	fi

	# We don't allow 8.x and previous to upgrade to this version
	# Block the disruptive upgrade from 8.2.x to 9.1.0 to mandate TruFOS
	#
	if [ $CUR_MAJOR -le 8 ]; then
		add_err_status "$UNSUPPORTED_UP_VERMSG" "$BNA_UNSUPPORTED_UP_VERMSG"
		return $STS_ERR
	fi

	#
	# Block upgrade from 9.0.0/9.0.0x to 9.x if there are any ICL EX-ports
	# on non-VF switches in GEN6+/GEN7 chassis.
	#
	if [ $CUR_MAJOR -eq 9 -a $CUR_MINOR -eq 0 -a $CUR_PATCH -eq 0 ]; then
		TEST check_ex_ports_ICL_configured
	fi

	#
	# Block upgrade to 9.x_G610LW if the switch is not G610LW
	#
	if [ $TO_MAJOR -ge 9 ]; then
		TEST check_G610LW "$UNSUPPORTED_G610LW_ERR" "$BNA_UNSUPPORTED_G610LW_ERR"
	fi

        #
        # Block upgrade if any 9.0 specific features are enabled.
        #
        check_pre_91_features

	# Display root account disabled warning message for upgrade to 910
	add_warn_status "$ROOT_DISABLED_WARN_MSG" "$BNA_ROOT_DISABLED_WARN_MSG"

	# Display RTA feature enabled warning message for upgrade to 910
	add_warn_status "$RTA_ENABLED_WARN_MSG" "$BNA_RTA_ENABLED_WARN_MSG"

	# warn the user if FIPS inside mode is enabled and downgrading to <=910
	if [ $TO_PATCH -eq 0 ]; then
		TEST check_fips_inside_support "$FIPSINSIDE_NOTSUPPORTED" "$BNA_FIPSINSIDE_NOTSUPPORTED"
	fi

	TEST check_maintenance_service_shell

        return $RET_CODE
}

#
# This is downgrade from 9.1 to 9.0 case
#
handle_91_to_90()
{
        $ECHO handle_91_to_90

        #
        # Block downgrade if any 9.1 specific features are enabled.
        #
        check_91_features

	# Display root account password reset warning message for downgrade from 910 to 90
	add_warn_status "$ROOT_PASSWORD_RESET_WARN_MSG" "$BNA_ROOT_PASSWORD_RESET_WARN_MSG"

	TEST check_maintenance_service_shell

	return $RET_CODE
}

#
# This is downgrade to 8.2 or lower case
#
handle_to_82_lower()
{

	$ECHO handle_to_82_lower

	# Block downgrade to version 2.0.0 on AMP
	if [ ${SWBD##SWBD} == '171' ]; then
		if [ $TO_MAJOR -eq 2 -a $TO_MINOR -le 1 -a $TO_PATCH -eq 0 ]; then
			add_err_status "$UNSUPPORTED_FWDL_AMP" "$BNA_UNSUPPORTED_FWDL_AMP"			
			return $STS_ERR
		fi
	fi

	add_err_status "$UNSUPPORTED_DL_VERMSG" "$BNA_UNSUPPORTED_DL_VERMSG"
	return ${STS_ERR}
}


#
# main()
#
#$ECHO Requested version is ${TO_MAJOR}.${TO_MINOR}.${TO_PATCH} Type is $TYPE
if [ -z $TYPE ]; then
	TEST check_hcl_switchstate "$SWITCH_FAULTY_MSG" "$BNA_SWITCH_FAULTY_MSG"
	RET=$?
	if [ $RET != $STS_OK ]; then
		exit $RET_CODE
	fi

	#
	# clean up to free up disk space on /mnt before firmwaredownload
	#
	$ECHO removing tracedump.dmp
	rm -f /mnt/var/tracedump.dmp
	# Overwrite raslog.int and raslog.ext file with FWDL version
	# This ensures that we do not overwrite the raslog files of new standby with
	# new active CP files.
	RASLOG_INT_FILE=/mnt/etc/raslog.int
	RASLOG_EXT_FILE=/mnt/etc/raslog.ext

	echo "RASLOG" > $RASLOG_INT_FILE
	echo "RASLOG" > $RASLOG_EXT_FILE
fi
# Creating /mnt/dev/platform device file if not present
node="platform"
major=`grep $node\$ /proc/devices | cut -d ' ' -f 1`
if [ ! -e /mnt/dev/$node ];then
    mknod  /mnt/dev/$node c $major 0
fi

#
# Handle a specific firmware version
#
case "${TO_MAJOR}.${TO_MINOR}.${TO_PATCH}" in
    9.1.[0-9])
        handle_to_91
        RET=$?
    ;;
	9.0.[0-9])
        handle_91_to_90
        RET=$?
    ;;
    *)
        handle_to_82_lower
        RET=$?
	exit $RET
    ;;
esac


# Extension FWDL Prep
#
# Prior to performing any feature checks, attempt to prep extension
# platforms for FWDL to the target version. This will perform any
# necessary migrations that can occur automatically without impact
# to the user. If any user intervention is required for activated
# features, the feature checks in the 'handle_to_XX' routines will
# catch them.
prep_extn_features
# Perform main extension feature check. We process the version within the
# command, so we check it globally here instead of in the handle_to_xx
# routines.
TEST check_extn_features "$XFCIP_FEATURE_RESTRICTION" "$BNA_XFCIP_FEATURE_RESTRICTION"
EXT_RET=$?
if [ $EXT_RET != $STS_OK ]; then
	RET=$EXT_RET
fi

#
# Preinstall check fails
#
if [ $RET != $STS_OK ]; then
	prep_extn_features_abort
	exit $RET;
fi

#
# Preinstall checks passed - check for HCL readiness
#
# This will not actually prevent any firmware operation from continuing
# but will just print any warnings to the user and fall through to the
# normal FWDL prompt asking if they wish to proceed.
check_extn_hcl


if [ $TO_MAJOR -lt 8 ] || [ $TO_MAJOR -eq 8 -a $TO_MINOR -lt 1 ]; then
	cmd=`cat /etc/fabos/fabos.chassis.conf | grep "system.tcptimestamp"`
	if [ "$cmd" != "" ]; then
		mode="${cmd: -1}"
		if [ $mode == "0" ]; then
			echo "Warning.... !!!" \
				"The TCP timestamp is disabled now. After firmware downgrade, TCP timestamp will be enabled."
		fi	
	fi
fi

#
# Firmwaredownload check passes, return
#
if [ -z $TYPE ]; then
	$ECHO return code is $RET
	exit $RET
fi

MNT_PREINST="/mnt/sbin/preinst" # This is the new firmware being downloaded
PREINST="/sbin/preinst"		# This is the current / running firmware
#
# Build Configuration Compatibility Management scripts
#
preinst_ccm ()
{

  $ECHO "BASH_SOURCE=${BASH_SOURCE[0]}"

  if [[ "${BASH_SOURCE[0]}" == *"mnt"* ]]; then
    cfgccm="/mnt/etc/fabos/config/scripts/ccm"
  else
    cfgccm="/etc/fabos/config/scripts/ccm"
  fi

#  umask 0
  if [ ! -e "$cfgccm" ]; then
    echo "Error -- could not locate configuration CCM module $cfgccm"
    return $STS_ERR
  fi

  . $cfgccm
  rc=$?
  if [ $rc -ne 0 ]
  then
      $ECHO "Fail to load CCM module -- $cfgccm err=$rc"
      echo "Fail to set up CCM (CCM loading)"
      return $STS_ERR
  else
      do_ccm
      ccm_rc=$?
      if [ $ccm_rc -ne 0 ]
      then
	  echo "Fail to set up Configuration Compatibility Management scripts err=$ccm_rc"
	  do_ccm_cleanup 

	  return $STS_ERR
      fi	
  fi
  return $STS_OK
}

cfgut_preinst=`/fabos/cliexec/config get cfgut.preinst 2`
if [ ! -z ${cfgut_preinst+x} ] && [ "$cfgut_preinst" == "1" ]; then
   echo "cfgut.preinst enable"
   preinst_ccm
   exit 0
fi

#
# For firmwarerestore, we will perform the firmwarerestore here.
# it will not return to the caller. That is to workaround a
# 2.4.19 kernel and 2.3.6 glibc mismatch issue. (79299). Read
# more comments in fwdl_undo() in the fwdl.c file.
#
baddev=`bootenv BadRootDev 2>/dev/null`
upgrade=`bootenv Upgrade 2>/dev/null`
softupgrade=`bootenv SoftUpgrade 2>/dev/null`
osloader=`bootenv OSLoader 2>/dev/null`

dev_p=`bootenv OSRootPartition 2>/dev/null | cut -d ';' -f 1`
dev_s=`bootenv OSRootPartition 2>/dev/null | cut -d ';' -f 2`
kern_p=`bootenv OSLoader 2>/dev/null | cut -d ';' -f 1`
kern_s=`bootenv OSLoader 2>/dev/null | cut -d ';' -f 2`

mount_p=`cat /proc/mounts | grep " / " | grep -v rootfs |sed 's? .*??g;s?^.*dev/??g'`
mount_s=`cat /proc/mounts |grep "/mnt" | sed 's? .*??g;s?^.*dev/??g'`

if [ -n "$baddev" ]; then
	add_err_status "$FWDL_RUNNING_MSG" "$BNA_FWDL_RUNNING_MSG"
    	exit 1;
fi

if [ -n "$softupgrade" ]; then
	add_err_status "$FWDL_RUNNING_MSG" "$BNA_FWDL_RUNNING_MSG"
	exit 1;
fi

if [ -z "$upgrade" ]; then
	add_err_status "$FWRESTORE_DISALLOWED_MSG" "$BNA_FWRESTORE_DISALLOWED_MSG"
	exit 1;
fi

if [ "$upgrade" == /dev/$mount_s ]; then
	add_err_status "$FWRESTORE_DISALLOWED_MSG" "$BNA_FWRESTORE_DISALLOWED_MSG"
    	exit 1;
fi

#
# Build Configuration Compatibility Management scripts
#
preinst_ccm
ccm_rc=$?
if [ $ccm_rc -ne 0 ]; then
    add_err_status "Fail to set up the Configuration Compability Management"
    exit 1;
fi 

cfgut_preinst_noboot=`/fabos/cliexec/config get cfgut.preinst_noboot 2`
if [ ! -z ${cfgut_preinst_noboot+x} ] && [ "$cfgut_preinst_noboot" == "1" ]; then
   add_err_status "cfgut.preinst_noboot is enabled"
   exit 1
fi

MNT_POSTINST="/mnt/sbin/postinst" # This is the new firmware being downloaded
POSTINST="/sbin/postinst"		  # This is the current / running firmware
SSHD_CONFIG_FILE=/etc/sshd_config
SSHD_CONFIG_FILE_MNT=/mnt/etc/sshd_config
TMP_SSHD=/tmp/sshd_tmp
SSH_CONFIG_FILE_MNT=/mnt/etc/ssh_config
TMP_SSH=/tmp/ssh_tmp

ssh_rekeylimit_conversion() {
	new_fw_is_SV=$(/bin/grep -c "SSK_REKEY_LIMIT_CONVERSION_REQUIRED" $MNT_POSTINST) # grep in postinst of New fw
	cur_fw_is_SV=$( /bin/grep -c "SSK_REKEY_LIMIT_CONVERSION_REQUIRED" $POSTINST)    # grep in postinst of Current fw
	#Forward conversion
	if [ $cur_fw_is_SV -eq 0 -a $new_fw_is_SV -gt 0 ]; then
		ret=$(/bin/grep -c "RekeyInterval" $SSHD_CONFIG_FILE_MNT)
		if [ $ret -gt 0 ]; then
			/bin/sed "s/RekeyInterval/RekeyLimit default/" $SSHD_CONFIG_FILE_MNT > $TMP_SSHD
			/bin/mv $TMP_SSHD $SSHD_CONFIG_FILE_MNT
		fi
	#Backward conversion
	elif [ $new_fw_is_SV -eq 0 -a $cur_fw_is_SV -gt 0 ]; then
		ret=$(/bin/grep -c "RekeyLimit" $SSHD_CONFIG_FILE_MNT)
		if [ $ret -gt 0 ]; then
			/bin/sed "s/RekeyLimit default/RekeyInterval/" $SSHD_CONFIG_FILE_MNT > $TMP_SSHD
			/bin/mv $TMP_SSHD $SSHD_CONFIG_FILE_MNT
		fi
	fi
}

sshd_config_handling() {

	new_fw_is_SV=$(/bin/grep -c "SSHD_CONFIG_HANDLING_REQUIRED" $MNT_POSTINST)
	cur_fw_is_SV=$(/bin/grep -c "SSHD_CONFIG_HANDLING_REQUIRED" $POSTINST)

	## Serverkeybits , PrintLastlog and UsePrivilegeSeparation not required in fw_version >=v9.0
	## Forward conversion
	if [ $cur_fw_is_SV -eq 0 -a $new_fw_is_SV -gt 0 ]; then
		Printlastlog=$(/bin/grep -c "PrintLastLog" $SSHD_CONFIG_FILE_MNT)
		usepriv_sep=$(/bin/grep -c "UsePrivilegeSeparation" $SSHD_CONFIG_FILE_MNT)
		if [ $Printlastlog -gt 0 ]; then
			/bin/sed '/PrintLastLog/d' $SSHD_CONFIG_FILE_MNT > $TMP_SSHD
			/bin/mv $TMP_SSHD $SSHD_CONFIG_FILE_MNT
		fi
		if [ $usepriv_sep -gt 0 ]; then
			/bin/sed '/UsePrivilegeSeparation/d' $SSHD_CONFIG_FILE_MNT > $TMP_SSHD
			/bin/mv $TMP_SSHD $SSHD_CONFIG_FILE_MNT
		fi

		serverkeybits=$(/bin/grep -c "ServerKeyBits" $SSHD_CONFIG_FILE_MNT)
		if [ $serverkeybits -gt 0 ]; then
			/bin/sed '/ServerKeyBits/d' $SSHD_CONFIG_FILE_MNT > $TMP_SSHD
			/bin/mv $TMP_SSHD $SSHD_CONFIG_FILE_MNT
		fi
	## Backward conversion
	## UsePrivilegeSeparation and printlaslog entry gets added from openssh package when fwdl to <= v9.0,
	## Not adding those entries here, if present.
	elif [ $new_fw_is_SV -eq 0 -a $cur_fw_is_SV -gt 0 ]; then
		Printlastlog=$(/bin/grep -c "PrintLastLog" $SSHD_CONFIG_FILE_MNT)
		usepriv_sep=$(/bin/grep -c "UsePrivilegeSeparation" $SSHD_CONFIG_FILE_MNT)
		if [ $usepriv_sep -eq 0 ]; then
			/bin/echo 'UsePrivilegeSeparation no' >> $SSHD_CONFIG_FILE_MNT
		fi
		if [ $Printlastlog -eq 0 ]; then
			/bin/echo 'PrintLastLog no' >> $SSHD_CONFIG_FILE_MNT
		fi

	fi

        new_fw_is_SV=$(grep -c "SSHD_CONFIG_FILE_HOSTKEY" $MNT_POSTINST)
        cur_fw_is_SV=$(grep -c "SSHD_CONFIG_FILE_HOSTKEY" $POSTINST)

        ## Pre 9.1 SSHD config file update for no host keys
	if [ $new_fw_is_SV -eq 0 -a $cur_fw_is_SV -gt 0 ]; then
                GREP=`/usr/bin/which grep`
                CAT=`/usr/bin/which cat`
                RM=`/usr/bin/which rm`
                SED=`/usr/bin/which sed`

                ssh_host_keys_list="/etc/ssh_host_rsa_key \
                                /etc/ssh_host_dsa_key \
                                /etc/ssh_host_ecdsa_key"
                for i in $ssh_host_keys_list; do
			HOST="HostKey $i"
                        if $GREP "^#$HOST" $SSHD_CONFIG_FILE_MNT >/dev/null ; then
				$SED "s+#$HOST+$HOST+" $SSHD_CONFIG_FILE_MNT > $TMP_SSHD &&
                                $CAT $TMP_SSHD > $SSHD_CONFIG_FILE_MNT
                                $RM -f $TMP_SSHD
                        fi
                done
        fi
}

ssh_fips_config_handling() {
	new_fw=$(/bin/grep -c "SSH_CONFIG_FIPS_RELATED" $MNT_POSTINST)
	cur_fw=$(/bin/grep -c "SSH_CONFIG_FIPS_RELATED" $POSTINST)

	if [ $cur_fw -eq 0 -a $new_fw -gt 0 ]; then
		minprime=$(/bin/grep -c "MinPrime" $SSHD_CONFIG_FILE_MNT)
		ssh_minprime=$(/bin/grep -c "MinPrime" $SSH_CONFIG_FILE_MNT)
		ssh_serverhostkeysize=$(/bin/grep -c "ServerHostKeySize" $SSH_CONFIG_FILE_MNT)
		if [ $minprime -gt 0 ]; then
			/bin/sed '/MinPrime/d' $SSHD_CONFIG_FILE_MNT > $TMP_SSHD
			/bin/mv $TMP_SSHD $SSHD_CONFIG_FILE_MNT
		fi
		if [ $ssh_minprime -gt 0 ]; then
			/bin/sed '/MinPrime/d' $SSH_CONFIG_FILE_MNT > $TMP_SSH
			/bin/mv $TMP_SSH $SSH_CONFIG_FILE_MNT
		fi
		if [ $ssh_serverhostkeysize -gt 0 ]; then
			/bin/sed '/ServerHostKeySize/d' $SSH_CONFIG_FILE_MNT > $TMP_SSH
			/bin/mv $TMP_SSH $SSH_CONFIG_FILE_MNT
		fi
	fi
}

#SSH_HOSTKEY_CONVERSION_REQUIRED="Convert ssh hostkeys from openssh to PEM format during downgrade"
ssh_hostkey_conversion() {
	new_fw_is_SV=$(/bin/grep -c "SSH_HOSTKEY_CONVERSION_REQUIRED" $MNT_POSTINST) # grep in postinst of New fw
	cur_fw_is_SV=$( /bin/grep -c "SSH_HOSTKEY_CONVERSION_REQUIRED" $POSTINST)    # grep in postinst of Current fw
	if [ $ACTIVECP ]; then
		isActiveCp=1
	else
		isActiveCp=0
	fi
	#Downgrade conversion
	if [ $cur_fw_is_SV -gt 0 ]; then
		if [ $new_fw_is_SV -eq 0 ]; then
			IFS=' '
			ssh_host_keys_list="/mnt/etc/ssh_host_rsa_key /mnt/etc/ssh_host_dsa_key /mnt/etc/ssh_host_ecdsa_key"
			for i in $ssh_host_keys_list; do
				if [ -f $i ]; then
					new_format_key_present=$(/bin/grep -c "BEGIN OPENSSH" $i)
					if [ $new_format_key_present -gt 0 ]; then
						if [ $isActiveCp -eq 0 ]; then
							correcthost_to_curr_vfid "/usr/bin/ssh-keygen -p -f $i -P '' -N '' -m 'PEM' > /dev/null 2>&1"
						else
							/usr/bin/ssh-keygen -p -f $i -P '' -N '' -m 'PEM' > /dev/null 2>&1
						fi
					fi
				fi
			done
			unset IFS
		fi
	fi
}

# Remove debugexec logs generated by maintenance user
remove_debugexec_log()
{
	if ls /var/log/debugexec.log* 1> /dev/null 2>&1; then
		rm -rf /var/log/debugexec.log* 2>/dev/null
		rm -rf /mnt/var/log/debugexec.log* 2>/dev/null
	fi
}

maintenance_conversion() {

	new_fw_is_SV=$(/bin/grep -c "MAINTENANCE_SUPPORT" $MNT_POSTINST) # grep in postinst of New fw
	cur_fw_is_SV=$(/bin/grep -c "MAINTENANCE_SUPPORT" $POSTINST)    # grep in postinst of Current fw

	#Forward conversion
	if [ $cur_fw_is_SV -eq 0 -a $new_fw_is_SV -gt 0 ]; then

		#passwd file conversion
		/usr/sbin/chroot /mnt /fabos/libexec/passwd_convert /etc/passwd FWDL_CONVERSION MAINTENANCE_ADDITION > /dev/null 2>&1

		#shadow file conversion
		/usr/sbin/chroot /mnt /fabos/libexec/config_convert /etc/shadow FWDL_CONVERSION MAINTENANCE_ADDITION > /dev/null 2>&1

		#group file conversion
		#Since we have removed 'maintenance' entry from group.default to handle downgrade,
		#adding entry back to .default file to handle 9.0 restore
		ret=$(/bin/grep -c '^maintenance:' /mnt/etc/group.default)
		if [ $ret -eq 0 ]; then
			/bin/echo "maintenance::611:maintenance,root" >> /mnt/etc/group.default
		fi
		/usr/sbin/chroot /mnt /fabos/libexec/group_convert /etc/group FWDL_CONVERSION MAINTENANCE_ADDITION > /dev/null 2>&1

		#user.db file conversion
		export VF_ENABLED=$VF_ENABLED
		/usr/sbin/chroot /mnt /fabos/libexec/dummy_trigger /etc/fabos/user.db FWDL_CONVERSION MAINTENANCE_ADDITION > /dev/null 2>&1

	#Backward conversion
	elif [ $new_fw_is_SV -eq 0 -a $cur_fw_is_SV -gt 0 ]; then

		#passwd file conversion
		/fabos/libexec/passwd_convert /mnt/etc/passwd FWDL_CONVERSION MAINTENANCE_REMOVAL > /dev/null 2>&1

		#shadow file conversion
		/fabos/libexec/config_convert /mnt/etc/shadow FWDL_CONVERSION MAINTENANCE_REMOVAL > /dev/null 2>&1

		#group file conversion
		/fabos/libexec/group_convert /mnt/etc/group FWDL_CONVERSION MAINTENANCE_REMOVAL > /dev/null 2>&1

		#user.db file conversion
		/fabos/libexec/dummy_trigger /mnt/etc/fabos/user.db FWDL_CONVERSION MAINTENANCE_REMOVAL > /dev/null 2>&1
		/bin/cp /mnt/etc/fabos/user.db /etc/fabos/user.db > /dev/null 2>&1

		remove_debugexec_log
	fi
}

rbac_conversion()
{
			if [ $ACTIVECP ]; then
				isActiveCp=1
			else
				isActiveCp=0
			fi

			if [ "$isActiveCp" -eq 1 ]; then
			#Rbac and Userdb Update
				/bin/mv /etc/fabos/rbac/dynamic.default /etc/fabos/rbac/org_dynamic.default
				/bin/cp -p /mnt/etc/fabos/rbac/dynamic.default /etc/fabos/rbac/dynamic.default
				/fabos/libexec/trig_userdb_merge /mnt/etc/fabos/rbac/dynamic $CUR_MAJOR.$CUR_MINOR.$CUR_PATCH $TO_MAJOR.$TO_MINOR.$TO_PATCH
				/bin/cp -p /mnt/etc/fabos/rbac/dynamic /etc/fabos/rbac/dynamic
				/bin/mv /etc/fabos/rbac/org_dynamic.default /etc/fabos/rbac/dynamic.default
				/fabos/cliexec/config save /etc/fabos/rbac/dynamic
			fi
}

ldaps_protocol_handling() {

        new_fw_is_SV=$(/bin/grep -c "LDAPS_SUPPORT" $MNT_POSTINST) # grep in postinst of New fw
        cur_fw_is_SV=$(/bin/grep -c "LDAPS_SUPPORT" $POSTINST)    # grep in postinst of Current fw

        LDAP_FILE="/etc/fabos/ldap.conf"
        CHASSIS_CONFIG="/etc/fabos/fabos.chassis.conf"
        MNT_LDAP_FILE="/mnt/etc/fabos/ldap.conf"
        MNT_CHASSIS_CONFIG="/mnt/etc/fabos/fabos.chassis.conf"
        TMP_FILE="/tmp/ldap"

        if [ ! -f $LDAP_FILE ]; then
                # LDAP servers not configured
                return
        fi

        #Downgrade
        if [ $new_fw_is_SV -eq 0 -a $cur_fw_is_SV -gt 0 ]; then
                while read line
                do
                        columns=`echo $line | awk 'BEGIN{FS=" "};{print NF}'`
                        if [ $columns -eq 4 -o $columns -eq 9 ]; then
                                /bin/echo $line | /bin/awk '!($4="")' >> $TMP_FILE
                        else
                                /bin/echo $line >> $TMP_FILE
                        fi
                done < $LDAP_FILE
                mv $TMP_FILE $LDAP_FILE >/dev/null 2>&1

                while read line
                do
                        columns=`echo $line | awk 'BEGIN{FS=" "};{print NF}'`
                        if [ $columns -eq 4 -o $columns -eq 9 ]; then
                                /bin/echo $line | /bin/awk '!($4="")' >> $TMP_FILE
                        else
                                /bin/echo $line >> $TMP_FILE
                        fi
                done < $MNT_LDAP_FILE
                mv $TMP_FILE $MNT_LDAP_FILE >/dev/null 2>&1

                /bin/sed '/ldap.server.*.tlsMode/d' $CHASSIS_CONFIG > $TMP_FILE
                mv $TMP_FILE $CHASSIS_CONFIG

                /bin/sed '/ldap.server.*.tlsMode/d' $MNT_CHASSIS_CONFIG > $TMP_FILE
                mv $TMP_FILE $MNT_CHASSIS_CONFIG
        fi
}

root_account_enable_handling() {

	new_fw_is_SV=$(/bin/grep -c "ROOT_ACCOUNT_REMOVAL_SUPPORT" $MNT_POSTINST) # grep in postinst of New fw
	cur_fw_is_SV=$(/bin/grep -c "ROOT_ACCOUNT_REMOVAL_SUPPORT" $POSTINST)    # grep in postinst of Current fw

	PASSWD_FILE="/etc/passwd"
	MNT_PASSWD_FILE="/mnt/etc/passwd"
	TMP_PASSWD="/tmp/passwd"
	SHADOW_FILE="/etc/shadow"
	MNT_SHADOW_FILE="/mnt/etc/shadow"
	TMP_SHADOW="/tmp/shadow"

	#Downgrade 9.1.0 to pre-9.0.1a
	if [ $new_fw_is_SV -eq 0 -a $cur_fw_is_SV -gt 0 ]; then
		pwcfg_oldpass=`/fabos/cliexec/config get passwdcfg.oldpasswd 2`
		if [ -z "$pwcfg_oldpass" ]; then
			#if empty, add config back
			cfgkey="passwdcfg.oldpasswd"
    			cfgkey_type=2
    			cfgkey_value=0
			/fabos/cliexec/config set $cfgkey $cfgkey_type $cfgkey_value
		fi
		root_access=`/fabos/cliexec/config get root.access 5`
		if [ -z "$root_access" ]; then
			#if empty, add config back
			cfgkey="root.access"
    			cfgkey_type=5
    			cfgkey_value="consoleonly"
			/fabos/cliexec/config set $cfgkey $cfgkey_type $cfgkey_value
		fi
		/fabos/cliexec/config update

		#Convert /etc/passwd root entry to /bin/sh shell
		/bin/sed 's+root:/root:/bin/false+root:/root:/bin/sh+g' $PASSWD_FILE > $TMP_PASSWD
                /bin/mv $TMP_PASSWD $PASSWD_FILE
		/bin/chmod 600 $PASSWD_FILE
		/bin/sed 's+root:/root:/bin/false+root:/root:/bin/sh+g' $MNT_PASSWD_FILE > $TMP_PASSWD
                /bin/mv $TMP_PASSWD $MNT_PASSWD_FILE
		/bin/chmod 600 $MNT_PASSWD_FILE
		# Change root account password to old default in shadow for pre-9.1
		/bin/awk -F: '{ if ($1 == "root") $2="$6$xk/VD29GLswzCqlC$1o6RtIdi5qwTcXCLPRuh2x3JlOEa8sjSXmtAIjdIy1tTvxCdO3Yq7Kym9lf.V3remXI7nfXN.DpwaoYxlJy2R1";}1' OFS=: $SHADOW_FILE > $TMP_SHADOW
		/bin/mv $TMP_SHADOW $SHADOW_FILE
		/bin/chmod 600 $SHADOW_FILE
		/bin/awk -F: '{ if ($1 == "root") $2="$6$xk/VD29GLswzCqlC$1o6RtIdi5qwTcXCLPRuh2x3JlOEa8sjSXmtAIjdIy1tTvxCdO3Yq7Kym9lf.V3remXI7nfXN.DpwaoYxlJy2R1";}1' OFS=:  $MNT_SHADOW_FILE > $TMP_SHADOW
		/bin/mv $TMP_SHADOW $MNT_SHADOW_FILE
		/bin/chmod 600 $MNT_SHADOW_FILE		
	fi
    	
}


#Dynamic RBAC conversion
rbac_conversion

#*******SSH host key conversion
ssh_hostkey_conversion

#*******SSH rekey limit conversion
ssh_rekeylimit_conversion

### PrivilegeSeparation, ServerKeybits and PrintLastlog Handling
sshd_config_handling

### MinPrime, ServerHostKeySize Handling
ssh_fips_config_handling

#***maintenenance account conversion
maintenance_conversion

#***** LDAPS support
ldaps_protocol_handling

#***** Root account removal support
root_account_enable_handling

# The following steps restores the old RBAC dynamic db
if [ $CUR_MAJOR -eq 7 -a $TO_MAJOR -eq 7 ]; then
	/usr/sbin/chroot /mnt /fabos/libexec/userdb_convert $CUR_MAJOR.$CUR_MINOR $TO_MAJOR.$TO_MINOR > /dev/null 2>&1
	cp /mnt/etc/fabos/rbac/dynamic /etc/fabos/rbac/dynamic
fi

#Push Manufacturing key to SP
if [ -f '/fabos/libexec/spmPublicKeyUpdate' ] ; then
	/fabos/libexec/spmPublicKeyUpdate
fi

# Resotoring only the 8548 and 440epx prom images
echo "Restoring the PROM image ..."
if [ -s /mnt/boot/bootrom.bin ]; then
    /usr/sbin/chroot /mnt /sbin/prominst
fi

bootenv OSRootPartition "$dev_s;$dev_p"

if [ -n "$osloader" ] ; then
	bootenv OSLoader "$kern_s;$kern_p"
fi
bootenv Upgrade "/dev/$dev_s"
bootenv SoftUpgrade "commit"

bootenv bootcmd "run linux_bootcmd"

if [ $CUR_MAJOR -eq 6 -a $CUR_MINOR -le 2 ]; then
echo "The system is rebooting now!! After reboot, firmwarecommit" \
    "will be started and the partitions will be restored to the" \
    "original firmware."
/fabos/cliexec/reboot -s -r FirmwareDownload -f
fi

exit 0
FW_FUNC_MAP="XRzwD2sofjWgsYvTbt2JI6Drr+/FFIr34Be0qxytC1bSXGAUcvX6KwneOj3CZDED
+sQFAmX3MpGzU59Kog17d9mu07wBD4OenJv7vH7lXIAwetlbfOeq4ozDSm+PwrhG
HFo9wYsk7FAuyRyj1xrE6r7d6gn4P1qhhadMB7XVe6F65aRUmw56xzwTShszSd1x
kaA/0W2G0iKEYpkjM6icFnSpTHD1dknIiUTMzQ1DswsVCJ2LgfXKCFlqiNIgLtQ1
LJddOMiGoWZr/B6bNNXVXXLV7jf5TIP0wg/KSeSX6KxKxuOeT1J9WBK/Q2kljcWt
AxEuBzAfMt77xQaqH0hEM8AZCGN666cLibwqtq3Glh3cwvQzcfzH1HU27KbxEMIm
2wOCVcC5lT79AIGLRKO1ZxcONp09cMqYijCC44wFfEtxmBuKi2U7MF9XgGcsi21X
00jOo3pSuw8uhEo1XB+3pK2FlDvXIo/PvcyCc9HBDvhDRRIfYnNEMNccO65SGywK
1M9VDZKS2qntBetTF5FUoM9qNWXinEuqS1N9JlWM4DLNtMlnXztFSaQD8LkUeN59
xbqcwODht1pfYoayeoXQmOLctcu5vct5JSEnOYFiXJfKQXyr61YVXd9kv7Fbm3S2
o91kbsKomwggGR9INkGjOVZpWIK3kYLxzhXOLQ+6pMg=FW_FUNC_MAP="
: <<'NEW_EULA_TEXT'

*************************************************************************
* BROCADE FABRIC OPERATING SYSTEM AND FEATURE LICENSES AND LICENSE KEYS *
*************************************************************************

END USER LICENSE AGREEMENT
==========================
THIS END USER LICENSE AGREEMENT ("Agreement") GOVERNS THE DOWNLOAD, INSTALLATION, USE, POSTING, DISTRIBUTING AND  OTHERWISE MAKING AVAILABLE OF  BROCADE'S FABRIC OPERATING SYSTEM ("FOS") SOFTWARE AND/ OR USE OF BROCADE FEATURE LICENSES AND LICENSE KEYS THAT ACTIVATE FOS OR FUNCTIONALITY WITHIN FOS, AND ACCOMPANYING DOCUMENTATION (collectively the "Software"). BY DOWNLOADING, INSTALLING, USING, POSTING, DISTRIBUTING OR OTHERWISE MAKING AVAILABLE THE SOFTWARE, OR BY PURCHASING, CONVERTING A TRANSACTION KEY INTO A LICENSE KEY, OR INSTALLING A LICENSE OR LICENSE KEY, YOU ARE AGREEING TO BE BOUND ON AN ONGOING BASIS BY THE TERMS AND CONDITIONS HEREIN, WHICH MAY BE UPDATED BY BROCADE FROM TIME TO TIME. IF AT ANY TIME YOU DO NOT AGREE TO ALL OF THE TERMS OF THIS AGREEMENT, PROMPTLY STOP USE OF THE SOFTWARE AND DESTROY ALL COPIES OF THE SOFTWARE IN YOUR POSSESSION OR CONTROL, AND CERTIFY IN WRITING TO BROCADE SUCH CESSATION OF USE AND DESTRUCTION.

Single User License
===================
Subject to the terms and conditions of this Agreement and payment of the applicable license fees, Brocade Communications Systems LLC ("Brocade") and its suppliers grant to you ("End User") a non-exclusive, non-transferable, non-assignable, non-sub licensable license to use the Software in object code form (in the case of FOS) solely for the purpose of operating Brocade storage area networking switches in accordance with the section entitled "Restrictions" below. End User may make such backup copies of the Software as may be necessary for End User's lawful use, provided End User affixes to such copies all trademark, copyright, patent, and notices of other proprietary rights that appear on the original.

FOS Licenses and License Keys
=============================
FOS Licenses are used to activate FOS features or functionality in Brocade switches.  FOS Licenses shall only be purchased from a Brocade authorized distributor or official OEM partner, and FOS License Keys shall only be obtained through Brocade's License Portal or an authorized OEM License Portal and shall only be used on Brocade switches purchased through authorized channels.   FOS License Keys obtained from any other sources are not permitted to be used on any Brocade hardware products.  FOS Licenses and License Keys shall not be resold, assigned, sub-licensed or otherwise transferred to a third party. 

Open Source Software
====================
Certain components of the Software may incorporate "open source" software.  Open source software is subject to the applicable open source license (e.g., the GNU General Public License) and is not subject to this Agreement. To obtain a copy of the source code and applicable licensing terms for the open source software used by Brocade, please download the open source disclosure documents in the Broadcom Customer Support Portal (CSP).  If you do not have a CSP account or are unable to login, please contact your support provider for this information. 

Restrictions 
============
FOS is designed for use with Brocade hardware products sold through authorized sales channels, and with hardware platforms that are currently supported by Brocade.  End User acknowledges that use of the Software on hardware products that do not meet the above criteria, or which is inconsistent with the restrictions below, presents risks to the security and quality of Products and to the Software, for which Brocade disclaims all liability.  Except as otherwise expressly provided in this Agreement or expressly authorized by Brocade, End User shall have no right, and End User specifically agrees not to, and not to permit third parties to: (i) modify, adapt, or create derivative works based upon the Software; (ii) copy, in whole or in part, decompile, translate, reverse engineer, disassemble or otherwise reduce the Software to humanreadable form; (iii) install the Software on any products other than Brocade storage area networking switches purchased by End User through authorized channels for its own use or for resale expressly authorized by Brocade; (iv) install or use the Software on products in excess of the maximum number of Brocade storage area networking switches for which End User is licensed; (v) install the Software on any Brocade storage area networking switches that have reached End of Support as defined by Brocade, or refurbished devices, except with Brocade's prior written consent, (vi) use the Software on any devices not designated by Brocade for use with the Software (as notified through software release notes and other notices), (vii) download, or make available for use or download, any versions of the Software that have reached End of Support, as declared by Brocade, or (viii) sub-license or permit third parties to post or otherwise make available, or use the Software to provide support for Brocade products unless expressly authorized by Brocade.   

Upgrades and Additional Copies 
==============================
For purposes of this Agreement, "Software" shall also include any upgrades, updates, bug fixes or modified versions ("Upgrades") provided to End User by Brocade or an authorized distributor and for which End User had paid the applicable license fees, and any backup copies of the Software. Notwithstanding the foregoing, End User acknowledges and agrees that Brocade and its resellers and distributors shall have no obligation to provide any Upgrades. If Upgrades or additional copies of the Software are provided, End User acknowledges and agrees that it has no license or right to use such additional copies or Upgrades unless End User, at the time of acquiring such copy or Upgrade, already holds a valid license to the original Software for the applicable number of copies. 

No Support 
==========
Brocade may, but is not required to, provide technical support for the Software. 

Security Notice 
===============
Software may include security features that End User can use, along with other security tools, to implement increased security in End User's storage area network ("SAN"). However, use of the security features of the Software does not guarantee the security of End User's SAN or overall network. There are numerous factors that affect the security of a SAN, including, without limitation, correct installation and setup of the security features of Software and all related requirements, correctly configured security policies, selection of hardware and software (including network security tools), correct installation, configuration, and maintenance of the hardware and software, the interoperability of the various components of End User's SAN and End User's network, and a physically and electronically secure operating environment. In addition, Software may utilize digital certificates in connection with its access control features. Although digital certificates are a useful authentication security measure that improves overall security, they do not guarantee authenticity or security.  In designing the security of End User's SAN, it is End User's responsibility to evaluate all of these factors to ensure End User's SAN meets End User's security requirements. End User's experience may vary based on these and other factors. End User's use of Software, including the digital certificates, is subject to and governed by the terms of this Agreement and to End User's compliance with the policies and procedures for the use of the security features of Software and digital certificates, which may be made available to End User by Brocade from time to time. If Brocade becomes aware of a breach of the security of its digital certificate infrastructure, Brocade reserves the right to re-issue digital certificates. In that event, End User will be required to submit new certificate signing requests and install reissued certificates across End User's SAN. End User should plan for any network disruption that this may cause. END USER ACKNOWLEDGES THAT END USER HAS ACCESS TO SUFFICIENT INFORMATION TO ENSURE THAT END USER CAN MAKE AN INFORMED DECISION AS TO THE EXTENT TO WHICH END USER CHOOSES TO RELY ON DIGITAL CERTIFICATES AND OTHER SECURITY FEATURES IN SOFTWARE ("SECURITY"). 

Disclaimer of Warranty 
======================
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, BROCADE PROVIDES THE SOFTWARE 'AS IS' WITHOUT WARRANTY OF ANY KIND. BROCADE DOES NOT WARRANT THAT THE SOFTWARE IS ERROR FREE OR THAT END USER WILL BE ABLE TO OPERATE THE SOFTWARE WITHOUT PROBLEMS OR INTERRUPTIONS. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, BROCADE AND ITS LICENSORS, SUPPLIERS, DISTRIBUTORS AND RESELLERS DISCLAIM ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS, AND WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OR CONDITION OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, AND SATISFACTORY QUALITY OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. 

Limitation of Liability 
=======================
IN NO EVENT WILL BROCADE OR ITS LICENSORS, SUPPLIERS, RESELLERS OR DISTRIBUTORS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROCADE OR ITS LICENSORS, SUPPLIERS, RESELLERS OR DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO EVENT SHALL BROCADE'S OR ITS LICENSORS', SUPPLIERS', RESELLERS' OR DISTRIBUTORS' TOTAL LIABILITY TO END USER, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, EXCEED THE PRICE PAID BY END USER. THE FOREGOING LIMITATIONS SHALL APPLY EVEN IF THE ABOVE-STATED WARRANTY FAILS OF ITS ESSENTIAL PURPOSE. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO END USER. 

Proprietary Rights 
==================
The Software, including all intellectual property rights therein, is and will remain the sole and exclusive property of Brocade or its licensors. 

Term and Termination 
====================
This Agreement is effective until terminated. End User's license rights under this Agreement will terminate immediately without notice from Brocade if End User fails to comply with any provision of this Agreement. Upon termination, End User must stop using the Software and destroy all copies of Software and the corresponding license keys in its possession or control. 

Compliance with Law 
===================
Each party agrees to comply with all applicable laws, rules and regulations in connection with its activities under this Agreement. Without limiting the foregoing, End User acknowledges and agrees that the Software, including technical data, is subject to United States export control laws, including the United States Export Administration Act and its associated regulations, and may be subject to export or import regulations in other countries. End User agrees to comply strictly with all such regulations and acknowledges that End User has the responsibility to obtain licenses to export, re-export, or import the Software. 

Restricted Rights
=================
The Software under this Agreement is commercial computer software as that term is described in 48 C.F.R. 252.227-7014(a)(1). If acquired by or on behalf of a civilian agency, the U.S. Government acquires this commercial computer software and/or commercial computer software documentation subject to the terms of this Agreement as specified in 48 C.F.R. 12.212 (Computer Software) and 12.211 (Technical Data) of the Federal Acquisition Regulations ("FAR") and its successors. If acquired by or on behalf of any agency within the Department of Defense ("DOD"), the U.S. Government acquires this commercial computer software and/or commercial computer software documentation subject to the terms of this Agreement as specified in 48 C.F.R. 227.7202-3 of the DOD FAR Supplement ("DFAR") and its successors. 

General 
=======
This Agreement will bind and inure to the benefit of each party's successors and assigns, provided that End User may not assign or transfer this Agreement, in whole or in part, without Brocade's written consent. This Agreement shall be governed by and construed in accordance with the laws of the State of California, United States of America, as if performed wholly within the state and without giving effect to the principles of conflict of law. No failure of either party to exercise or enforce any of its rights under this Agreement will act as a waiver of such rights. If any portion hereof is found to be void or unenforceable, the remaining provisions of this Agreement shall remain in full force and effect. This Agreement is the complete and exclusive agreement between the parties with respect to the subject matter hereof, superseding and replacing any and all prior agreements, communications, and understandings (both written and oral) regarding such subject matter. 
 
Effective October 1, 2019 
NEW_EULA_TEXT
