#!/bin/sh
#  Note:	The above line determines what interpreter to use to interpret this script.
######################################################
#
#  Program Name:		installfunctions
#
#  Program Description:	Utility functions used throughout the install procedure.
#
#  Return value:			Varies per function
#
#  Rights to this program:
#
#  This script file is the property of iZ technology corporation (www.iZcorp.com).
#  Unauthorized distribution and/or use of this script is strictly prohibited and subject
#  to applicable laws.
#
######################################################

#
#  Declare constants and variables.
#
#  NOTE: 	To handle file names with spaces in them, the name and variable need to be
#		"surrounded by double quotes" like in this sentence.

FALSE=0
TRUE=1
FLOPPY="/boot/floppy"		# Cannot be /floppy.
CDROM="/boot/cdrom"
LOCAL_INSTALL="/boot/Install"
LOCAL_INSTALLCURRENT="/boot/InstallCurrent"
LOCAL_INSTALLPREVIOUS="/boot/InstallPrevious"
FLOPPY_MOUNT_POINT=""
CDROM_MOUNT_POINT=""
FIRST_MOUNT=0

BOOT_DIR="/boot"
HOME_DIR="${BOOT_DIR}/home"
RADAR_DIR="${HOME_DIR}/radar"
INSTALL_DIR="${RADAR_DIR}/install"
INSTALL_LOGS_DIR="${INSTALL_DIR}/logs"
INSTALL_MEDIA="${INSTALL_DIR}/installMedia"
#MYNAME=${0##*/}								#define in each script
#INSTALL_LOG="${INSTALL_LOGS_DIR}/${MYNAME}.log"	#define in each script
#LOG_RESULTS="/bin/tee -a ${INSTALL_LOG}"			#define in each script

DISK_ID_FILE="disk_id"
DISK_ID_FILE_PATCH="disk_id_patch"
DISK_ID_FILE_PATCH20="disk_id_patch20"
DISK_ID_FILE_PATCH30="disk_id_patch30"

ZIMAGE_PATTERN="RADAR24_v*.*.*_"
CHUNK_FILE_PREFIX="chunk"

MAJOR_VER=3
MIN_MINOR_VER=0
MAX_MINOR_VER=99

# Declare variables.
declare -i i
declare -i i_disknum

# Exit Code Constants.
EXIT_CODE_OK=0
EXIT_CODE_WRONG_NUMBER_OF_ARGUMENTS=118
EXIT_CODE_WRONG_VERSION=119
EXIT_CODE_INVALID_DISK=120
EXIT_CODE_UNABLE_TO_UNZIP=121
EXIT_CODE_UNABLE_TO_COPY=122
EXIT_CODE_UNABLE_TO_MOUNT=123
EXIT_CODE_UNABLE_TO_UNMOUNT=124
EXIT_CODE_UPGRADE_NO=125
EXIT_CODE_WRONG_DISK=126
EXIT_CODE_FAILED=127

# Debug Constants.
NULL_DEV="/dev/null>2>&1"


##########################################################
#
#	General message display and logging functions
#	NOTE:	Must put argument in quotes.
#
##########################################################

function PrintMessage
{
	/bin/echo -e $1
}

function LogMessage
{
	/bin/echo -e $1 | $LOG_RESULTS
}

function TimeStamp()
{
	timeStamp=$(/bin/date +%T)
	/bin/echo "TIMESTAMP: $timeStamp" | $LOG_RESULTS
}


##########################################################
#
#	Floppy mounting functions
#
##########################################################

function CheckFloppyMounted()
{
#	Return Values:
#		0		- a floppy is currently mounted
#		1		- a floppy is not currently mounted
#
	# Find the mount point
	/bin/mountvolume -p | $LOG_RESULTS
	FLOPPY_MOUNT_POINT=$(/bin/mountvolume -p | /bin/grep floppy | /bin/cut -b 42-62)
	PrintMessage "IsFloppyMounted():  Mount point = '$FLOPPY_MOUNT_POINT'."
	
	# Strip blanks from end, beginning of mount point location name
	FLOPPY_MOUNT_POINT=${FLOPPY_MOUNT_POINT%%  *}
	FLOPPY_MOUNT_POINT=${FLOPPY_MOUNT_POINT##*/}

	if [ -z "$FLOPPY_MOUNT_POINT" ]
	then
		LogMessage "No floppy is mounted."
		return $TRUE	# A floppy disk is not mounted
	else
		LogMessage "Floppy is mounted at '$FLOPPY_MOUNT_POINT'."
		return $FALSE	# A floppy disk is mounted
	fi
}

function MountFloppy()		#  Mount floppy disk read-only
{
#	Return Values:
#		EXIT_CODE_OK					- floppy mounted successfully
#		EXIT_CODE_UNABLE_TO_MOUNT		- mount command returned an error
#		EXIT_CODE_UNABLE_TO_UNMOUNT	- a floppy is already mounted and cannot be unmounted
#
	LogMessage "Looking for Floppy Disk ..."
	if [ "$FIRST_MOUNT" = "0" ]
	then
		UnMountFloppy
		local ret_unmount=$?
		PrintMessage "MountFloppy():  UnMountFloppy() returned $ret_unmount"

		if [ "$ret_unmount" = "$EXIT_CODE_UNABLE_TO_UNMOUNT" ]
		then
			return $EXIT_CODE_UNABLE_TO_UNMOUNT
		fi

		/bin/rm -f ${INSTALL_LOGS_DIR}/mkdir.log
		/bin/mkdir -p "$FLOPPY" > ${INSTALL_LOGS_DIR}/mkdir.log 2>&1
	fi
	
	if [ -d "$FLOPPY" ]
	then
		local ret_isunmounted=$TRUE
		if [ "$FIRST_MOUNT" = "0" ]
		then
			CheckFloppyMounted
			ret_isunmounted=$?
		fi

		/bin/rm -f ${INSTALL_LOGS_DIR}/mount.log
		/bin/mount -ro -t dos /dev/disk/floppy/raw $FLOPPY > ${INSTALL_LOGS_DIR}/mount.log 2>&1
		local ret_mount=$?
		local ret_string=$(/bin/cat ${INSTALL_LOGS_DIR}/mount.log | /bin/grep "General OS error")

		if [[ "$ret_string" != "" && "$ret_isunmounted" = $TRUE ]]
		then
			# We can assume no floppy is in the drive
			LogMessage "No floppy in drive."
			LogMessage "Floppy Disk is not mounted."
			return $EXIT_CODE_UNABLE_TO_MOUNT
		fi

		if [ "$ret_mount" != "0" ]
		then
			LogMessage "ERROR: Mounting floppy failed with exit code $ret_mount."
			LogMessage "Floppy Disk is not mounted."
			return $EXIT_CODE_UNABLE_TO_MOUNT			
		else
			return $EXIT_CODE_OK
		fi
	else
		LogMessage "ERROR: Cannot create floppy mount point '$FLOPPY'."
		LogMessage "Floppy Disk is not mounted."
		return $EXIT_CODE_UNABLE_TO_MOUNT	
	fi
}

function UnMountFloppy()
{
#	Return Values:
#		0							- unmount not necessary
#		1							- unmount necessary and successful
#		EXIT_CODE_UNABLE_TO_UNMOUNT	- unmount necessary but unable to unmount
#
	if CheckFloppyMounted		# Condition is true if disk is NOT mounted!
	then
		local mnt="/$FLOPPY_MOUNT_POINT"
		if [ "$FIRST_MOUNT" = "0" ]
		then
			mnt="${BOOT_DIR}/$FLOPPY_MOUNT_POINT"
		fi

		if /bin/unmount "$mnt"
		then
			LogMessage "Unmounted floppy."
			return $TRUE
		else
			LogMessage "ERROR: Can't unmount floppy."
			return $EXIT_CODE_UNABLE_TO_UNMOUNT
		fi
	else
		return $FALSE
	fi
}


##########################################################
#
#	CD mounting functions
#
##########################################################

function CheckCdromMounted()
{
#	Return Values:
#		0		- a disk is currently mounted
#		1		- a disk is not currently mounted
#
	# Find the mount point
	/bin/mountvolume -p | $LOG_RESULTS
	CDROM_MOUNT_POINT=$(/bin/mountvolume -p | /bin/grep /boot/cdrom | /bin/cut -b 43-62 | awk '{print $1}')
	PrintMessage "CheckCdromMounted(): Mount point = '$CDROM_MOUNT_POINT'."
	
	if [ "$CDROM_MOUNT_POINT" = "$CDROM" ]
	then
		LogMessage "Disk is mounted at '$CDROM_MOUNT_POINT'."
		return $FALSE	# A disk is mounted
	fi
	
	CDROM_MOUNT_POINT=$(/bin/mountvolume -p | /bin/grep "IDE master bus:1" | /bin/cut -b 43-62 | awk '{print $1}')

	if [ -z "$CDROM_MOUNT_POINT" ]
	then
		LogMessage "No disk is mounted."
		return $TRUE	# A disk is not mounted
	else
		LogMessage "Non-RADAR disk is mounted at '$CDROM_MOUNT_POINT'."
		return $FALSE	# A disk is mounted
	fi
}

function MountCdrom()		#  Mount CD-ROM disk read-only
{
#	Return Values:
#		EXIT_CODE_OK					- disk mounted successfully
#		EXIT_CODE_UNABLE_TO_MOUNT		- mount command returned an error
#		EXIT_CODE_UNABLE_TO_UNMOUNT	- a disk is already mounted and cannot be unmounted
#
	LogMessage "Looking for CD-ROM Disk ..."
	UnMountCdrom
	local ret_unmount=$?
	PrintMessage "MountCdrom():  UnMountCdrom() returned $ret_unmount"

	if [ "$ret_unmount" = "$EXIT_CODE_UNABLE_TO_UNMOUNT" ]
	then
		return $EXIT_CODE_UNABLE_TO_UNMOUNT
	fi
	
	if [ "$FIRST_MOUNT" = "0" ]
	then
		/bin/rm -f ${INSTALL_LOGS_DIR}/mkdir.log
		/bin/mkdir -p "$CDROM" > ${INSTALL_LOGS_DIR}/mkdir.log 2>&1
	fi

	if [ -d "$CDROM" ]
	then
		/bin/rm -f ${INSTALL_LOGS_DIR}/mount.log
		/bin/mount -ro -t iso9660 /dev/disk/ide/atapi/1/master/0/raw $CDROM > ${INSTALL_LOGS_DIR}/mount.log 2>&1
		local ret_mount=$?
		local ret_string=$(/bin/cat ${INSTALL_LOGS_DIR}/mount.log | /bin/grep "General OS error")

		if [ "$ret_string" != "" ]
		then
			# We can assume no disk is in the drive
			LogMessage "No disk in drive."
			LogMessage "CD-ROM Disk is not mounted."
			return $EXIT_CODE_UNABLE_TO_MOUNT
		fi

		if [ "$ret_mount" != "0" ]
		then
			LogMessage "ERROR: Mounting disk failed with exit code $ret_mount."
			LogMessage "CD-ROM Disk is not mounted."
			return $EXIT_CODE_UNABLE_TO_MOUNT			
		else
			return $EXIT_CODE_OK
		fi
	else
		LogMessage "ERROR: Cannot create CD mount point '$CDROM'."
		LogMessage "CD-ROM Disk is not mounted."
		return $EXIT_CODE_UNABLE_TO_MOUNT	
	fi
}

function UnMountCdrom()
{
#	Return Values:
#		0							- unmount not necessary
#		1							- unmount necessary and successful
#		EXIT_CODE_UNABLE_TO_UNMOUNT	- unmount necessary but unable to unmount
#
	if CheckCdromMounted		# Condition is true if disk is NOT mounted!
	then
		if /bin/unmount "$CDROM_MOUNT_POINT"
		then
			LogMessage "Unmounted disk."
			return $TRUE
		else
			LogMessage "ERROR: Can't unmount disk."
			return $EXIT_CODE_UNABLE_TO_UNMOUNT
		fi
	else
		return $FALSE
	fi
}


##########################################################
#
#	Network (local) mounting functions
#
##########################################################

function MountLocal()		#  Mount local install directory read-only
{
#	Return Values:
#		EXIT_CODE_OK					- local install mounted successfully
#		EXIT_CODE_UNABLE_TO_MOUNT		- mount command returned an error
#		EXIT_CODE_UNABLE_TO_UNMOUNT	- local install is already mounted and cannot be unmounted
#
	LogMessage "Looking for Net Install ..."
	if [[ -d "$LOCAL_INSTALLCURRENT" && -d "$LOCAL_INSTALL" ]]
	then
		if ValidateDiskID
		then
			# Already mounted
			LogMessage "Net Install is already mounted at '$MEDIA'."
			return $EXIT_CODE_OK
		fi

		if [ "$FIRST_MOUNT" = "0" ]
		then
			# If this isn't the first try, then just report not mounted
			LogMessage "Net Install is not mounted."
			return $EXIT_CODE_UNABLE_TO_MOUNT
		fi

		/bin/rm -f ${INSTALL_LOGS_DIR}/mount.log
		ZIPPED_FILES=$(ls -1 ${LOCAL_INSTALL}/${ZIMAGE_PATTERN}*.zip 2> /dev/null)
		
		major_ver=0
		minor_ver=0
		build_ver=0
		prev_major_ver=0
		prev_minor_ver=0
		prev_build_ver=0

		declare -i ver_count=0
		ZIPPED_FILE=""
				
		#
		#  Choose the most recent version
		#
		for ZFILE in $ZIPPED_FILES
		do
			VER=${ZFILE##*_v}
			VER=${VER%%_*}
			major_ver=${VER%%.*}
			minor_ver=${VER#*.} ; minor_ver=${minor_ver%.*}
			build_ver=${VER##*.}
			PrintMessage "Zipped file of RADAR v$VER found (major.minor.build = $major_ver.$minor_ver.$build_ver)."
			
			if [ $major_ver -gt $prev_major_ver ]
			then
				prev_major_ver=$major_ver
				prev_minor_ver=$minor_ver
				prev_build_ver=$build_ver
				ZIPPED_FILE=$ZFILE
			elif [[ $major_ver -ge $prev_major_ver && $minor_ver -gt $prev_minor_ver ]]
			then
				prev_major_ver=$major_ver
				prev_minor_ver=$minor_ver
				prev_build_ver=$build_ver
				ZIPPED_FILE=$ZFILE
			elif [[ $major_ver -ge $prev_major_ver && $minor_ver -ge $prev_minor_ver && $build_ver -gt $prev_build_ver ]]
			then
				prev_major_ver=$major_ver
				prev_minor_ver=$minor_ver
				prev_build_ver=$build_ver
				ZIPPED_FILE=$ZFILE
			fi	
		done
		
		if [ -f "$ZIPPED_FILE" ]
		then
			PrintMessage "Most recent version is: major.minor.build = $major_ver.$minor_ver.$build_ver"
			LogMessage "'$ZIPPED_FILE' selected for install."
			LogMessage "Unzipping '$ZIPPED_FILE' ..."
			/bin/unzip -o $ZIPPED_FILE -d $LOCAL_INSTALLCURRENT
			local ret_unzip=$?
			if [ "$ret_unzip" != "0" ]
			then
				LogMessage "ERROR: Unzipping '$ZIPPED_FILE' failed with exit code $ret_unzip."
				LogMessage "Net Install is not mounted."
				return $EXIT_CODE_UNABLE_TO_MOUNT
			else
				return $EXIT_CODE_OK
			fi
		else
			LogMessage "No valid net.zip file found."
			LogMessage "Net Install is not mounted."
			return $EXIT_CODE_UNABLE_TO_MOUNT
		fi
	else
		LogMessage "ERROR: Cannot find install directories '$LOCAL_INSTALL' and '$LOCAL_INSTALLCURRENT'."
		LogMessage "Net Install is not mounted."
		return $EXIT_CODE_UNABLE_TO_MOUNT
	fi
}


##########################################################
#
#	Validation functions
#
##########################################################

function ValidateDiskID
{
	MEDIA_DISK_ID_FILE=$DISK_ID_FILE
	if [ -f "${MEDIA}/$DISK_ID_FILE_PATCH30" ]
	then
		MEDIA_DISK_ID_FILE=$DISK_ID_FILE_PATCH30
	elif [ -f "${MEDIA}/$DISK_ID_FILE_PATCH20" ]
	then
		MEDIA_DISK_ID_FILE=$DISK_ID_FILE_PATCH20
	elif [ -f "${MEDIA}/$DISK_ID_FILE_PATCH" ]
	then
		MEDIA_DISK_ID_FILE=$DISK_ID_FILE_PATCH
	elif [ -f "${MEDIA}/$DISK_ID_FILE" ]
	then
		MEDIA_DISK_ID_FILE=$DISK_ID_FILE
	else
		return $EXIT_CODE_INVALID_DISK
	fi

	/bin/rm -f  ${INSTALL_DIR}/$DISK_ID_FILE
	/bin/cp ${MEDIA}/$MEDIA_DISK_ID_FILE ${INSTALL_DIR}/$DISK_ID_FILE
	return $EXIT_CODE_OK
}

function ValidateMedia
{
	# return value = version of software that the floppy contains or an error
	#
	#  Verify first installation diskette in a verification loop.
	#  There are two possible things that can result from this function:
	#	1.  Floppy/Cdrom in drive is not a valid RADAR install disk.
	#	2.  Floppy/Cdrom in drive is a valid RADAR install disk.
	#
	local ret_mount=$FALSE

	for MEDIA in $LOCAL_INSTALLCURRENT $CDROM $FLOPPY
	do
		case $MEDIA in
			$LOCAL_INSTALLCURRENT ) 
				MEDIA_NAME="Net Install"
				MountLocal
				ret_mount=$?
			;;
			$CDROM ) 
				MEDIA_NAME="CD-ROM Disk"
				MountCdrom
				ret_mount=$?
			;;
			$FLOPPY )
				MEDIA_NAME="Floppy Disk"
				MountFloppy
				ret_mount=$?
			;;
			* )
				return $EXIT_CODE_FAILED
			;;
		esac	# end case
		
		if [ "$ret_mount" = "$EXIT_CODE_OK" ]
		then
			LogMessage "$MEDIA_NAME mounted successfully to '$MEDIA'."

			if ValidateDiskID
			then
				# We found something valid--break out now
				return $EXIT_CODE_OK
			else
				LogMessage "No valid RADAR software on $MEDIA_NAME."
			fi
		else
			LogMessage "$MEDIA_NAME failed to mount to '$MEDIA' (return code = ${ret_mount}).\n"
		fi
	done	# end for loop
	
	LogMessage "No valid RADAR installation media detected."
	return $EXIT_CODE_UPGRADE_NO			
}


#
#  End of Script
#