#!/bin/sh

source ${CONF_DIR}/config;
source ${CONF_DIR}/devices;
source ${CONF_DIR}/helpers/functions

UPGRADE=;

if [ "X${CONFIG_UPGRADE_ALLOW}" != "Xy" ]; then
	exit 0;
fi

if [ "X${CONFIG_UPGRADE_SILENT}" != "Xy" ]; then
	DISPLAY="echo -ne";
else
	DISPLAY="true";
fi

if [ "X${CONFIG_UPGRADE_AUTO}" == "Xy" ]
then
	if [ -e ${CONF_DIR}/helpers/autoupdate ]
	then
		${DISPLAY} "\nExecuting Autoupdate script\n"
		/bin/sh ${CONF_DIR}/helpers/autoupdate
		exit 0
	else
		${DISPLAY} "skipped.\n"
		exit 0
	fi
else
	# Check if the user wants to upgrade
	${DISPLAY} "Press 'U' to upgrade the board ... ";
	read -n 1 -t ${CONFIG_UPGRADE_DELAY} UPGRADE;
	if [ "X${UPGRADE}" != "XU" ] && [ "X${UPGRADE}" != "Xu" ]
	then
		${DISPLAY} "skipped.\n";
		exit 0;
	fi
fi

echo -ne "\nUpgrading board:\n";
sleep 1; # Leave a chance for the user to stop pressing 'u'
# Detect or ask which device to upgrade from
UPGRADES_SUPPORTED="abort";
if [ "X${CONFIG_UPGRADE_FTP}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} ftp";
fi
if [ "X${CONFIG_UPGRADE_HTTP}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} http";
fi
if [ "X${CONFIG_UPGRADE_CIFS}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} cifs";
fi
if [ "X${CONFIG_UPGRADE_NFS}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} nfs";
fi
if [ "X${CONFIG_UPGRADE_UART}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} uart";
fi
if [ "X${CONFIG_UPGRADE_USB}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} usb";
fi
if [ "X${CONFIG_UPGRADE_NAND}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} nand";
fi
if [ "X${CONFIG_UPGRADE_MANUAL}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} shell";
fi
if [ "X${CONFIG_UPGRADE_CUSTOM}" == "Xy" ]; then
	UPGRADES_SUPPORTED="${UPGRADES_SUPPORTED} custom";
fi

if [ -z "${UPGRADES_SUPPORTED}" ]; then
	echo -ne "ERROR: no upgrade supported on this board, please check your configuration.\n";
	exit 1;
fi

VALID_MODE=0;
while [ $((VALID_MODE)) -eq 0 ]; do
	echo -e "Supported upgraded modes are: ${UPGRADES_SUPPORTED}"
	echo -ne "Upgrade from: ";
	read UPGRADE_MODE
	for mode in ${UPGRADES_SUPPORTED}; do
		if [ "X${mode}" == "X${UPGRADE_MODE}" ]; then
			VALID_MODE=1;
		fi
	done	
done

UPGRADE_DIRNAME=""
# get the filenames for any images that will be upgraded
get_upgrade_filenames()
{
		UPGRADE_FILENAME_BOOTLOADER=;
		UPGRADE_FILENAME_KERNEL=;
		UPGRADE_FILENAME_INITRD=;
		UPGRADE_FILENAME_ROOTFS=;

		DO_UPGRADE=;
		echo -ne "Upgrade bootloader(y/N): ";
		read DO_UPGRADE
		if [ "X${DO_UPGRADE}" == "Xy" ] || [ "X${DO_UPGRADE}" == "XY" ]
		then
			echo -ne "Enter bootloader filename(nand-bootloader.bin): "
			read UPGRADE_FILENAME_BOOTLOADER
			if [ "X${UPGRADE_FILENAME_BOOTLOADER}" == "X" ] 
			then
				UPGRADE_FILENAME_BOOTLOADER=nand-bootloader.bin
			fi
		fi

		DO_UPGRADE=;
		echo -ne "Upgrade kernel(y/N): ";
		read DO_UPGRADE
		if [ "X${DO_UPGRADE}" == "Xy" ] || [ "X${DO_UPGRADE}" == "XY" ]
		then
			echo -ne "Enter kernel filename(nand-kernel.img): "
			read UPGRADE_FILENAME_KERNEL
			if [ "X${UPGRADE_FILENAME_KERNEL}" == "X" ] 
			then
				UPGRADE_FILENAME_KERNEL=nand-kernel.img
			fi
		fi

		DO_UPGRADE=;
		echo -ne "Upgrade initrd(y/N): ";
		read DO_UPGRADE
		if [ "X${DO_UPGRADE}" == "Xy" ] || [ "X${DO_UPGRADE}" == "XY" ]
		then
			echo -ne "Enter initrd filename(nand-initrd.img): "
			read UPGRADE_FILENAME_INITRD
			if [ "X${UPGRADE_FILENAME_INITRD}" == "X" ] 
			then
				UPGRADE_FILENAME_INITRD=nand-initrd.img
			fi
		fi

		DO_UPGRADE=;
		echo -ne "Upgrade rootfs(y/N): ";
		read DO_UPGRADE
		if [ "X${DO_UPGRADE}" == "Xy" ] || [ "X${DO_UPGRADE}" == "XY" ]
		then
			echo -ne "Enter rootfs filename(nand-rootfs.tgz): "
			read UPGRADE_FILENAME_ROOTFS
			if [ "X${UPGRADE_FILENAME_ROOTFS}" == "X" ] 
			then
				UPGRADE_FILENAME_ROOTFS=nand-rootfs.tgz
			fi
		fi
}

get_partitions()
{
	ALLOW_REPARTITION=$1

	local boot_mtddev=
	local root_mtddev=

	if [ "X${CFGDEVICES_BOOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_BOOTDEV}" == "Xnor" ]
	then
		boot_mtddev="true"
	fi
	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]
	then
		root_mtddev="true"
	fi

	REPARTITION=
	if [ -n "${boot_mtddev}" ] || [ -n "${root_mtddev}" ] 
	then
		if [ $ALLOW_REPARTITION -eq 1 ]
		then
			echo -ne "Re-partition MTD device(y/N/s) ? : "
			read REPARTITION
			if [ "X${REPARTITION}" == "Xs" ] 
			then
				echo "CURRENT: ${CFGDEVICES_BOOTDEV_MTDPARTS}"
				echo -ne "Re-partition MTD device(y/N/s) ? : "
				read REPARTITION
			fi
		else
			REPARTITION="n"
		fi

		if [ "X${REPARTITION}" == "Xy" ] || [ "X${REPARTITION}" == "XY" ]
		then
			REPARTITION="y"
			NEWPARTITIONS=
			echo -ne "Enter partition info: "
			read NEWPARTITIONS
			echo $NEWPARTITIONS |grep -sq '"'
			if [ $? -eq 0 ]
			then
				echo $NEWPARTITIONS |grep -sq '^"'
				if [ $? -eq 0 ]
				then
					NEWPARTITIONS=`echo $NEWPARTITIONS | busybox cut -d'"' -f2`
				else
					NEWPARTITIONS=`echo $NEWPARTITIONS | busybox cut -d'"' -f1`
				fi
			fi
			if [ -n "${boot_mtddev}" ]
			then
				BOOTDEV_MTDPARTS="${NEWPARTITIONS}"
			fi
			if [ -n "${root_mtddev}" ]
			then
				ROOTDEV_MTDPARTS="${NEWPARTITIONS}"
			fi
		else
			REPARTITION="n"
			if [ -n "${boot_mtddev}" ]
			then
				BOOTDEV_MTDPARTS="${CFGDEVICES_BOOTDEV_MTDPARTS}"
			fi
			if [ -n "${root_mtddev}" ]
			then
				ROOTDEV_MTDPARTS="${CFGDEVICES_ROOTDEV_MTDPARTS}"
			fi
		fi
	fi
}

display_filenames()
{
	echo -ne "\nYou requested an upgrade from ${UPGRADE_MODE} using the following files:\n"
	UPGRADE_BOOTLOADER=;
	if [ -n "${UPGRADE_FILENAME_BOOTLOADER}" ]; then
		echo -ne "Bootloader: ${UPGRADE_FILENAME_BOOTLOADER}\n"
		UPGRADE_BOOTLOADER="y";
	fi
	UPGRADE_KERNEL=;
	if [ -n "${UPGRADE_FILENAME_KERNEL}" ]; then
		echo -ne "Kernel: ${UPGRADE_FILENAME_KERNEL}\n"
		UPGRADE_KERNEL="y";
	fi
	UPGRADE_INITRD=;
	if [ -n "${UPGRADE_FILENAME_INITRD}" ]; then
		echo -ne "Initrd: ${UPGRADE_FILENAME_INITRD}\n"
		UPGRADE_INITRD="y";
	fi
	UPGRADE_ROOTFS=;
	if [ -n "${UPGRADE_FILENAME_ROOTFS}" ]; then
		echo -ne "RootFS: ${UPGRADE_FILENAME_ROOTFS}\n"
		UPGRADE_ROOTFS="y";
		UPGRADE_ROOTFS_TYPE="$(echo ${UPGRADE_FILENAME_ROOTFS} | sed -e 's/.*\.//')";
	fi
}

get_params()
{

	if [ "X${UPGRADE_MODE}" == "Xftp" ] ||   \
		[ "X${UPGRADE_MODE}" == "Xcifs" ] || \
		[ "X${UPGRADE_MODE}" == "Xnfs" ]  || \
		[ "X${UPGRADE_MODE}" == "Xhttp" ]
	then

		echo -ne "Server name or IP: ";
		read UPGRADE_SERVER
		echo -ne "Path to images : ";
		read UPGRADE_DIRNAME

		if [ "X${UPGRADE_MODE}" == "Xftp" ] || [ "X${UPGRADE_MODE}" == "Xcifs" ]
		then
			echo -ne "User name: ";
			read UPGRADE_USER_NAME
			echo -ne "Password: ";
			read UPGRADE_USER_PASSWORD
		fi

		echo -ne "Please enter the name of the files on the server:\n";
		get_upgrade_filenames

		# 1 indicates that we can repartition the mtd device
		get_partitions 1

		display_filenames
		echo -ne "These images will be downloaded from ${UPGRADE_SERVER}.\n"

		if [ "X${REPARTITION}" == "Xy" ] 
		then
			echo "MTD Device will be partitioned as follows:"
			echo "$NEWPARTITIONS"
		fi

	elif [ "X${UPGRADE_MODE}" == "Xuart" ]; then
		echo -ne "Do you want to upgrade the bootloader (y/N) ? ";
		read UPGRADE_BOOTLOADER
		echo -ne "Do you want to upgrade the kernel (y/N) ? ";
		read UPGRADE_KERNEL
		echo -ne "Do you want to upgrade the initrd (y/N) ? ";
		read UPGRADE_INITRD
		echo -ne "Do you want to upgrade the root filesystem (y/N) ? ";
		read UPGRADE_ROOTFS
		if [ "X${UPGRADE_ROOTFS}" == "Xy" ] || [ "X${UPGRADE_ROOTFS}" == "XY" ]; then
			echo -ne "Root filesystem file type(tar tgz gz bz2 bin img): ";
			read UPGRADE_ROOTFS_TYPE
		fi

		get_partitions 1

		echo -ne "\nYou requested an upgrade from ${UPGRADE_MODE} of the following:\n"
		if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] || [ "X${UPGRADE_BOOTLOADER}" == "XY" ]; then
			echo -ne "Bootloader\n";
			UPGRADE_BOOTLOADER="y";
		else
			UPGRADE_BOOTLOADER=;
		fi
		if [ "X${UPGRADE_KERNEL}" == "Xy" ] || [ "X${UPGRADE_KERNEL}" == "XY" ]; then
			echo -ne "Kernel\n"
			UPGRADE_KERNEL="y";
		else
			UPGRADE_KERNEL=;
		fi
		if [ "X${UPGRADE_INITRD}" == "Xy" ] || [ "X${UPGRADE_INITRD}" == "XY" ]; then
			echo -ne "Initrd\n"
			UPGRADE_INITRD="y";
		else
			UPGRADE_INITRD=;
		fi
		if [ "X${UPGRADE_ROOTFS}" == "Xy" ] || [ "X${UPGRADE_ROOTFS}" == "XY" ]; then
			echo -ne "RootFS\n"
			UPGRADE_ROOTFS="y";
		else
			UPGRADE_ROOTFS=;
		fi

		if [ "X${REPARTITION}" == "Xy" ] 
		then
			echo "MTD Device will be partitioned as follows:"
			echo "$NEWPARTITIONS"
		fi

	elif [ "X${UPGRADE_MODE}" == "Xnand" ] || [ "X${UPGRADE_MODE}" == "Xusb" ]
	then
		echo -e  "Do not include mountpoint name in path(ie. /data)"
		echo -ne "Specify file path on device(return for top dir): ";
		read UPGRADE_DIRNAME

		echo
		echo -ne "Please enter the name of the files to be used:\n";
		get_upgrade_filenames

		if [ "X${UPGRADE_MODE}" == "Xnand" ]
		then
			# don't allow partitions to be re-defined
			get_partitions 0
		else 
			get_partitions 1
		fi

		display_filenames
		if [ "X${REPARTITION}" == "Xy" ] 
		then
			echo "MTD Device will be partitioned as follows:"
			echo "$NEWPARTITIONS"
		fi
	fi
}

ftp_get_images()
{
	OPTIONS="";
	if [ -n "${UPGRADE_USER_NAME}" ]; then
		OPTIONS="${OPTIONS} -u ${UPGRADE_USER_NAME}";
	fi
	if [ -n "${UPGRADE_USER_PASSWORD}" ]; then
		OPTIONS="${OPTIONS} -p ${UPGRADE_USER_PASSWORD}";
	fi
	
	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]; then
		echo -ne "Downloading new bootloader ... ";
		ftpget ${OPTIONS} ${UPGRADE_SERVER} ${LOCAL_BOOTLOADER_FILENAME} ${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_BOOTLOADER};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_BOOTLOADER} on ${UPGRADE_SERVER} using FTP.\n"
			exit 30;
		fi
		echo -ne "done.\n";
	fi		

	if [ "X${UPGRADE_KERNEL}" == "Xy" ]; then
		echo -ne "Downloading new kernel ... ";
		ftpget ${OPTIONS} ${UPGRADE_SERVER} ${LOCAL_KERNEL_FILENAME} ${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_KERNEL} on ${UPGRADE_SERVER} using FTP.\n"
			exit 31;
		fi
		echo -ne "done.\n";
	fi	

	if [ "X${UPGRADE_INITRD}" == "Xy" ]; then
		echo -ne "Downloading new initrd ... ";
		ftpget ${OPTIONS} ${UPGRADE_SERVER} ${LOCAL_INITRD_FILENAME} ${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_INITRD} on ${UPGRADE_SERVER} using FTP.\n"
			exit 32;
		fi
		echo -ne "done.\n";
	fi
}

http_get_images()
{
	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]
	then
		echo -ne "Downloading new bootloader ... ";
		wget http://${UPGRADE_SERVER}/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_BOOTLOADER} -O ${LOCAL_BOOTLOADER_FILENAME}
		if [ $? -ne 0 ]
		then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_BOOTLOADER} on ${UPGRADE_SERVER} using HTTP.\n"
			exit 30;
		fi
		echo -ne "done.\n";
	fi		

	if [ "X${UPGRADE_KERNEL}" == "Xy" ]
	then
		echo -ne "Downloading new kernel ... ";
		wget http://${UPGRADE_SERVER}/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL} -O ${LOCAL_KERNEL_FILENAME}
		if [ $? -ne 0 ]
		then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_KERNEL} on ${UPGRADE_SERVER} using HTTP.\n"
			exit 31;
		fi
		echo -ne "done.\n";
	fi	

	if [ "X${UPGRADE_INITRD}" == "Xy" ]
	then
		echo -ne "Downloading new initrd ... ";
		wget http://${UPGRADE_SERVER}/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD} -O ${LOCAL_INITRD_FILENAME}
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_INITRD} on ${UPGRADE_SERVER} using HTTP.\n"
			exit 32;
		fi
		echo -ne "done.\n";
	fi
}

nfs_get_images()
{
	OPTIONS="-o defaults,ro,nolock";
	if [ ! -d /mnt ]; then
		mkdir /mnt
	fi
	mount "${UPGRADE_SERVER}:${UPGRADE_DIRNAME}" /mnt -t nfs ${OPTIONS};
	if [ $? -ne 0 ]; then
		echo -ne "ERROR:\nFailed to mount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME} using NFS.\n"
		exit 40;
	fi
	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]; then
		echo -ne "Downloading new bootloader ... ";
		cp "/mnt/${UPGRADE_FILENAME_BOOTLOADER}" ${LOCAL_BOOTLOADER_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD} using NFS.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_KERNEL}" == "Xy" ]; then
		echo -ne "Downloading new kernel ... ";
		cp "/mnt/${UPGRADE_FILENAME_KERNEL}" ${LOCAL_KERNEL_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL} using NFS.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_INITRD}" == "Xy" ]; then
		echo -ne "Downloading new initrd ... ";
		cp "/mnt/${UPGRADE_FILENAME_INITRD}" ${LOCAL_INITRD_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD} using NFS.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	umount /mnt;
	if [ $? -ne 0 ]; then
		echo -ne "ERROR:\nFailed to unmount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}.\n"
		exit 40;
	fi
}

cifs_get_images()
{
	OPTIONS="-o defaults,ro";
	if [ -n "${UPGRADE_USER_NAME}" ]; then
		OPTIONS="${OPTIONS},user=${UPGRADE_USER_NAME}";
	fi
	if [ -n "${UPGRADE_USER_PASSWORD}" ]; then
		OPTIONS="${OPTIONS},password=${UPGRADE_USER_PASSWORD}";
	else
		OPTIONS="${OPTIONS},guest";
	fi
	if [ ! -d /mnt ]; then
		mkdir /mnt;
	fi
	mount "${UPGRADE_SERVER}:${UPGRADE_DIRNAME}" /mnt -t cifs ${OPTIONS};
	if [ $? -ne 0 ]; then
		echo -ne "ERROR:\nFailed to mount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME} using CIFS.\n"
		exit 40;
	fi
	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]; then
		echo -ne "Downloading new bootloader ... ";
		cp "/mnt/${LOCAL_BOOTLOADER_FILENAME}" ${LOCAL_BOOTLOADER_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD} using CIFS.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi	
	if [ "X${UPGRADE_KERNEL}" == "Xy" ]; then
		echo -ne "Downloading new kernel ... ";
		cp "/mnt/${UPGRADE_FILENAME_KERNEL}" ${LOCAL_KERNEL_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL} using CIFS.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_INITRD}" == "Xy" ]; then
		echo -ne "Downloading new initrd ... ";
		cp "/mnt/${UPGRADE_FILENAME_INITRD}" ${LOCAL_INITRD_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD} using CIFS.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	umount /mnt;
	if [ $? -ne 0 ]; then
		echo -ne "ERROR:\nFailed to unmount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME}.\n"
		exit 40;
	fi
}

uart_get_images()
{
	cd $(dirname ${LOCAL_BOOTLOADER_FILENAME});
	DONE=0;
	while [ $((DONE)) -eq 0 ]; do
		echo
		echo "Device ready to receive data."
		echo "On the host side initiate the ZMODEM transaction"
		echo "for the following files:"
		if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] && [ ! -f ${LOCAL_BOOTLOADER_FILENAME} ]; then
			echo $(basename ${LOCAL_BOOTLOADER_FILENAME});
			rm -f ${LOCAL_BOOTLOADER_FILENAME}
		fi
		if [ "X${UPGRADE_KERNEL}" == "Xy" ] && [ ! -f ${LOCAL_KERNEL_FILENAME} ]; then
			echo $(basename ${LOCAL_KERNEL_FILENAME});
			rm -f ${LOCAL_KERNEL_FILENAME}
		fi
		if [ "X${UPGRADE_INITRD}" == "Xy" ] && [ ! -f ${LOCAL_INITRD_FILENAME} ]; then
			echo $(basename ${LOCAL_INITRD_FILENAME});
			rm -f ${LOCAL_INITRD_FILENAME}
		fi
		lrz --binary
		DONE=1;

		# lrz doesn't rename file so it's not sure what the file name is but 
		# we will assume the names follow some standard convention, and
		# change them to a common one
		if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] && \
			[ ! -f ${LOCAL_BOOTLOADER_FILENAME} ] && \
			[ -f *bootloader*.bin ]
		then
			mv *bootloader*.bin ${LOCAL_BOOTLOADER_FILENAME}
		fi
		if [ "X${UPGRADE_KERNEL}" == "Xy" ] && \
			[ ! -f ${LOCAL_KERNEL_FILENAME} ] && \
			[ -f *kernel*.img ]
		then
			mv *kernel*.img ${LOCAL_KERNEL_FILENAME}
		fi
		if [ "X${UPGRADE_INITRD}" == "Xy" ] && \
			[ ! -f ${LOCAL_INITRD_FILENAME} ] && \
			[ -f *initrd*.img ] 
		then
			mv *initrd*.img ${LOCAL_INITRD_FILENAME}
		fi

		# Check the file are there
		if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] && [ ! -f ${LOCAL_BOOTLOADER_FILENAME} ]; then
			DONE=0;
		fi
		if [ "X${UPGRADE_KERNEL}" == "Xy" ] && [ ! -f ${LOCAL_KERNEL_FILENAME} ]; then
			DONE=0;
		fi
		if [ "X${UPGRADE_INITRD}" == "Xy" ] && [ ! -f ${LOCAL_INITRD_FILENAME} ]; then
			DONE=0;
		fi
	done
	cd
}

mount_nand_extra_partitions()
{

	i=0;
	OLD_IFS=${IFS};
	IFS=",";
	for part in ${CFGDEVICES_BOOTDEV_MTDPARTS}
	do
		name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/')
		case ${name} in
			mboot*) 
				i=$((i+1))
				;;
			initrd*) 
				i=$((i+1))
				;;
			kernel*) 
				i=$((i+1))
				;;
			rootfs*) 
				i=$((i+1))
				;;
			*) break
				;;
		esac
	done

	# now mount any extra partitions
	if [ "X${CFGDEVICES_ROOTDEV_EXTRA_MTDPARTS}" != "X" ]
	then
		load_module mtdblock
	fi

	for part in ${CFGDEVICES_ROOTDEV_EXTRA_MTDPARTS}
	do
		MOUNTPOINT=`echo ${part}|busybox cut -d':' -f1`
		FSTYPE=`echo ${part}|busybox cut -d':' -f2`

		# skip raw partitions
		if [ "X${FSTYPE}" == "Xraw" ]
		then
			i=$((i+1));
			continue
		fi

		mount |grep -sq /dev/mtdblock${i}
		if [ $? -ne 0 ] 
		then
			if [ ! -d /${MOUNTPOINT} ]
			then
				mkdir -p /${MOUNTPOINT};
			fi
			busybox chmod 777 /${MOUNTPOINT}

			if [ ! -e /dev/mtdblock${i} ]
			then
				mknod /dev/mtdblock${i} b 31 ${i}
			fi
			mount -t ${FSTYPE} /dev/mtdblock${i} /${MOUNTPOINT}
			if [ $? -ne 0 ]
			then
				echo -ne "ERROR:  Failed to mount NAND partition /dev/mtdblock${i}\n"
				exit 41
			fi
		fi
		i=$((i+1));
	done
	IFS=${OLD_IFS};
}

nand_get_images()
{
	mount_nand_extra_partitions

	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]; then
		echo -ne "Downloading new bootloader ... ";
		cp "/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_BOOTLOADER}" ${LOCAL_BOOTLOADER_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /data/${UPGRADE_FILENAME_INITRD}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_KERNEL}" == "Xy" ]; then
		echo -ne "Downloading new kernel ... ";
		cp "/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL}" ${LOCAL_KERNEL_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /data/${UPGRADE_FILENAME_KERNEL}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_INITRD}" == "Xy" ]; then
		echo -ne "Downloading new initrd ... ";
		cp "/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD}" ${LOCAL_INITRD_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /data/${UPGRADE_FILENAME_INITRD}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
}

mount_usb_device()
{
	mount | grep -sq '/mnt type'
	if [ $? -ne 0 ]
	then
		mkdir /mnt
		load_module sd_mod
		load_module usb-storage
		load_module dwc_otg

		count=0
		while [ $count -le 30 ]
		do
			if [ -e /sys/block/sda ]
			then
				break
			else
				sleep 1
			fi
			count=$((count+1))
		done

		if [ ! -e /sys/block/sda ]
		then
			echo "ERROR:  USB device not found!\n"
			exit 40
		fi

		DEV=/dev/sda
		mknod ${DEV} b 8 0
		# just in case there are no partitions
		ID_FS_TYPE=$(/lib/udev/vol_id ${DEV} | grep ID_FS_TYPE | sed -e 's/ID_FS_TYPE=//')
		if [ "X$ID_FS_TYPE" == "X" ]
		then
			DEV=/dev/sda1
			mknod ${DEV} b 8 1
			ID_FS_TYPE=$(/lib/udev/vol_id ${DEV} | grep ID_FS_TYPE | sed -e 's/ID_FS_TYPE=//')
		fi
		if [ "X$ID_FS_TYPE" == "X" ]
		then
			echo -ne "ERROR:\nUnrecognized filesystem: $ID_FS_TYPE\n"
			exit 40;
		fi
		if [ "X$ID_FS_TYPE" != "Xjfs" ] && \
			[ "X$ID_FS_TYPE" != "Xxfs" ] && \
			[ "X$ID_FS_TYPE" != "Xvfat" ] && \
			[ "X$ID_FS_TYPE" != "Xext2" ] && \
			[ "X$ID_FS_TYPE" != "Xext3" ] 
		then
			echo -ne "ERROR:\nUnrecognized filesystem: $ID_FS_TYPE\n"
			exit 40;
		fi
		mount -t $ID_FS_TYPE ${DEV} /mnt
		if [ $? -ne 0 ]
		then
			echo -ne "ERROR:  Failed to mount NAND data partition\n"
			exit 41
		fi
	fi
}

usb_get_images()
{
	mount_usb_device

	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]; then
		echo -ne "Downloading new bootloader ... ";
		cp "/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_BOOTLOADER}" ${LOCAL_BOOTLOADER_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /mnt/${UPGRADE_FILENAME_INITRD}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_KERNEL}" == "Xy" ]; then
		echo -ne "Downloading new kernel ... ";
		cp "/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_KERNEL}" ${LOCAL_KERNEL_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /mnt/${UPGRADE_FILENAME_KERNEL}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
	if [ "X${UPGRADE_INITRD}" == "Xy" ]; then
		echo -ne "Downloading new initrd ... ";
		cp "/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_INITRD}" ${LOCAL_INITRD_FILENAME};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to copy /mnt/${UPGRADE_FILENAME_INITRD}.\n"
			exit 41;
		fi
		echo -ne "done.\n";
	fi
}

if [ "X${UPGRADE_MODE}" == "Xshell" ]; then
	echo "Starting a shell, when done exit and the boot process will continue ..."
	/bin/sh;
	exit 0;
elif [ "X${UPGRADE_MODE}" == "Xabort" ]; then
	echo "Upgrade aborted, continue the boot process ..."
	exit 0;
elif [ "X${CONFIG_UPGRADE_CUSTOM}" == "Xy" ]
then
	if [ -e ${CONF_DIR}/helpers/customupdate ]
	then
		${DISPLAY} "\nExecuting Custom update script\n"
		/bin/sh ${CONF_DIR}/helpers/customupdate
		exit 0
	else
		${DISPLAY} "skipped.\n";
		exit 0
	fi
else
	# for modes: ftp, cifs, nfs, uart, http

	CORRECT=""
	until [ "X${CORRECT}" == "Xy" ] || [ "X${CORRECT}" == "XY" ] 
	do
		get_params
		echo -ne "Is this correct(y/N) ? ";
		read CORRECT
	done

	echo -e "\nWARNING: All data in selected sections will be deleted!!"
	echo -ne "Do you want to continue (y/N) ? ";
	read VALIDATE
	if [ "X${VALIDATE}" != "Xy" ] && [ "X${VALIDATE}" != "XY" ]; then
		echo "Upgrade aborted by user.";
		exit 0;
	fi
	echo

	if [ "X${UPGRADE_MODE}" == "Xftp" ] || \
		[ "X${UPGRADE_MODE}" == "Xcifs" ] ||  \
		[ "X${UPGRADE_MODE}" == "Xhttp" ] ||  \
		[ "X${UPGRADE_MODE}" == "Xnfs" ]
	then
		echo
		if [ -z "${UPGRADE_SERVER}" ]; then
			echo "ERROR: You must specify a server to upgrade from in ${UPGRADE_MODE} upgrade."
			exit 1;
		fi
		echo -ne "Starting network ... ";
		${HELPERS_DIR}/network start;
		if [ $? -ne 0 ]; then
			exit 1;
		fi
		echo -ne "done.\n";
	fi
fi

#Check the configuration we are in before proceeding
if [ "X${CONFIG_BOOT_DEVICE_RAM}" == "Xy" ] || \
	   [ "X${CONFIG_BOOT_DEVICE_XMODEM}" == "Xy" ] || \
	   [ "X${CONFIG_BOOT_DEVICE_MEMTEST}" == "Xy" ]; then

	if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] || \
		[ "X${UPGRADE_KERNEL}" == "Xy" ] || \
		[ "X${UPGRADE_INITRD}" == "Xy" ]; then
		echo "ERROR: the boot device is not upgradeable.";
		exit 10;
	fi
fi

if [ "X${CONFIG_ROOTFS_DEVICE_RAM}" == "Xy" ]
then
	if [ "X${UPGRADE_ROOTFS}" == "Xy" ]
	then
		echo "ERROR: the root filesystem device is not upgradeable.";
		exit 11;
	fi
fi

if [ "X${REPARTITION}" == "Xy" ] 
then
	if [ "X${UPGRADE_BOOTLOADER}" != "Xy" ] || \
		[ "X${UPGRADE_KERNEL}" != "Xy" ] || \
		[ "X${UPGRADE_INITRD}" != "Xy" ] || \
		[ "X${UPGRADE_ROOTFS}" != "Xy" ]
	then
		echo "ERROR:  All images must be updated if repartitioning the devices"
		exit 12;
	fi
fi

# Now we create a tmpfs drive to download the boot images on it
mkdir /upgrade
mount none /upgrade -t tmpfs
if [ $? -ne 0 ]; then
	echo "ERROR: failed to allocate RAM drive to store the images."
	exit 20;
fi

# We upgrade the boot device
if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] || [ "X${UPGRADE_KERNEL}" == "Xy" ] || [ "X${UPGRADE_INITRD}" == "Xy" ]; then

	# Now we download all the boot images
	LOCAL_BOOTLOADER_FILENAME="/upgrade/bootloader.bin";
	LOCAL_KERNEL_FILENAME="/upgrade/kernel.img";
	LOCAL_INITRD_FILENAME="/upgrade/initrd.img";

	if [ "X${UPGRADE_MODE}" == "Xftp" ]
	then
		ftp_get_images
	elif [ "X${UPGRADE_MODE}" == "Xhttp" ]
	then
		http_get_images
	elif [ "X${UPGRADE_MODE}" == "Xnfs" ]
	then
		nfs_get_images
	elif [ "X${UPGRADE_MODE}" == "Xcifs" ]
	then
		cifs_get_images
	elif [ "X${UPGRADE_MODE}" == "Xuart" ]
	then
		uart_get_images
	elif [ "X${UPGRADE_MODE}" == "Xusb" ]
	then
		usb_get_images
	fi

	# Load any required and missing module
	echo -ne "Initializing access to the boot device ... ";
	LOAD_MODULES=
	if [ "X${CFGDEVICES_BOOTDEV}" == "Xnand" ]; then
		LOAD_MODULES="${LOAD_MODULES} nand aumb3000_nand";
		BOOT_MTDDEV="aumb3000-nand";
		WRBLOCKSIZE=$((CONFIG_NAND_PAGESIZE));
	elif [ "X${CFGDEVICES_BOOTDEV}" == "Xnor" ]; then
		LOAD_MODULES="${LOAD_MODULES} mhif mg3500_flash cfi_probe cfi_util cfi_cmdset_0001 cfi_cmdset_0002";
		BOOT_MTDDEV="physmap-flash";
		WRBLOCKSIZE=1;
	else
		echo -ne "ERROR:\nUnsupported Boot device.\n";
		exit 60;
	fi
	if [ -n "${BOOT_MTDDEV}" ]; then
		LOAD_MODULES="${LOAD_MODULES} mtdchar";
		if [ "X${BOOTDEV_MTDPARTS}" != "X" ]
		then
			load_module cmdlinepart "mtdparts=${BOOT_MTDDEV}:${BOOTDEV_MTDPARTS}"
		else
			load_module cmdlinepart
		fi
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to load module cmdlinepart.\n";
			exit 61;
		fi
	fi
	for module in ${LOAD_MODULES}; do
		load_module ${module}
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to load module ${module}.\n";
			exit 62;
		fi
	done
	echo -ne "done.\n"

	if [ "X${UPGRADE_MODE}" == "Xnand" ]
	then
		nand_get_images
	fi

	# WARNING: we only support MTD devices for now
	if [ -n "${BOOT_MTDDEV}" ]
	then
		i=0;
		OLD_IFS=${IFS};
		IFS=",";

		# if repartitioning, lets erase all the non-core partitions here, this 
		# should allow any filesystem partitions to be mounted properly during 
		# bootup
		if [ "X${REPARTITION}" == "Xy" ] 
		then
			for part in ${BOOTDEV_MTDPARTS}
			do
				name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/')
				case ${name} in
					mboot*) 
						i=$((i+1))
						;;
					initrd*) 
						i=$((i+1))
						;;
					kernel*) 
						i=$((i+1))
						;;
					rootfs*) 
						i=$((i+1))
						;;
					*)  
						mknod /dev/mtd$((i)) c 90 $((i*2));
						if [ $? -ne 0 ]; then
							echo -ne "ERROR: Failed to create access node to /dev/mtd$((i)).\n"
							exit 70;
						fi
						echo  -ne "Erasing partition /dev/mtd$((i)) ... ";echo
						flash_eraseall /dev/mtd$((i))
						if [ $? -ne 0 ]; then
							echo -ne "ERROR:\nFailed to erase /dev/mtd$((i)).\n"
							exit 71;
						fi
						echo -ne "done.\n"
						i=$((i+1))
						;;
				esac
			done
		fi

		i=0;
		for part in ${BOOTDEV_MTDPARTS}; do
			name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/');
			if [ -z "$(echo ${name} | sed -e 's/mboot[0-9]*//')" ] && [ "X${UPGRADE_BOOTLOADER}" == "Xy" ]
			then
				type=bootloader;
				file=${LOCAL_BOOTLOADER_FILENAME};
			elif [ -z "$(echo ${name} | sed -e 's/kernel[0-9]*//')" ] && [ "X${UPGRADE_KERNEL}" == "Xy" ]
			then
				type=kernel;
				file=${LOCAL_KERNEL_FILENAME};
			elif [ -z "$(echo ${name} | sed -e 's/initrd[0-9]*//')" ] && [ "X${UPGRADE_INITRD}" == "Xy" ]
			then
				type=initrd;
				file=${LOCAL_INITRD_FILENAME};
			else
				i=$((i+1));
				continue;
			fi

			mknod /dev/mtd$((i)) c 90 $((i*2));
			if [ $? -ne 0 ]; then
				echo -ne "ERROR: Failed to create access node to /dev/mtd$((i)).\n"
				exit 70;
			fi
			echo -ne "Erasing ${type} partition /dev/mtd$((i)) ... ";echo
			flash_eraseall /dev/mtd$((i))
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to erase /dev/mtd$((i)).\n"
				exit 71;
			fi
			echo -ne "done.\n"
			echo -ne "Writing new ${type} into /dev/mtd$((i)) ... "
			if [ "X${CFGDEVICES_BOOTDEV}" == "Xnand" ]; then
				nandwrite -p /dev/mtd$((i)) ${file}
				if [ $? -ne 0 ]; then
					echo -ne "ERROR:\nFailed to copy ${file} on NAND device ${RAW_DEVICE}.\n"
					exit 150;
				fi
			else
				dd if=${file} of=/dev/mtd$((i)) bs=$((WRBLOCKSIZE)) conv=sync
				if [ $? -ne 0 ]; then
					echo -ne "ERROR:\nFailed to copy ${file} to /dev/mtd$((i)).\n"
					exit 72;
				fi
			fi
			echo -ne "done.\n"
			i=$((i+1));
		done
		IFS=${OLD_IFS};
	fi
#	echo -ne "Cleanup all modules loaded ... "
#	for module in ${LOAD_MODULES}; do
#		/sbin/modprobe -r ${module};
#	done
	rm /upgrade/*
	echo -ne "done.\n"
fi

# Last we update the root filesystem. We try to do that without
# storing anything on the device because the root filesystem
# may be too big
if [ "X${UPGRADE_ROOTFS}" == "Xy" ]
then

	if [ "X${UPGRADE_ROOTFS_TYPE}" == "Xtar" ]  ||  \
		[ "X${UPGRADE_ROOTFS_TYPE}" == "Xtgz" ] || \
		[ "X${UPGRADE_ROOTFS_TYPE}" == "Xgz" ]	|| \
		[ "X${UPGRADE_ROOTFS_TYPE}" == "Xbz2" ]
	then
		UPGRADE_ROOTFS_TYPE_TAR=1;
	# Otherwise we write directly to the device
	elif [ "X${UPGRADE_ROOTFS_TYPE}" == "Xbin" ] || [ "X${UPGRADE_ROOTFS_TYPE}" == "Ximg" ]; then
		UPGRADE_ROOTFS_TYPE_TAR=0;	
	else
		echo "ERROR: Unknown rootfs image type ${UPGRADE_ROOTFS_TYPE}.";
		exit 80
	fi
	# We initialize the root filesystem 
	# Load any required and missing module
	echo -ne "Initializing access to the root device ... ";
	LOAD_MODULES=
	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ]; then
		LOAD_MODULES="${LOAD_MODULES} nand aumb3000_nand";
		ROOT_MTDDEV="aumb3000-nand";
		WRBLOCKSIZE=$((CONFIG_NAND_PAGESIZE));
	elif [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]; then
		LOAD_MODULES="${LOAD_MODULES} mhif mg3500_flash cfi_probe cfi_util cfi_cmdset_0001 cfi_cmdset_0002";
		ROOT_MTDDEV="physmap-flash";
		WRBLOCKSIZE=1;
	elif [ "X${CFGDEVICES_ROOTDEV}" == "Xnfs" ]; then
		ROOT_MTDDEV=;
		WRBLOCKSIZE=1;
		if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
			echo "ERROR:\nYou cannot use an image when upgrading an NFS rootfs.\n";
			exit 81;
		fi
	else
		echo -ne "ERROR:\nUnsupported Root device.\n";
		exit 82;
	fi
	if [ -n "${ROOT_MTDDEV}" ]; then
		LOAD_MODULES="${LOAD_MODULES} mtdchar mtdblock";
		if [ "X${ROOTDEV_MTDPARTS}" != "X" ]
		then
			load_module cmdlinepart "mtdparts=${ROOT_MTDDEV}:${ROOTDEV_MTDPARTS}"
		else
			load_module cmdlinepart
		fi
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to load module cmdlinepart.\n";
			exit 83;
		fi
	fi
	if [ "X${CFGDEVICES_ROOTDEV_FS}" != "Xtmpfs" ]; then
		# tmpfs is compiled in the kernel
		LOAD_MODULES="${LOAD_MODULES} ${CFGDEVICES_ROOTDEV_FS}";	
	fi
	for module in ${LOAD_MODULES}; do
		load_module ${module};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to load module ${module}.\n";
			exit 84;
		fi
	done
	echo -ne "done.\n"
	# If we use a TAR file for the upgrade we 
	# format the root filesystem, then we mount it
	i=0;
	OLD_IFS=${IFS};
	IFS=",";
	for part in ${ROOTDEV_MTDPARTS}; do
		name=$(echo ${part} | sed -e 's/[^\(]*[\(]\([^\)]*\)[\)].*/\1/');
		if [ -z "$(echo ${name} | sed -e 's/rootfs//')" ]; then
			break;
		fi
		i=$((i+1));
	done
	IFS=${OLD_IFS};
	# Prepare the root filesystem to be mounted
	# For MTD devices that means erasing them, for most others
	# it means formatting the device
	MOUNT_DEVICE=;
	MOUNT_OPTIONS="-o defaults";
	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]; then
		RAW_DEVICE="/dev/mtd$((i))";
		mknod ${RAW_DEVICE} c 90 $((i*2));
		if [ $? -ne 0 ]; then
			echo -ne "ERROR: failed to create access node to /dev/mtd$((i)).\n"
			exit 90;
		fi
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to erase /dev/mtd$((i)).\n"
			exit 91;
		fi
		echo -ne "done.\n";
		if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
			MOUNT_DEVICE="/dev/mtdblock$((i))";
			mknod ${MOUNT_DEVICE} b 31 $((i));
			if [ $? -ne 0 ]; then
				echo -ne "ERROR: failed to create access node to /dev/mtdblock$((i)).\n"
				exit 92;
			fi
		fi
	elif [ "X${CFGDEVICES_ROOTDEV}" == "Xnfs" ]; then
		MOUNT_DEVICE="${CONFIG_ROOTFS_NFS_PATH}";
		MOUNT_OPTIONS="${MOUNT_OPTIONS},nolock";
		if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -eq 0 ]; then
			echo -ne "ERROR: You cannot upgrade an NFS root filesystem using a binary image.\n"
			exit 95;
		fi
	fi
	# Now comes the hard stuff, we must install the rootfs
	# image but avoid downloading it first. If we have
	# to download it we create a tmpfs and copy the 
	# file there.
	rm -f /upgrade/*
	if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
		LOCAL_ROOTFS_IMAGE_FILENAME="/upgrade/rootfs.tgz";
	else
		LOCAL_ROOTFS_IMAGE_FILENAME="/upgrade/rootfs.bin";
	fi
	if [ "X${UPGRADE_MODE}" == "Xftp" ]; then
		OPTIONS="";
		if [ -n "${UPGRADE_USER_NAME}" ]; then
			OPTIONS="${OPTIONS} -u ${UPGRADE_USER_NAME}";
		fi
		if [ -n "${UPGRADE_USER_PASSWORD}" ]; then
			OPTIONS="${OPTIONS} -p ${UPGRADE_USER_PASSWORD}";
		fi
		echo -ne "Downloading new root filesystem ... ";
		ftpget ${OPTIONS} ${UPGRADE_SERVER} ${LOCAL_ROOTFS_IMAGE_FILENAME} ${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_ROOTFS} on ${UPGRADE_SERVER} using FTP.\n"
			exit 100;
		fi
		# Now the image is accessible
		echo -ne "done.\n";

	elif [ "X${UPGRADE_MODE}" == "Xhttp" ]; then
		echo -ne "Downloading new root filesystem ... ";
		wget http://${UPGRADE_SERVER}/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS} -O ${LOCAL_ROOTFS_IMAGE_FILENAME}
		if [ $? -ne 0 ]
		then
			echo -ne "ERROR:\nFailed to retrieve ${UPGRADE_FILENAME_ROOTFS} on ${UPGRADE_SERVER} using HTTP.\n"
			exit 100;
		fi
		# Now the image is accessible
		echo -ne "done.\n";

	elif [ "X${UPGRADE_MODE}" == "Xnfs" ]; then
		OPTIONS="-o defaults,ro,nolock";
		if [ ! -d /mnt ]; then
			mkdir /mnt
		fi
		mount "${UPGRADE_SERVER}:${UPGRADE_DIRNAME}" /mnt -t nfs ${OPTIONS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to mount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME} using NFS.\n"
			exit 110;
		fi
		LOCAL_ROOTFS_IMAGE_FILENAME=/mnt/${UPGRADE_FILENAME_ROOTFS};
	elif [ "X${UPGRADE_MODE}" == "Xcifs" ]; then
		OPTIONS="-o defaults,ro";
		if [ -n "${UPGRADE_USER_NAME}" ]; then
			OPTIONS="${OPTIONS},user=${UPGRADE_USER_NAME}";
		fi
		if [ -n "${UPGRADE_USER_PASSWORD}" ]; then
			OPTIONS="${OPTIONS},password=${UPGRADE_USER_PASSWORD}";
		else
			OPTIONS="${OPTIONS},guest";
		fi
		if [ ! -d /mnt ]; then
			mkdir /mnt
		fi
		mount "${UPGRADE_SERVER}:${UPGRADE_DIRNAME}" /mnt -t nfs ${OPTIONS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to mount ${UPGRADE_SERVER}:${UPGRADE_DIRNAME} using NFS.\n"
			exit 120;
		fi
		LOCAL_ROOTFS_IMAGE_FILENAME=/mnt/${UPGRADE_FILENAME_ROOTFS};
	elif [ "X${UPGRADE_MODE}" == "Xuart" ]; then
		cd $(dirname ${LOCAL_ROOTFS_IMAGE_FILENAME});
		DONE=0;
		while [ $((DONE)) -eq 0 ]; do
			echo 
			echo "Device ready to receive data."
			echo "On the host side initiate the ZMODEM transaction"
			echo "for the following file:"
			echo $(basename ${LOCAL_ROOTFS_IMAGE_FILENAME});
			lrz --binary
			DONE=1;

			if [ ! -f ${LOCAL_ROOTFS_IMAGE_FILENAME} ] && [ -f *rootfs* ] 
			then
				mv *rootfs* $(basename ${LOCAL_ROOTFS_IMAGE_FILENAME})
			fi
			# Check the file are there
			if [ ! -f ${LOCAL_ROOTFS_IMAGE_FILENAME} ]; then
				echo "Missing $(basename ${LOCAL_ROOTFS_IMAGE_FILENAME})";
				DONE=0;
			fi
		done
		cd
	elif [ "X${UPGRADE_MODE}" == "Xnand" ]; then
		mount_nand_extra_partitions
		LOCAL_ROOTFS_IMAGE_FILENAME=/data/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS};
	elif [ "X${UPGRADE_MODE}" == "Xusb" ]; then
		mount_usb_device
		LOCAL_ROOTFS_IMAGE_FILENAME=/mnt/${UPGRADE_DIRNAME}/${UPGRADE_FILENAME_ROOTFS};
	fi

	if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ] || [ "X${CFGDEVICES_ROOTDEV}" == "Xnor" ]
	then
		if [ -e ${LOCAL_ROOTFS_IMAGE_FILENAME} ]
		then
			echo -ne "Erasing root filesystem partition ... ";
			flash_eraseall ${RAW_DEVICE}
		else
			echo "rootFS file not found: ${LOCAL_ROOTFS_IMAGE_FILENAME}"
			exit 110
		fi
	fi

	if [ $((UPGRADE_ROOTFS_TYPE_TAR)) -ne 0 ]; then
		echo -ne "Mounting root filesystem ... ";
		if [ ! -d /rootfs ]; then
			mkdir /rootfs;
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to create /rootfs directory.\n"
				exit 100;
			fi
		fi
		mount ${MOUNT_DEVICE} /rootfs -t ${CFGDEVICES_ROOTDEV_FS} ${MOUNT_OPTIONS};
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to mount root filesystem.\n"
			exit 130;
		fi
		echo -ne "done.\n";
		# In NFS we now clean the root filesystem
		if [ "X${CFGDEVICES_ROOTDEV}" == "Xnfs" ]; then
			echo -ne "Cleaning root filesystem ... ";
			rm -rf /rootfs/*
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to erase data on NFS rootfs.\n"
				exit 102;
			fi
			echo -ne "done.\n";
		fi
		# Extract the archive
		echo -ne "Installing new root filesystem ... ";
		if [ "X${UPGRADE_ROOTFS_TYPE}" == "Xgz" ] || [ "X${UPGRADE_ROOTFS_TYPE}" == "Xtgz" ]; then
			TAR='tar z';
		elif [ "X${UPGRADE_ROOTFS_TYPE}" == "Xbz2" ]; then
			TAR='tar j';
		else
			TAR='tar ';
		fi
		${TAR}xpf ${LOCAL_ROOTFS_IMAGE_FILENAME} -C /rootfs;
		if [ $? -ne 0 ]; then
			echo -ne "ERROR:\nFailed to untar ${LOCAL_ROOTFS_IMAGE_FILENAME}.\n"
			exit 140;
		fi
		echo -ne "done.\n";
	else
		# Flash the image directly on the device
		# Use nandwrite for a NAND or dd otherwise
		if [ "X${CFGDEVICES_ROOTDEV}" == "Xnand" ]; then
			nandwrite -p ${RAW_DEVICE} ${LOCAL_ROOTFS_IMAGE_FILENAME};
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to copy ${LOCAL_ROOTFS_IMAGE_FILENAME} on NAND device ${RAW_DEVICE}.\n"
				exit 150;
			fi
		else
			dd if=${LOCAL_ROOTFS_IMAGE_FILENAME} of=${RAW_DEVICE} bs=${CFGDEVICES_ROOTDEV_BLOCKSIZE};
			if [ $? -ne 0 ]; then
				echo -ne "ERROR:\nFailed to copy ${LOCAL_ROOTFS_IMAGE_FILENAME} on device ${RAW_DEVICE}.\n"
				exit 155;
			fi
		fi
	fi
	if [ $(mount | grep -c /rootfs) -ne 0 ]; then
		umount /rootfs;
		if [ $? -ne 0 ]; then
			echo -ne "WARNING:\nFailed to unmount /rootfs.\n"
		fi
	fi
	if [ $(mount | grep -c /mnt) -ne 0 ]; then
		umount /mnt;
		if [ $? -ne 0 ]; then
			echo -ne "WARNING:\nFailed to unmount /mnt.\n"
		fi
	fi
	if [ $(mount | grep -c /data) -ne 0 ]; then
		umount /data
		if [ $? -ne 0 ]; then
			echo -ne "WARNING:\nFailed to unmount /data.\n"
		fi
	fi
	rm -f /upgrade/*
# not all dependancies are being resolved by this unload
# however, is is really necessary to unload??
#echo -ne "Cleanup all modules loaded ... "
#	for module in ${LOAD_MODULES}; do
#		/sbin/modprobe -r ${module};
#	done
	echo -ne "done.\n"
fi

cd
umount /upgrade

if [ "X${UPGRADE_MODE}" == "Xftp" ] || \
	[ "X${UPGRADE_MODE}" == "Xcifs" ] || \
	[ "X${UPGRADE_MODE}" == "Xhttp" ] || \
	[ "X${UPGRADE_MODE}" == "Xnfs" ]
then
	echo -ne "Stopping network ... ";
	${HELPERS_DIR}/network stop;
	echo -ne "done.\n";
fi

if [ "X${UPGRADE_BOOTLOADER}" == "Xy" ] || [ "X${UPGRADE_KERNEL}" == "Xy" ] || [ "X${UPGRADE_INITRD}" == "Xy" ]; then
	echo "Rebooting the board to apply changes ... "
	# /sbin/reboot doesn't work here so we will just do what it eventually does  
	# also, want to play nice and make sure any mtdblock devices mounted are unmounted
	# can't do umount -a since we need /proc to do the reset
	mount |grep -sq mtdblock | \
	while read dev 
	do
		umount `echo $dev |cut -d" " -f1`
	done
	mount |grep -sq /mnt
	if [ $? -eq 0 ]
	then
		umount /mnt
	fi
	echo "0x8 0xC4 0x4 0x1" > /proc/driver/qcc/writebid
fi

exit 0;
