# Global Variables
DEFAULTS10SERIAL=USSCI00002PRB003
DEFAULTS30SERIAL=MXE340005CIRB02D
DEFAULTS10BASESAS=500093D000000000
DEFAULTS30BASESAS=500093D000000000
DEFAULTS10MACADDRA=00093D010203
DEFAULTS10MACADDRB=00093D010204
DEFAULTS30MACADDRA=0093D00001A0
DEFAULTS30MACADDRB=0093D00001B0

# Function to handle user value confirmation
# $1 = Value selected (NO SPACES ALLOWED)
# CONFIRMED = TRUE if accepted, empty if not
UserConfirmation()
{
    CONFIRMED=
    if (( $# == 1 )); then
        echo
        echo "Value $1 Selected - Type YES If This Is Correct"
        read ANSWER
        if [[ "$ANSWER" == "YES" ]]; then
            CONFIRMED=TRUE
        fi
    else
        echo "Invalid UserConfirmation Function Call"
        exit 2
    fi
}

# Function to validate a strings length and contents
# $1 = Length to be matched (0 if unlimited)
# $2 = Validation to be used (Supported validation checks are: NONE, ALPHA, ALPHACAP, ALPHALOW, ALPHANUM, ALPHANUMCAP, ALPHANUMLOW, HEX, HEXNZ, HEXNF, HEXNZNF, HEXCAP, HEXCAPNZ, HEXCAPNF, HEXCAPNZNF, HEXLOW, HEXLOWNZ, HEXLOWNF, HWXLOWNZNF, NUMERIC)
# $3 = String to be checked
# LENGTHCHECK will be TRUE if the length matches and empty if not
# VALIDATIONCHECK will be TRUE if the validation is correct and empty if not
CheckString()
{
    LENGTHCHECK=
    VALIDATIONCHECK=
    if (( $# == 3 )); then
        if (( $1  < 0 )); then
            echo "ERROR: Negative Length Is Invalid"
            exit 2
        fi
        if (( $1  == 0 )); then
            LENGTHCHECK=TRUE
        else
            if [[ ${#3} == $1  ]]; then
                LENGTHCHECK=TRUE
            fi
        fi
        if [[ $2 == NONE ]]; then
            VALIDATIONCHECK=TRUE
        else
            CHECKSTRING=
            case $2 in
                ALPHA)
                    CHECKSTRING='\([A-Za-z]*\)'
                    ;;
                ALPHACAP)
                    CHECKSTRING='\([A-Z]*\)'
                    ;;
                ALPHALOW)
                    CHECKSTRING='\([a-z]*\)'
                    ;;
                ALPHANUM)
                    CHECKSTRING='\([A-Za-z0-9]*\)'
                    ;;
                ALPHANUMCAP)
                    CHECKSTRING='\([A-Z0-9]*\)'
                    ;;
                ALPHANUMLOW)
                    CHECKSTRING='\([a-z0-9]*\)'
                    ;;
                HEX|HEXNZ|HEXNF|HEXNZNF)
                    CHECKSTRING='\([A-Fa-f0-9]*\)'
                    ;;
                HEXCAP|HEXCAPNZ|HEXCAPNF|HEXCAPNZNF)
                    CHECKSTRING='\([A-F0-9]*\)'
                    ;;
                HEXLOW|HEXLOWNZ|HEXLOWNF|HEXLOWNZNF)
                    CHECKSTRING='\([a-f0-9]*\)'
                    ;;
                NUMERIC)
                    CHECKSTRING='\([0-9]*\)'
                    ;;
            esac
            CHECK=$(expr match "$3" $CHECKSTRING)
            if [ $2 == "HEXNZ" -o $2 == "HEXCAPNZNF" -o $2 == "HEXCAPNZ" -o $2 == "HEXCAPNZNF" -o $2 == "HEXLOWNZ" -o $2 == "HEXLOWNZNF" ]; then
                if (( $1 == 0 )); then
                    LENGTH=${#3}
                else
                    LENGTH=$1
                fi
                ZEROSTRING=
                COUNT=0
                while (( COUNT < LENGTH )); do
                    ZEROSTRING="$ZEROSTRING"0
                    (( COUNT++ ))
                done
                if [[ "$3" == "$ZEROSTRING" ]]; then
                    CHECK=
                fi
            fi
            if [ $2 == "HEXNF" -o $2 == "HEXCAPNZNF" -o $2 == "HEXCAPNF" -o $2 == "HEXCAPNZNF" -o $2 == "HEXLOWNF" -o $2 == "HEXLOWNZNF" ]; then
                if (( $1 == 0 )); then
                    LENGTH=${#3}
                else
                    LENGTH=$1
                fi
                FSTRING=
                UPSTRING=
                COUNT=0
                while (( COUNT < LENGTH )); do
                    FSTRING="$FSTRING"F
                    if [[ ${3:$COUNT:1} == f ]]; then
                        UPSTRING="$UPSTRING"F
                    else
                        UPSTRING="$UPSTRING"${3:$COUNT:1}
                    fi
                    (( COUNT++ ))
                done
                if [[ "$UPSTRING" == "$FSTRING" ]]; then
                    CHECK=
                fi
            fi
            if [[ "$CHECK" == "$3" ]]; then
                VALIDATIONCHECK=TRUE
            fi
        fi
    else
        echo "Invalid CheckString Function Call"
        exit 2
    fi
}

# Function to handle user input text
# $1 = User field prompt string (NO SPACES ALLOWED)
# $2 = Length to be matched (0 if unlimited)
# $3 = Validation to be used (Supported validation checks are: NONE, ALPHA, ALPHACAP, ALPHALOW, ALPHANUM, ALPHANUMCAP, ALPHANUMLOW, HEX, HEXNZ, HEXNF, HEXNZNF, HEXCAP, HEXCAPNZ, HEXCAPNF, HEXCAPNZNF, HEXLOW, HEXLOWNZ, HEXLOWNF, HWXLOWNZNF, NUMERIC)
# RESULT = User entered input
UserInput()
{
    RESULT=
    if (( $# == 3 )); then
        case $3 in
            NONE)
                ;;
            ALPHA)
                VALIDATIONSTRING="Alphabetic"
                ;;
            ALPHACAP)
                VALIDATIONSTRING="Alphabetic Upper Case"
                ;;
            ALPHALOW)
                VALIDATIONSTRING="Alphabetic Lower Case"
                ;;
            ALPHANUM)
                VALIDATIONSTRING="Alphabetic and Numeric"
                ;;
            ALPHANUMCAP)
                VALIDATIONSTRING="Alphabetic Upper Case and Numeric"
                ;;
            ALPHANUMLOW)
                VALIDATIONSTRING="Alphabetic Lower Case and Numeric"
                ;;
            HEX)
                VALIDATIONSTRING="Hexadecimal"
                ;;
            HEXNZ)
                VALIDATIONSTRING="Hexadecimal Non-Zero"
                ;;
            HEXNF)
                VALIDATIONSTRING="Hexadecimal Non-Hex F"
                ;;
            HEXNZNF)
                VALIDATIONSTRING="Hexadecimal Non-Zero Non-Hex F"
                ;;
            HEXCAP)
                VALIDATIONSTRING="Hexadecimal Upper Case"
                ;;
            HEXCAPNZ)
                VALIDATIONSTRING="Hexadecimal Upper Case Non-Zero"
                ;;
            HEXCAPNF)
                VALIDATIONSTRING="Hexadecimal Upper Case Non-Hex F"
                ;;
            HEXCAPNZNF)
                VALIDATIONSTRING="Hexadecimal Upper Case Non-Zero Non-Hex F"
                ;;
            HEXLOW)
                VALIDATIONSTRING="Hexadecimal Lower Case"
                ;;
            HEXLOWNZ)
                VALIDATIONSTRING="Hexadecimal Lower Case Non-Zero"
                ;;
            HEXLOWNF)
                VALIDATIONSTRING="Hexadecimal Lower Case Non-Hex F"
                ;;
            HEXLOWNZNF)
                VALIDATIONSTRING="Hexadecimal Lower Case Non-Zero Non-Hex F"
                ;;
            NUMERIC)
                VALIDATIONSTRING="Numeric"
                ;;
            *)
                echo "ERROR: Invalid Validation Type"
                exit 2
                ;;
        esac
        while ((1)); do
            echo
            echo "Enter $1: \($LENGTH $VALIDATIONSTRING Characters\)"
            read RESULT
            if [[ "$RESULT" != "" ]]; then
                CheckString $2 $3 $RESULT
                if [[ "$LENGTHCHECK" == "" ]]; then
                    echo "Invalid Input: String Not Length $LENGTH"
                fi
                if [[ "$VALIDATIONCHECK" == "" ]]; then
                        echo "Invalid Input: Only $VALIDATIONSTRING Characters Allowed"
                fi
                if [ "$LENGTHCHECK" == "TRUE" -a "$VALIDATIONCHECK" == "TRUE" ]; then
                    break
                fi
            else
                echo "Input String Cannot Be Empty"
            fi
        done
    else
        echo "Invalid UserInput Function Call"
        exit 2
    fi
}

# Function to handle user input selection lists
# $1 = User field prompt string (NO SPACES ALLOWED)
# $2 = TRUE if user entry is allowed
# #3 = Response length (0 if unlimited string)
# #4 = Validation type (Limited values are supported, see UserInput function for specifics)
# #5+ = List values (optional)
# RESULT = Value of selection from list
MANUAL=UserEntry
UserSelection()
{
    RESULT=
    PROMPT=
    if (( $# >= 2 )); then
        if [[ $2 != TRUE ]]; then
            NUMARGS=5
        else
            NUMARGS=4
        fi
        if (( $# >= $NUMARGS )); then
            PROMPT=$1
            USERENTRY=$2
            LENGTH=$3
            VALIDATION=$4
            if [[ $2 != TRUE ]]; then
                shift 4
                LISTITEMS="$@"
            else
                shift 4
                LISTITEMS="$MANUAL $@"
            fi
            echo
            echo "Select $PROMPT:"
            select RESULT in $LISTITEMS
            do
                if [[ "$RESULT" != "" ]]; then
                    if [[ $RESULT == $MANUAL ]]; then
                        UserInput $PROMPT $LENGTH $VALIDATION
                    fi
                    UserConfirmation $RESULT
                    if [[ "$CONFIRMED" == "TRUE" ]]; then
                        break
                    fi
                else
                    echo "Invalid Selection"
                fi
                echo
                echo "Select $PROMPT: \(Press ENTER To Show The List Again\)"
            done
        else
            echo "Invalid UserSelection Function Call"
            exit 2
        fi
    else
        echo "Invalid UserSelection Function Call"
        exit 2
    fi
}

# Function to collect the critical VPD items from the output files
# $1 = First file
# $2 = Second file
# SERIALNUMBER1 = Serial Number from VPD1
# BASESASADDRESS1 = Base SAS Address from VPD1
# MACADDRESS1 = MAC Address from VPD1
# SERIALNUMBER2 = Serial Number from VPD2
# BASESASADDRESS2 = Base SAS Address from VPD2
# MACADDRESS2 = MAC Address from VPD2
CollectCriticalFields()
{
    if (( $# == 2 )); then
        if [[ ! -f $1 ]]; then
            echo "CollectCriticalFields: File $FILE Not Found"
            exit 2
        fi
        if [[ ! -f $2 ]]; then
            echo "CollectCriticalFields: File $FILE Not Found"
            exit 2
        fi
        SERIALNUMBER1=$(grep BoardInfo $1 | grep SerialNumber | grep -v Type | awk '{print $7}' | sed -e "s/\"//g") 
        BASESASADDRESS1=$(grep EnclosureConfig $1 | grep EnclosureBaseSasAddress | grep -v Type | awk '{print $7}' | sed -e "s/\"//g") 
        MACADDRESS1=$(grep IPConfig $1 | grep MacAddress | grep -v Type | awk '{print $7}' | sed -e "s/\"//g") 
        SERIALNUMBER2=$(grep BoardInfo $2 | grep SerialNumber | grep -v Type | awk '{print $7}' | sed -e "s/\"//g") 
        BASESASADDRESS2=$(grep EnclosureConfig $2 | grep EnclosureBaseSasAddress | grep -v Type | awk '{print $7}' | sed -e "s/\"//g") 
        MACADDRESS2=$(grep IPConfig $2 | grep MacAddress | grep -v Type | awk '{print $7}' | sed -e "s/\"//g") 
    else
        echo "Invalid CollectCriticalFields Function Call"
        exit 2
    fi
}

# Function to allow the user to select from VPD critical field information
# $1 = Enclosure SCSI generic handle
# SERIALNUMBER = Selected serial number
# BASESASADDRESS = Selected base SAS address
# MACADDRESS = Selected MAC address
UserSelectCriticalFields()
{
    if (( $# == 1 )); then
        # Pull the fields to be saved from both VPDs
        CollectCriticalFields dev-${ENCLOSURE#/dev/}-VPD1-1.txt dev-${ENCLOSURE#/dev/}-VPD2-1.txt

        LISTITEMS=
        CheckString 16 ALPHANUMCAP $SERIALNUMBER1
        if [ "$SERIALNUMBER1" != "" -a "$SERIALNUMBER1" != $DEFAULTS10SERIAL -a "$SERIALNUMBER1" != $DEFAULTS30SERIAL -a "$LENGTHCHECK" == TRUE -a "$VALIDATIONCHECK" == TRUE ]; then
            LISTITEMS="$LISTITEMS $SERIALNUMBER1"
        fi
        CheckString 16 ALPHANUMCAP $SERIALNUMBER2
        if [ "$SERIALNUMBER2" != "" -a "$SERIALNUMBER2" != $DEFAULTS10SERIAL -a "$SERIALNUMBER2" != $DEFAULTS30SERIAL -a "$SERIALNUMBER1" != "$SERIALNUMBER2" -a "$LENGTHCHECK" == TRUE -a "$VALIDATIONCHECK" == TRUE ]; then
            LISTITEMS="$LISTITEMS $SERIALNUMBER2"
        fi
        UserSelection SerialNumber TRUE 16 ALPHANUMCAP $LISTITEMS
        SERIALNUMBER=$RESULT
        LISTITEMS=
        CheckString 16 HEXCAPNZNF $BASESASADDRESS1
        if [ "$BASESASADDRESS1" != "" -a "$BASESASADDRESS1" != $DEFAULTS10BASESAS -a "$BASESASADDRESS1" != $DEFAULTS30BASESAS -a "$LENGTHCHECK" == TRUE -a "$VALIDATIONCHECK" == TRUE ]; then
            LISTITEMS="$LISTITEMS $BASESASADDRESS1"
        fi
        CheckString 16 HEXCAPNZNF $BASESASADDRESS2
        if [ "$BASESASADDRESS2" != "" -a "$BASESASADDRESS2" != $DEFAULTS10BASESAS -a "$BASESASADDRESS2" != $DEFAULTS30BASESAS -a "$BASESASADDRESS1" != "$BASESASADDRESS2" -a "$LENGTHCHECK" == TRUE -a "$VALIDATIONCHECK" == TRUE ]; then
            LISTITEMS="$LISTITEMS $BASESASADDRESS2"
        fi
        UserSelection EnclosureBaseSasAddress TRUE 16 HEXCAPNZNF $LISTITEMS
        BASESASADDRESS=$RESULT
        LISTITEMS=
        CheckString 12 HEXCAPNZNF $MACADDRESS1
        if [ "$MACADDRESS1" != "" -a "$MACADDRESS1" != $DEFAULTS10MACADDRA -a "$MACADDRESS1" != $DEFAULTS10MACADDRB -a "$MACADDRESS1" != $DEFAULTS30MACADDRA -a "$MACADDRESS1" != $DEFAULTS30MACADDRB -a "$LENGTHCHECK" == TRUE -a "$VALIDATIONCHECK" == TRUE ]; then
            LISTITEMS="$LISTITEMS $MACADDRESS1"
        fi
        CheckString 12 HEXCAPNZNF $MACADDRESS2
        if [ "$MACADDRESS2" != "" -a "$MACADDRESS2" != $DEFAULTS10MACADDRA -a "$MACADDRESS2" != $DEFAULTS10MACADDRB -a "$MACADDRESS2" != $DEFAULTS30MACADDRA -a "$MACADDRESS2" != $DEFAULTS30MACADDRB -a "$MACADDRESS1" != "$MACADDRESS2" -a "$LENGTHCHECK" == TRUE -a "$VALIDATIONCHECK" == TRUE ]; then
            LISTITEMS="$LISTITEMS $MACADDRESS2"
        fi
        UserSelection MacAddress TRUE 12 HEXCAPNZNF $LISTITEMS
        MACADDRESS=$RESULT
    else
        echo "Invalid UserSelectCriticalFields Function Call"
        exit 2
    fi
}

IMAGE=Image.xml
# Function to create the image file once the template and critical fields have been properly set
CreateVPDImageFile()
{
    VARLIST="TEMPLATE TEMPLATESERIALNUMBER TEMPLATESASADDRESS TEMPLATEMACADDRESS SERIALNUMBER BASESASADDRESS MACADDRESS"
    for VAR in VARLIST; do
        if [[ "${VAR}" == "" ]]; then
            echo "Invalid CreateVPDImageFile Function Call"
            exit 2
        fi
    done
    sed -e "s/>$TEMPLATESERIALNUMBER<\/SerialNumber>/>$SERIALNUMBER<\/SerialNumber>/" $TEMPLATE | sed -e "s/>$TEMPLATESASADDRESS<\/EnclosureBaseSasAddress>/>$BASESASADDRESS<\/EnclosureBaseSasAddress>/" | sed -e "s/>$TEMPLATEMACADDRESS<\/MacAddress>/>$MACADDRESS<\/MacAddress>/" > $IMAGE
}

# Function to allow the user to select which IOMs to be reset
# $1 = Enclosure SCSI generic device name
InteractiveExpanderReset()
{
    RESULT=
    if (( $# == 1 )); then
        LISTITEMS="None Attached Both"
        echo
        echo "Select IOM\(s\) To Reset:"
        select RESULT in $LISTITEMS
        do
            if [[ "$RESULT" != "" ]]; then
                UserConfirmation $RESULT
                if [[ "$CONFIRMED" == "TRUE" ]]; then
                    break
                fi
            else
                echo "Invalid Selection"
            fi
            echo
            echo "Select IOM\(s\) To Reset: \(Press ENTER To Show The List Again\)"
        done
        if [[ $RESULT == Attached ]]; then
            echo
            echo "Resetting attached IOM on enclosure $ENCLOSURE"
            sg_senddiag $ENCLOSURE --pf --raw=04,00,00,01,45 # Reset locally attached IOM (A or B depending on the server module and enclosure)
        fi
        if [[ $RESULT == Both ]]; then
            echo
            echo "Resetting attached IOM on enclosure $ENCLOSURE"
            sg_senddiag $ENCLOSURE --pf --raw=04,00,00,01,43 # Reset both IOMs
        fi
    else
        echo "Invalid InteractiveExpanderReset Function Call"
        exit 2
    fi
}

# Function to determine if this is an S10 or S30
# $1 = TRUE if the system type should be displayed
# RESULT = System type
# TEMPLATE = Filename of template for system type
DetermineSystemType()
{
    if (( $# == 1 )); then
        VENDOR=$(dmidecode -s system-manufacturer | awk '{print $1}')
        PRODUCT=$(dmidecode -s system-product-name | awk '{print $1}')
        RESULT=
        if [[ $1 == TRUE ]]; then
            echo
        fi
        if [ "$VENDOR" == "Newisys" -a "$PRODUCT" == "NDS-SB1EA" ]; then
            RESULT=S10
            TEMPLATE=HDS_NDS4600_BB_VPD.xml
            if [[ $1 == TRUE ]]; then
                echo "Detected S10 System"
            fi
        fi
        if [ "$VENDOR" == "Quanta" -a "$PRODUCT" == "D51B-2U" ]; then
            RESULT=S30
            TEMPLATE=HDS_NDS4603_BB_VPD.xml
            if [[ $1 == TRUE ]]; then
                echo "Detected S30 System"
            fi
        fi
        if [[ "$RESULT" == "" ]]; then
            echo "ERROR: Could Not Determine Platform - Vendor:$VENDOR Product:$PRODUCT"
            exit 1
        fi
    else
        echo "Invalid DetermineSystemType Function Call"
        exit 2
    fi
}

# Function to find and display enclosure information
# No arguments
# ENCLOSURES = List of enclosures by SCSI generic name
# ENCLOSURECOUNT = Number of enclosures
GetEnclosureSCSIGenericNames()
{
    echo
    echo "Enclosure Vendor & Firmware Information:"
    lsscsi -g | grep enclosu
    echo
    echo "Enclosure SAS Address Information:"
    lsscsi -gt | grep enclosu
    ENCLOSURES=$(lsscsi -g | grep enclosu | awk '{print $7}')
    if [[ "$ENCLOSURES" == "" ]]; then
        echo "ERROR: Unable To Locate Enclosures SCSI Generic Names"
        exit 1
    fi
}

# Function to ensure there is only one server module installed in an S10
# Must call GetEnclosureSCSIGenericNames before this function
# No arguments
# No return
EnsureS10SingleServer()
{
    DetermineSystemType FALSE
    if [[ "$RESULT" == S10 ]]; then
        # Some VPD settings will expose each expander as what looks like an enclosure, so we need to find the real one
        ENCCOUNT=$(echo $ENCLOSURES | wc -w)
        if (( ENCCOUNT > 1 )); then
            for ENCLOSURE in $ENCLOSURES; do
                RESULT=$(sg_ses -p 0x00 $ENCLOSURE | grep Supported)
            if [[ "$RESULT" != "" ]]; then
                    ENCLOSURES=$ENCLOSURE
                    break
                fi
            done
        fi
        SERVERMODULE=$(sg_inq -p 0x83 $ENCLOSURES | grep "Relative target port:" | awk {'print $4'})
        while (( 1 )); do
            if [[ $SERVERMODULE == 0x1 ]]; then
                ELEMENT1=$(sg_ses -p 0x0A $ENCLOSURES | grep -A 7 "Element index: 75" | grep "SAS address:" | awk '{print $3}')
                ELEMENT2=$(sg_ses -p 0x0A $ENCLOSURES | grep -A 4 "Element index: 78" | grep "SAS address:" | awk '{print $3}')
            else
                ELEMENT1=$(sg_ses -p 0x0A $ENCLOSURES | grep -A 7 "Element index: 74" | grep "SAS address:" | awk '{print $3}')
                ELEMENT2=$(sg_ses -p 0x0A $ENCLOSURES | grep -A 4 "Element index: 76" | grep "SAS address:" | awk '{print $3}')
            fi
            if [ $ELEMENT1 != 0x0000000000000000 -a $ELEMENT2 != 0x0000000000000000 ]; then
                echo
                echo "===================================== WARNING ====================================="
                echo "=            DETECTED BOTH SERVER MODULES ARE INSTALLED AND POWERED ON            ="
                echo "=     ONLY ONE SERVER MODULE CAN BE POWERED ON WHEN PERFORMING VPD UPDATES!!!     ="
                echo "==================================================================================="
                if [[ $SERVERMODULE == 0x1 ]]; then
                    echo "=     PLEASE POWER OFF SERVER MODULE TWO IN THE ADMINISTRATION USER INTERFACE     ="
                    echo "=   OR REMOVE THE RIGHT SERVER MODULE WHEN LOOKING AT THE REAR OF THE ENCLOSURE   ="
                else
                    echo "=     PLEASE POWER OFF SERVER MODULE ONE IN THE ADMINISTRATION USER INTERFACE     ="
                    echo "=   OR REMOVE THE LEFT SERVER MODULE WHEN LOOKING AT THE REAR OF THE ENCLOSURE    ="
                fi
                echo "===================================== WARNING ====================================="
                echo
                echo "Please confirm there is only one server module installed - Type YES if this is correct"
                read ANSWER
                if [[ "$ANSWER" != "YES" ]]; then
                    echo
                    echo "Exiting."
                    exit 1
                fi
            else
                break
            fi
        done
    else
        echo
        echo "This system is not an S10 ... Exiting".
        exit 1
    fi
}

# Function to allow the user to choose which VPDs to update and reflash them
# No arguments
# WRITEVPD1 = TRUE if VPD1 was reflashed
# WRITEVPD2 = TRUE if VPD2 was reflashed
ChooseVPDsAndFlash()
{
    # Allow the user to choose the VPDs to be updated
    LISTITEMS="None VPD1 VPD2 Both"
    echo
    echo "Select VPD(s) To Write:"
    select RESULT in $LISTITEMS
    do
        if [[ "$RESULT" != "" ]]; then
            UserConfirmation $RESULT
            if [[ "$CONFIRMED" == "TRUE" ]]; then
                break
            fi
        else
            echo "Invalid Selection"
        fi
        echo
        echo "Select VPD(s) To Write: (Press ENTER To Show The List Again)"
    done
    WRITEVPD1=
    WRITEVPD2=
    if [[ $RESULT == VPD1 ]]; then
        WRITEVPD1=TRUE
    fi
    if [[ $RESULT == VPD2 ]]; then
        WRITEVPD2=TRUE
    fi
    if [[ $RESULT == Both ]]; then
        WRITEVPD1=TRUE
        WRITEVPD2=TRUE
    fi

    # Replace requested VPD images
    if [[ "$WRITEVPD1" == TRUE ]]; then
        echo
        echo "Rewriting enclosure $ENCLOSURE VPD-1"
        perl xeeprom.pl -device=$ENCLOSURE -id=1 -replace $IMAGE
    fi
    if [[ "$WRITEVPD2" == TRUE ]]; then
        echo
        echo "Rewriting enclosure $ENCLOSURE VPD-2"
        perl xeeprom.pl -device=$ENCLOSURE -id=2 -replace $IMAGE
    fi
}

# Function to read from a VPD EEPROM and write out a text file containing the values
# $1 = Enclosure to read from
# $2 = VPD to read from (1 or 2)
# $3 = Filename to create with the contents
# RESULT = FAILED if unable to read or empty if OK
ReadFromVPDEEPROM()
{
    if (( $# == 3 )); then
        MAXRETRIES=5
        FILEMINBYTES=300000
        WAITBEFORERETRY=2
        RESULT=
        COUNT=0
        while (( COUNT < MAXRETRIES )); do
            perl xeeprom.pl -device=$1 -id=$2 -read $TEMPLATE > $3
            FILESIZE=$(ls -al $3 | awk '{print $5}')
            if (( FILESIZE > FILEMINBYTES )); then
                break
            fi
            (( COUNT++ ))
            sleep $WAITBEFORERETRY
        done
        if (( COUNT == MAXRETRIES )) ; then
            echo "ERROR: Unable to Read VPD Information After $MAXRETRIES Retries"
            exit 1
        fi
    else
        echo "Invalid ReadFromVPDEEPROM Function Call"
        exit 2
    fi
}

# Function to check if two VPD output files match all values
# $1 = First file
# $2 = Second file
# RESULT = CORRUPT if they do not match or empty if okay
CheckVPDCopiesMatch()
{
    RESULT=
    FILE1=ID1.$$
    FILE2=ID2.$$
    if (( $# == 2 )); then
        if [[ ! -f $1 ]]; then
            echo "CheckVPDCopiesMatch: File $FILE Not Found"
            exit 2
        fi
        if [[ ! -f $2 ]]; then
            echo "CheckVPDCopiesMatch: File $FILE Not Found"
            exit 2
        fi
        grep "^[0-9 ][0-9 ][0-9][0-9]*\./" $1 > $FILE1
        grep "^[0-9 ][0-9 ][0-9][0-9]*\./" $2 > $FILE2
        RESULT=$(diff $FILE1 $FILE2)
        if [[ "$RESULT" != "" ]]; then
            echo "Files $1 and $2 contents should match, but do not"
            RESULT=CORRUPT
        fi
        rm $FILE1 $FILE2
    else
        echo "Invalid CheckVPDCopiesMatch Function Call"
        exit 2
    fi
}

