#!/bin/ash
#
# install_fw:
# This script performs the fw installation for the RLM.
# Usage: install_fw <dest_partition> <install_type> <force option>
#        <dest_partition> = partition in which fw is going to be installed
#                           can be "primary" or "backup"
#        <install_type>   = eth (for ethernet based update) or sp (via ONTAP) 
#        <force option>   = -f to force flash burn, none otherwise
# 
# Huynh Mai
#
# Return Values:
#     101 = Invalid arguments
#     102 = Error Flashing u-boot
#     103 = Error Flashing linux
#     104 = Error Flashing JFFS2
#     105 = Metadata info not present in new package
#     106 = Metadata Info not present in primary
#     107 = Metadata Info not present in backup
#     108 = Missing u-boot.bin in new package
#     109 = Missing uImage in new package
#     110 = Error Flashing JFFS2 image
#     111 = Missing Root.bin in new package
#     113 = u-boot Checksum Failure
#     114 = Linux Checksum Failure
#     115 = ROOTFS File Checksum Failure
#     116 = Missing Config.bin in new package
#     117 = Error Flashing JFFS2 logs image
#     118 = File couldn't be copied. Possible mount problems
#     119 = Corrupt primary detected. 
#     120 = sp update -f necessary for upgrade
#     121 = Unable to change permissions for primary post-install script
#     122 = Unable to change permissions for backup post-install script
#     123 = Error executing primary post-install script
#     124 = Error executing backup post-install script
#     125 = FW doesn't support boot block architecture
#

FW_SETENV=/usr/local/bin/fw_setenv
FW_PRINTENV=/usr/local/bin/fw_printenv

ETH_FW_PACKAGE_DIR=/tmp/fud_eth/RLM_FW
SP_FW_PACKAGE_DIR=/tmp/ORFTP/fud_sp

PRIMARY=/etc/rlm_install/primary
BACKUP=/etc/rlm_install/backup

PRI_UBOOT_VERSION_STRING=pri_u-boot_version=
PRI_UBOOT_CHECKSUM_STRING=pri_u-boot_checksum=
PRI_UBOOT_SIZE=pri_u-boot_size=
SEC_UBOOT_VERSION_STRING=sec_u-boot_version=
SEC_UBOOT_CHECKSUM_STRING=sec_u-boot_checksum=
SEC_UBOOT_SIZE=sec_u-boot_size=
LINUX_VERSION_STRING=linux_version=
LINUX_CHECKSUM_STRING=linux_checksum=
LINUX_SIZE=linux_size=
ROOTFS_SIZE=rootfs_size=
LOGS_SIZE=logs_size=

PRIMARY_ROOTFS=/mnt/jffs2_rootfs_primary;
BACKUP_ROOTFS=/mnt/jffs2_rootfs_backup;
JFFS2_LOGS_MOUNT=/mnt/logs;

NAND_ERASE="/usr/bin/flash_eraseall -q"
NAND_WRITE="/usr/bin/nandwrite -p"
SPI_ERASE="/usr/bin/flash_erase"
SPI_WRITE="/usr/bin/flashcp"
MKFS_JFFS2="/usr/bin/mkfs.jffs2 --eraseblock=128KiB -n"

LOG="/var/log/messages"

# Remount_Rootfs():
# Remounts the primary and backup root-filesystems after install.
# 
# No arguments
#
Remount_Rootfs() {
    echo "Remounting primary rootfs";
    mount -o remount,rw -t jffs2 $PRIMARY_ROOTFS_PARTITION $PRIMARY_ROOTFS
    
    echo "Remounting backup rootfs";
    mount -o remount,rw -t jffs2 $BACKUP_ROOTFS_PARTITION $BACKUP_ROOTFS

    echo "Remounting JFFS2 logs";
    mount -o remount,rw -t jffs2 $JFFS2_LOGS_BLOCK_PARTITION $JFFS2_LOGS_MOUNT
}

# Umount_all():
# Unmounts the primary, backup 
# 
# No arguments
#
Umount_primary()
{
    echo "Unmounting primary rootfs";
    umount -f $PRIMARY_ROOTFS
}

Umount_backup()
{
    echo "Unmounting backup rootfs";
    umount -f $BACKUP_ROOTFS
}

# Mount_all():
# Mounts the primary, backup and logs root-filesystems.
# 
# No arguments
#
Mount_primary()
{
    echo "Mounting primary rootfs";
    mount -t jffs2 $PRIMARY_ROOTFS_BLOCK_PARTITION $PRIMARY_ROOTFS
} 

Mount_backup()
{
    echo "Mounting backup rootfs";
    mount -t jffs2 $BACKUP_ROOTFS_BLOCK_PARTITION $BACKUP_ROOTFS
}
    
#
# $1: Device to read from
# $2: File to dump to
# $3: Length
#

read_nbyte_from_spi_device () {
	echo "Copying $3 bytes from $1 to $2"
	dd if=$1 of=$2 bs=1 count=$3
}

#
# $1: Device to read from
# $2: File to dump to
# $3: Length
#

read_nbyte_from_nand_device () {
	nandread $1 $3 > $2
}

#
# $1: Root Directory
# $2: File to dump to
# $3: Pad size
#
create_jffs2_image() {
	echo "--Creating JFFS2 image for director $1 padsize=$3"
	$MKFS_JFFS2 --root=$1 --output=$2 --pad=$3
}

#
# spi_md5sum ():
# This function computes the MD5SUM with specified length of a SPI partition
# $1 = file to compute the checksum
# $2 = limit 
#
spi_md5sum () {
   	TMP_CHKSUM=`dd if=$1 bs=8192 | trunc $2 | md5sum | sed -e "s/\(.*\) \(.*\)/\1/"`;
	echo $TMP_CHKSUM $1
}

#
# nand_md5sum ():
# This function computes the MD5SUM with specified length of a nand partition
# $1 = Source 
# $2 = limit 
#

nand_md5sum () {
	TMP_CHKSUM=`nandread $1 $2 | md5sum | sed -e "s/\(.*\) \(.*\)/\1/"`;
	echo $TMP_CHKSUM $1
}

#
# program_spi_partition()
# this function program the SPI flash
#   $1: MTD Device 
#   $2: File to be programmed

program_spi_partition() {
	echo "--Erasing $1"
	$SPI_ERASE $1 0 8 >> $LOG 2>>$LOG

	echo "--Writing $2 to $1"
	$SPI_WRITE $2 $1 >>$LOG 2>>$LOG
}

#   program_nand_partition
#   This function write a NAND partition
#   $1: MTD Device 
#   $2: File to be programmed

program_nand_partition() {

    echo "--Erasing $1"
    $NAND_ERASE $1 >> $LOG 2>>$LOG

    echo "--Writing $2 to $1"
    $NAND_WRITE $1 $2 >> $LOG 2>>$LOG
}

#
#
# Force_Burn():
# $1 = u-boot source location
# $2 = u-boot dest location
# $3 = linux source location
# $4 = linux dest location
# $5 = Root FS image source location
# $6 = Root FS image dest location
#

Force_Burn() {
	program_spi_partition $2 $1
    if ! [ $? = 0 ] ; then
		echo "ERROR Flashing u-boot";
		exit 102;
    fi
    
	program_nand_partition $4 $3
    if ! [ $? = 0 ] ; then
		echo "ERROR Flashing Linux";
		exit 103;
    fi

	program_nand_partition $6 $5
    if ! [ $? = 0 ] ; then
		echo "ERROR Flashing JFFS2 image";
		exit 110;
    fi
	sync;
}    

# Burn_fw():
# $1 = Source package
# $2 = Destination 
# $3 = u-boot source location
# $4 = u-boot dest location
# $5 = linux source location
# $6 = linux dest location
# $7 = Root FS source location
# $8 = Root FS dest location
#

Burn_fw() {

date;
    Burn_uboot $1 $2 $3 $4;
date;
    Burn_linux $1 $2 $5 $6;
date;
    Burn_jffs2_rootfs $1 $2 $7 $8;
date;
	sync;

}

#
# Burn_uboot():
# Routine that burns uboot into the dest partition if necessary
# 
# Args:
#     $1 = Source package
#     $2 = Destination
#     $3 = u-boot source
#     $4 = u-boot dest
#
Burn_uboot() {

echo "Installing Boot Loader..."

# Check if u-boot has changed, dd it if necessary, verify checksums
	if [ "$2" = "$PRIMARY" ] ; then
		UBOOT_VERSION_STRING=$PRI_UBOOT_VERSION_STRING;
		UBOOT_CHECKSUM_STRING=$PRI_UBOOT_CHECKSUM_STRING;
		UBOOT_SIZE=$PRI_UBOOT_SIZE;
	else
		UBOOT_VERSION_STRING=$SEC_UBOOT_VERSION_STRING;
		UBOOT_CHECKSUM_STRING=$SEC_UBOOT_CHECKSUM_STRING;
		UBOOT_SIZE=$SEC_UBOOT_SIZE;
	fi

    UBOOT_NEW=`grep $UBOOT_VERSION_STRING $1/Metadata | sed -e "s/\$UBOOT_VERSION_STRING//g"`;
    UBOOT_CURR=`grep $UBOOT_VERSION_STRING $2/Metadata | sed -e "s/\$UBOOT_VERSION_STRING//g"`;
    
echo $UBOOT_NEW;
echo $UBOOT_CURR;
    
    if [ "$UBOOT_NEW" = "$UBOOT_CURR" ] ; then
		echo "u-boot version unchanged.";
    else
		echo "Flashing u-boot version..." $UBOOT_NEW;

		if [ "$2" = "$PRIMARY" ] ; then
		    if ! [ -f $3 ] ; then
			echo "ERROR: Missing u-boot.bin in $NEW_PACKAGE/uboot";
			exit 108;
		    fi
		fi

		program_spi_partition $4 $3

		if [ $? = 0 ] ; then

		    echo "Flashing u-boot complete, verifying checksum..."
			# Verifying u-boot checksum
			UBOOT_CHECKSUM_CURR=`grep $UBOOT_CHECKSUM_STRING $1/Metadata | sed -e "s/\$UBOOT_CHECKSUM_STRING//g"`;
			UBOOT_XSUM_SIZE=`grep $UBOOT_SIZE $1/Metadata | sed -e "s/\$UBOOT_SIZE//g"`;
		    UBOOT_CHECKSUM_NEW=`spi_md5sum $4 $UBOOT_XSUM_SIZE`;
			echo "New Checksum"
		    echo $UBOOT_CHECKSUM_NEW;
		    
		    if ! [ "$UBOOT_CHECKSUM_CURR $4" = "$UBOOT_CHECKSUM_NEW" ] ; then
				echo "u-boot Checksum Failure";
			exit 113;
		    else
				echo "u-boot Checksum Verified";
		    fi
		else 
			echo "ERROR Flashing u-boot";
	    	exit 102;
		fi
    fi
}

#
# Burn_linux():
# Burns linux into the dest partition if necessary
# 
# Args:
#     $1 = Source package
#     $2 = Destination
#     $3 = linux source
#     $4 = linux dest
#
Burn_linux() {

echo "Installing OS..."

# echo "Burn_linux $1 $2 $3 $4";

# Check if linux has changed, dd it if necessary, verify checksums
    LINUX_NEW=`grep $LINUX_VERSION_STRING $1/Metadata | sed -e "s/$LINUX_VERSION_STRING//g"`;
    LINUX_CURR=`grep $LINUX_VERSION_STRING $2/Metadata | sed -e "s/\$LINUX_VERSION_STRING//g"`;
    
#    echo $LINUX_NEW;
#    echo $LINUX_CURR;
    
    if [ "$LINUX_NEW" = "$LINUX_CURR" ] ; then
	echo "linux version unchanged.";
    else
	echo "Flashing linux version" $LINUX_NEW;
	
	if [ "$2" = "$PRIMARY" ] ; then
	    if ! [ -f $3 ] ; then
		echo "ERROR: Missing uImage in $NEW_PACKAGE/linux";
		exit 109;
	    fi
	fi


	program_nand_partition $4 $3
	
	if [ $? = 0 ] ; then
	    echo "Flashing linux complete, verifying checksum..."
# Verifying linux checksum
		LINUX_CHECKSUM_CURR=`grep $LINUX_CHECKSUM_STRING $1/Metadata | sed -e "s/\$LINUX_CHECKSUM_STRING//g"`;
	    echo $LINUX_CHECKSUM_CURR $4;
		LINUX_CHECKSUM_SIZE=`grep $LINUX_SIZE $1/Metadata | sed -e "s/\$LINUX_SIZE//g"`;
	    LINUX_CHECKSUM_NEW=`nand_md5sum $4 $LINUX_CHECKSUM_SIZE`;
	    echo $LINUX_CHECKSUM_NEW;

	    if ! [ "$LINUX_CHECKSUM_CURR $4" = "$LINUX_CHECKSUM_NEW" ] ; then
		echo "Linux Checksum Failure";
		exit 114;
	    else
		echo "Linux Checksum Verified";
	    fi
	else 
	    echo "ERROR Flashing linux";
	    exit 103;
	fi
    fi
    
}

#
# Burn_jffs2_rootfs():
# Burns the JFFS2 root FS files into the dest partition
# 
# Args:
#     $1 = Source package
#     $2 = Destination
#     $3 = Root FS source location
#     $4 = Root FS dest location
#

Burn_jffs2_rootfs() {

    echo "Installing Applications...";
    
#echo "Burn_jffs2_rootfs $1 $2 $3 $4";
# And run post-install script
    
    if [ "$2" = "$PRIMARY" ] ; then
		if [ "$1" = "/tmp/fud_eth/RLM_FW/install" ] ; then
   			echo "Burning new JFFS2 primary image";
			Umount_primary;
			program_nand_partition $PRIMARY_ROOTFS_PARTITION $NEW_PACKAGE/root-fs-image/Root.bin
			Mount_primary;
	
 			if ! [ $? = 0 ] ; then
                echo "ERROR Flashing JFFS2 primary image";
                exit 104;
            fi
		else
			Differential_file_update $PRIMARY_REGFILES_ADD $PRIMARY_SYMLINKS_ADD \
	    	$PRIMARY_REGFILES_DEL $PRIMARY_SYMLINKS_DEL $3 $4 \
	    	$NEW_PACKAGE/install/checksum.regfiles;
	
			chmod 755 $PRIMARY_POST_INSTALL_SCRIPT;
			if ! [ $? = 0 ] ; then
			    echo "Unable to change permissions for $PRIMARY_POST_INSTALL_SCRIPT";
			    exit 121;
			fi
	
			$PRIMARY_POST_INSTALL_SCRIPT $4;
			if ! [ $? = 0 ] ; then
			    echo "Error executing $PRIMARY_POST_INSTALL_SCRIPT";
			    exit 123;
			fi
		fi
    elif [ "$2" = "$BACKUP" ] ; then
		Differential_file_update $BACKUP_REGFILES_ADD $BACKUP_SYMLINKS_ADD \
	    $BACKUP_REGFILES_DEL $BACKUP_SYMLINKS_DEL $3 $4 \
	    $PRIMARY/checksum.regfiles;

		chmod 755 $BACKUP_POST_INSTALL_SCRIPT;
		if ! [ $? = 0 ] ; then
	   		 echo "Unable to change permissions for $BACKUP_POST_INSTALL_SCRIPT";
		    exit 122;
		fi

		$BACKUP_POST_INSTALL_SCRIPT $4;
		if ! [ $? = 0 ] ; then
		    echo "Error executing $BACKUP_POST_INSTALL_SCRIPT";
		    exit 124;
		fi
    fi

# cp all metadata information
    echo "Installing New Metadata..."
#    rm -f $2/*;
    cp -f $1/* $2/;
    cd $1; for file in *; do
	FILE_CHECKSUM_ORIG=`md5sum $file`;
	FILE_CHECKSUM_CURR=`cd $2; md5sum $file`;
	cd $1;
#	echo $FILE_CHECKSUM_CURR;
#	echo $FILE_CHECKSUM_ORIG;
	if ! [ "$FILE_CHECKSUM_CURR" = "$FILE_CHECKSUM_ORIG" ] ; then
	    echo "File $2/$file Checksum Failure";
	    exit 115;
	fi
    done;
    echo "Metadata installed, Checksums Verified.";
}

#
# Differential_file_update():
# Updates the JFFS2 root FS files with the correct set of files
# 
# Args:
#     $1 = Regular files added/changed
#     $2 = Symlinks added/changed
#     $3 = Regular files removed
#     $4 = Symlinks removed
#     $5 = Root FS source location
#     $6 = Root FS dest location
#     $7 = checksum.regfiles for the files to be installed
#
Differential_file_update() {

# List all differences files
    for i in $1 $2 $3 $4; do
	if [ -f $i ] ; then
            echo $i;
	    echo `cat $i`;
	fi
    done

# rm all deleted files and symlinks
    if [ -f $3 ] ; then
	for fileName in `cat $3`; do
	    rm -f $6$fileName;
	done
    fi
    if [ -f $4 ] ; then
	for fileName in `cat $4`; do
	    rm -f $6$fileName;
	done
    fi

# cp all new and changed files and symlinks, verify checksums
    if [ -f $1 ] ; then
	for fileName in `cat $1`; do

# Is this file a config file, if so copy it to JFFS2 logs.(only for primary)

	    CONFIG_FILE=`echo $fileName | grep "/mnt/logs"`;
	    if [ "$CONFIG_FILE" = "$fileName" ] ; then
		if [ "$1" = "$PRIMARY_REGFILES_ADD" ] ; then
		    NEWDIR=`echo $fileName | sed -e "s/\(.*\)\/\(.*\)/\1/"`;
		    mkdir -p $NEWDIR;
		    rm -f $fileName;
		    cp -dpf $5$fileName $fileName;
		    if ! [ $? = 0 ] ; then
			echo "File $fileName couldn't be copied";
			exit 118;
		    fi
		    
		    FILE_CHECKSUM_CURR=`md5sum $fileName | sed -e "s/\(.*\) \(.*\)/\1/"`;
		    FILE_CHECKSUM_ORIG=`grep " $fileName$" $7`;
		    
		    if ! [ "$FILE_CHECKSUM_CURR $fileName" = "$FILE_CHECKSUM_ORIG" ] ; then
			echo $FILE_CHECKSUM_CURR $fileName;
			echo $FILE_CHECKSUM_ORIG;
			echo "File $fileName Checksum Failure";
			exit 115;
		    fi
		fi
	    else
		NEWDIR=`echo $6$fileName | sed -e "s/\(.*\)\/\(.*\)/\1/"`;
		mkdir -p $NEWDIR;
		rm -f $6$fileName;
		cp -dpf $5$fileName $6$fileName;
		if ! [ $? = 0 ] ; then
		    echo "File $fileName couldn't be copied";
		    exit 118;
		fi

		FILE_CHECKSUM_CURR=`md5sum $6$fileName | sed -e "s/\(.*\) \(.*\)/\1/"`;
		FILE_CHECKSUM_ORIG=`grep " $fileName$" $7`;

		if ! [ "$FILE_CHECKSUM_CURR $fileName" = "$FILE_CHECKSUM_ORIG" ] ; then
		    echo $FILE_CHECKSUM_CURR $fileName;
		    echo $FILE_CHECKSUM_ORIG;
		    echo "File $fileName Checksum Failure";
		    exit 115;
		fi
	    fi
	done
    fi

    if [ -f $2 ] ; then
	COUNT=0;
	for fileName in `cat $2`; do
	    if [ $(($COUNT%2)) -eq 0 ] ; then
		FILENAME=$fileName;
	    else
		rm -f $6$FILENAME;
		ln -sf $fileName $6$FILENAME;
	    fi
	    COUNT=$(($COUNT + 1));
	done
    fi
}

PRIMARY_UBOOT_TEMP=/mnt/sapps/uboot
PRIMARY_LINUX_TEMP=/mnt/sapps/linux
PRIMARY_ROOTFS_TEMP=/mnt/sapps/rootfs

# Use -d flag to indicate this a differential update and the ROOT FS image is not required
create_primary_binary_images() {

	if [ -f "$PRIMARY_UBOOT_TEMP" ] ; then
		rm $PRIMARY_UBOOT_TEMP
	fi
	cp $PRIMARY/secondary-u-boot.bin $PRIMARY_UBOOT_TEMP

	if [ -f "$PRIMARY_LINUX_TEMP" ] ; then
		rm $PRIMARY_LINUX_TEMP
	fi
	LINUX_XSUM_SIZE=`grep $LINUX_SIZE $PRIMARY/Metadata | sed -e "s/\$LINUX_SIZE//g"`;
	read_nbyte_from_nand_device $PRIMARY_LINUX_PARTITION $PRIMARY_LINUX_TEMP $LINUX_XSUM_SIZE

	if [ "$1" != "-d" ] ; then
		if [ -f "$PRIMARY_ROOTFS_TEMP" ] ; then
			rm $PRIMARY_ROOTFS_TEMP
		fi
		ROOTFS_XSUM_SIZE=`grep $ROOTFS_SIZE $PRIMARY/Metadata | sed -e "s/\$ROOTFS_SIZE//g"`;
		create_jffs2_image $PRIMARY_ROOTFS $PRIMARY_ROOTFS_TEMP $ROOTFS_XSUM_SIZE
	fi
}

# Verify command line arguments
if [ $# -lt 2 ] || [ $# -gt 3 ] ; then
	echo "Usage: install_fw <dest_partition> <install_type> <force option>";
	exit 101;
fi
if [ $2 = "eth" ] ; then
    NEW_PACKAGE=$ETH_FW_PACKAGE_DIR
    DIFFS_DIR=$ETH_FW_PACKAGE_DIR/differences
    PRIMARY_POST_INSTALL_SCRIPT=$ETH_FW_PACKAGE_DIR/install/post-install-script
    BACKUP_POST_INSTALL_SCRIPT=$PRIMARY_ROOTFS/install/post-install-script

    PRIMARY_REGFILES_ADD=$DIFFS_DIR/add.regfiles.primary
    PRIMARY_REGFILES_DEL=$DIFFS_DIR/del.regfiles.primary
    PRIMARY_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.primary
    PRIMARY_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.primary

    BACKUP_REGFILES_ADD=$DIFFS_DIR/add.regfiles.backup
    BACKUP_REGFILES_DEL=$DIFFS_DIR/del.regfiles.backup
    BACKUP_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.backup
    BACKUP_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.backup
	UPDATE_MODE="eth"

elif [ $2 = "sp" ] ; then
    NEW_PACKAGE=$SP_FW_PACKAGE_DIR
    DIFFS_DIR=$SP_FW_PACKAGE_DIR/differences
    PRIMARY_POST_INSTALL_SCRIPT=$SP_FW_PACKAGE_DIR/install/post-install-script
    BACKUP_POST_INSTALL_SCRIPT=$PRIMARY_ROOTFS/install/post-install-script

    PRIMARY_REGFILES_ADD=$DIFFS_DIR/add.regfiles.primary
    PRIMARY_REGFILES_DEL=$DIFFS_DIR/del.regfiles.primary
    PRIMARY_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.primary
    PRIMARY_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.primary

    BACKUP_REGFILES_ADD=$DIFFS_DIR/add.regfiles.backup
    BACKUP_REGFILES_DEL=$DIFFS_DIR/del.regfiles.backup
    BACKUP_SYMLINKS_ADD=$DIFFS_DIR/add.symlinks.backup
    BACKUP_SYMLINKS_DEL=$DIFFS_DIR/del.symlinks.backup
	UPDATE_MODE="sp"
else 
    echo "Usage: install_fw <dest_partition> <install_type> <force option>";
    exit 101;
fi

# Set up the env vars depending on which image we booted - primary or backup
PRIMARY_UBOOT_PARTITION=/dev/mtd1
BACKUP_UBOOT_PARTITION=/dev/mtd4
PRIMARY_LINUX_PARTITION=/dev/mtd6
BACKUP_LINUX_PARTITION=/dev/mtd8
PRIMARY_ROOTFS_PARTITION=/dev/mtd7
PRIMARY_ROOTFS_BLOCK_PARTITION=/dev/mtdblock7
BACKUP_ROOTFS_PARTITION=/dev/mtd9
BACKUP_ROOTFS_BLOCK_PARTITION=/dev/mtdblock9
JFFS2_LOGS_PARTITION=/dev/mtd10
JFFS2_LOGS_BLOCK_PARTITION=/dev/mtdblock10

# Start the install process
# Entry point
grep -c use_tiny_rom $NEW_PACKAGE/install/Metadata > /dev/null
if [ $?  != 0 ]; then
	echo "ERROR: this FW does not support boot block architecture $PRIMARY";
	exit 125;
fi


if [ $1 = "primary" ] ; then
    
    installing_primary=`$FW_PRINTENV | grep INSTALLING_PRIMARY | sed -e "s/INSTALLING_PRIMARY=//g"`;
    
    if [ "$3" = "-f" ] || [ "$3" = "-F" ] || [ "$installing_primary" -eq "1" ] ; then

		echo "Starting forced update of primary...";
		if ! [ -f $NEW_PACKAGE/uboot/u-boot.bin ] ; then
		    echo "ERROR: Missing u-boot.bin in $NEW_PACKAGE/uboot";
		    exit 108;
		elif ! [ -f $NEW_PACKAGE/linux/uImage ] ; then
		    echo "ERROR: Missing uImage in $NEW_PACKAGE/linux";
		    exit 109;
		elif ! [ -f $NEW_PACKAGE/root-fs-image/Root.bin ] ; then
		    echo "ERROR: Missing Root.bin in $NEW_PACKAGE/root-fs-image";
		    exit 111;
		fi
		if [ "$3" = "-F" ] ; then
			if ! [ -f $NEW_PACKAGE/root-fs-image/Config.bin ] ; then
			    echo "ERROR: Missing Config.bin in $NEW_PACKAGE/root-fs-image";
			    exit 116;
			fi
		fi

		$FW_SETENV INSTALLING_PRIMARY 1 > /dev/null 2>&1; 
	
		Umount_primary;

		Force_Burn $NEW_PACKAGE/uboot/u-boot.bin $PRIMARY_UBOOT_PARTITION \
	    $NEW_PACKAGE/linux/uImage $PRIMARY_LINUX_PARTITION \
	    $NEW_PACKAGE/root-fs-image/Root.bin $PRIMARY_ROOTFS_PARTITION;

		Mount_primary;

		# Save this so we update later when we reboot 
		if [ "$3" = "-F" ] ; then
			cp -f $NEW_PACKAGE/root-fs-image/Config.bin $PRIMARY_ROOTFS/install/.
			if ! [ $? = 0 ] ; then
			    echo "ERROR saving JFFS2 logs image";
			    exit 117;
			fi
			sync
		fi

		$FW_SETENV INSTALLING_PRIMARY 0 > /dev/null 2>&1;
	
		exit;
	fi

	if [ -f $NEW_PACKAGE/install/checksum.regfiles.0 -a \
		! -f $NEW_PACKAGE/install/checksum.regfiles ] ; then
		echo "Copying checksum.regfiles.0 to checksum.regfiles"
		cp $NEW_PACKAGE/install/checksum.regfiles.0 $NEW_PACKAGE/install/checksum.regfiles
	fi

    if ! [ -f $NEW_PACKAGE/install/Metadata -a \
	-f $NEW_PACKAGE/install/checksum.regfiles -a \
	-f $NEW_PACKAGE/install/info.symlinks -a \
	-f $NEW_PACKAGE/install/post-install-script ] ; then
	
		echo "ERROR: No metadata information in $NEW_PACKAGE/install";
		exit 105;
	
    elif ! [ -f $PRIMARY/Metadata -a \
	-f $PRIMARY/checksum.regfiles -a \
	-f $PRIMARY/info.symlinks -a \
	-f $PRIMARY/post-install-script ] ; then
	
		echo "ERROR: No Metadata Information in $PRIMARY";
		exit 106;

	else
		$FW_SETENV INSTALLING_PRIMARY 1 > /dev/null 2>&1; 
	
		Burn_fw $NEW_PACKAGE/install $PRIMARY \
	    $NEW_PACKAGE/uboot/u-boot.bin $PRIMARY_UBOOT_PARTITION \
	    $NEW_PACKAGE/linux/uImage $PRIMARY_LINUX_PARTITION \
	    $NEW_PACKAGE/root-fs $PRIMARY_ROOTFS;
	
		Remount_Rootfs;

		$FW_SETENV INSTALLING_PRIMARY 0 > /dev/null 2>&1;
	fi

elif [ $1 = "backup" ] ; then

    installing_primary=`$FW_PRINTENV | grep INSTALLING_PRIMARY | sed -e "s/INSTALLING_PRIMARY=//g"`;
    installing_backup=`$FW_PRINTENV | grep INSTALLING_BACKUP | sed -e "s/INSTALLING_BACKUP=//g"`;
    
    if [ "$installing_primary" -eq "1" ] ; then
		echo "Primary might be corrupt. Previous unsuccessful install detected.";
		echo "Cant install backup when INSTALL_PRIMARY=1. Exiting..."
		exit;
    fi
    
    if [ "$3" = "-f" ] || [ "$3" = "-F" ] || [ "$installing_backup" -eq "1" ] ; then

		echo "Starting forced update of backup...";


		$FW_SETENV INSTALLING_BACKUP 1 > /dev/null 2>&1;

		create_primary_binary_images;

		Umount_backup;
		
		Force_Burn $PRIMARY_UBOOT_TEMP $BACKUP_UBOOT_PARTITION \
		    $PRIMARY_LINUX_TEMP $BACKUP_LINUX_PARTITION \
		    $PRIMARY_ROOTFS_TEMP $BACKUP_ROOTFS_PARTITION;

		rm -rf $PRIMARY_UBOOT_TEMP $PRIMARY_LINUX_TEMP $PRIMARY_ROOTFS_TEMP
		Mount_backup;

		$FW_SETENV INSTALLING_BACKUP 0 > /dev/null 2>&1;

		exit;
    fi

    if ! [ -f $PRIMARY/Metadata -a \
	-f $PRIMARY/checksum.regfiles -a \
	-f $PRIMARY/info.symlinks -a \
	-f $PRIMARY/post-install-script -a \
	-f $PRIMARY/secondary-u-boot.bin ] ; then

		echo "ERROR: No metadata information in $PRIMARY";
		exit 106;

    elif ! [ -f $BACKUP/Metadata -a \
	-f $BACKUP/checksum.regfiles -a \
	-f $BACKUP/info.symlinks -a \
	-f $BACKUP/post-install-script ] ; then
	
		echo "ERROR: No Metadata Information in $BACKUP";
		exit 107;

    else
		$FW_SETENV INSTALLING_BACKUP 1 > /dev/null 2>&1;

		create_primary_binary_images -d;

		Burn_fw $PRIMARY $BACKUP \
	    $PRIMARY_UBOOT_TEMP $BACKUP_UBOOT_PARTITION \
	    $PRIMARY_LINUX_TEMP $BACKUP_LINUX_PARTITION \
	    $PRIMARY_ROOTFS $BACKUP_ROOTFS;

		rm -rf $PRIMARY_UBOOT_TEMP $PRIMARY_LINUX_TEMP
		Remount_Rootfs;

		$FW_SETENV INSTALLING_BACKUP 0 > /dev/null 2>&1;
    fi
else 
    echo "Usage: install_fw <dest_partition> <install_type> <force option>";
    exit 101;
fi

exit;
