#!/bin/bash
#================
# FILE          : linuxrc
#----------------
# PROJECT       : OpenSuSE KIWI Image System
# COPYRIGHT     : (c) 2006 SUSE LINUX Products GmbH. All rights reserved
#               :
# AUTHOR        : Marcus Schaefer <ms@suse.de>
#               :
# BELONGS TO    : Operating System images
#               :
# DESCRIPTION   : This file includes functions for the OEM
#               : installation mode. Installation means a dump of
#               : the virtual disk file onto a preselected disk
#               :
#               :
# STATUS        : BETA
#----------------
#
#======================================
# OEMInstall
#--------------------------------------
function OEMInstall {
	# /.../
	# Installation mode: find a usable disk to install the image
	# on. The install image is a virtual disk. The system will be
	# rebooted at the end of this function
	# ----
	local count=0
	local dsize=0
	local index=0
	local message
	#======================================
	# Check for install mode indicator file
	#--------------------------------------
	if [ ! -f $VMX_SYSTEM ];then
		return
	fi
	#======================================
	# Display license if text exists
	#--------------------------------------
	displayEULA
	#======================================
	# Search CD/DVD/USB stick and mount it
	#--------------------------------------
	USBStickDevice install
	if [ $stickFound = 0 ];then
		Echo "Search for USB stick failed, checking CD/DVD drive"
		CDMount
		export OEMInstallType=CD
	else
		Echo "Found Stick: $stickRoot -> $stickSerial"
		mkdir -p /cdrom && mount $(ddn $stickRoot 2) /cdrom
		export OEMInstallType=USB
	fi
	#======================================
	# Search and ask for the install device
	#--------------------------------------
	IFS=$IFS_ORIG
	Echo "Searching harddrive for $OEMInstallType installation"
	hwinfo=/usr/sbin/hwinfo
	if [ "$OEMInstallType" = "USB" ];then
		deviceDisks=`$hwinfo --disk |\
			grep "Device File:" | cut -f2 -d: |\
			cut -f1 -d"(" | sed -e s"@$imageDiskDevice@@"`
	else
		deviceDisks=`$hwinfo --disk |\
			grep "Device File:" | cut -f2 -d: |\
			cut -f1 -d"("`
	fi
	export deviceDisks=`echo $deviceDisks`
	if [ -z "$deviceDisks" ];then
		systemException \
			"No device(s) for installation found... abort" \
		"reboot"
	fi
	Echo "Found following disk device(s)"
	count=0
	for i in $deviceDisks;do
		dsize=`partitionSize $i`
		dsizeMB=`expr $dsize / 1024`
		if [ "$dsizeMB" -gt 0 ];then
			Echo -b "Disk $count -> $i [ $dsizeMB MB ]"
			deviceArray[$count]=$i
			deviceDSize[$count]=$dsize
			count=`expr $count + 1`
		fi
	done
	if [ "$count" = "1" ];then
		#======================================
		# Found one single disk... use it
		#--------------------------------------
		instDisk=${deviceArray[0]}
	else
		#======================================
		# Found multiple disks...
		#--------------------------------------
		if [ -z "$OEM_SAP_INSTALL" ];then
			#======================================
			# standard mode, ask for install media
			#--------------------------------------
			hd="\"$TEXT_SELECT\""
			count=0
			for i in $deviceDisks;do
				dsize=`partitionSize $i`
				dsizeMB=`expr $dsize / 1024`
				if [ "$dsizeMB" -gt 0 ];then
					dname=`getDiskID $i`
					dname=`basename $dname | cut -c1-20`"..."
					if [ $count = 0 ];then
						dpara="$i \"$dname [ $dsizeMB MB ]\" on"
						count=1
					else
						dpara="$dpara $i \"$dname [ $dsizeMB MB ]\" off"
					fi
				fi
			done
			instDisk=$(runInteractive \
				"--stdout --radiolist $hd 20 75 15 $dpara"
			)
			if [ ! $? = 0 ];then
				systemException \
					"System installation canceled" \
				"reboot"
			fi
		else
			#======================================
			# SAP mode, use the smallest one
			#--------------------------------------
			count=0
			dsize=${deviceDSize[$count]}
			for i in $deviceDisks;do
				if [ ${deviceDSize[$count]} -lt $dsize ];then
					dsize=${deviceDSize[$count]}
					index=$count
				fi
				count=`expr $count + 1`
			done
			instDisk=${deviceArray[$index]}
		fi
	fi
	Echo "Entering installation mode for disk: $instDisk"
	if [ -z "$OEM_SAP_INSTALL" ];then
		TEXT_INST=$(
			getText "Destroying ALL data on %1, continue ?" $instDisk)
		Dialog --yesno "\"$TEXT_INST\"" 5 70
		if [ ! $? = 0 ];then
			systemException \
				"System installation canceled" \
			"reboot"
		fi
	fi
	clear
	#======================================
	# Import vmx configuration file
	#--------------------------------------
	importFile < $VMX_SYSTEM
	#======================================
	# Install disk system
	#--------------------------------------
	# install virtual disk image from the CD/DVD onto the
	# real disk. All data on the disk will be lost
	# ----
	imageZipped="uncompressed"
	imageDevice=$instDisk
	field=0
	#======================================
	# Evaluate OEM install file
	#--------------------------------------
	IFS=";" ; for n in $IMAGE;do
	case $field in
		0) field=1 ;; 
		1) imageName=$n   ; field=2 ;;
		2) imageVersion=$n; field=3 ;;
		3) imageZipped=$n ;
	esac
	done
	if [ "$imageZipped" = "compressed" ];then
		imageName="/cdrom/$imageName.gz"
		imageMD5="$imageName.md5"
	else
		imageName="/cdrom/$imageName"
		imageMD5="$imageName.md5"
	fi
	IFS=" "
	#======================================
	# Check MBR ID's...
	#--------------------------------------
	# /.../
	# mbr ID check is deactivated by default
	# see bug #525682 for details
	# ----
	nombridcheck=1
	if [ -z "$nombridcheck" ];then
		mbrD=$instDisk
		mbrI="cat $imageName"
		if [ "$imageZipped" = "compressed" ];then
			mbrI="gzip -cd $imageName"
		fi
		mbrM=`dd if=$mbrD bs=1 count=4 skip=$((0x1b8))|hexdump -n4 -e '"0x%x"'`
		mbrI=`$mbrI | dd  bs=1 count=4 skip=$((0x1b8))|hexdump -n4 -e '"0x%x"'`
		if [ $mbrM = $mbrI ];then
			systemException \
				"Base system already installed" \
			"reboot"
		fi	
	fi
	#======================================
	# read MD5 information...
	#--------------------------------------
	read sum1 blocks blocksize zblocks zblocksize < $imageMD5
	#======================================
	# Get available disk space
	#--------------------------------------
	haveKByte=`partitionSize $imageDevice`
	#======================================
	# Get required disk space, setup I/O
	#--------------------------------------
	needBytes=$(expr $blocks \* $blocksize)
	needKByte=`expr $needBytes / 1024`
	needMByte=`expr $needKByte / 1024`
	#======================================
	# Check disk space...
	#--------------------------------------
	haveMByte=`expr $haveKByte / 1024`
	needMByte=`expr $needKByte / 1024`
	Echo "Have size: $imageDevice -> $haveMByte MB"
	Echo "Need size: $imageName -> $needMByte MB"
	if [ $needMByte -gt $haveMByte ];then
		systemException \
			"Not enough space available for this image" \
		"reboot"
	fi
	#======================================
	# Dump image on disk
	#--------------------------------------
	dump="cat $imageName"
	if test "$imageZipped" = "compressed"; then
		dump="gzip -cd $imageName"
	fi
	if [ -x /usr/bin/dcounter ];then
		progressBaseName=$(basename $imageName)
		TEXT_LOAD=$(getText "Loading %1" $progressBaseName)
		dump="$dump | dcounter -s $needMByte -l \"$TEXT_LOAD \""
	fi
	Echo "Loading $imageName [$imageDevice] "
	if [ -x /usr/bin/dcounter ];then
		mkfifo /progress; errorLogStop
		(
			if ! eval $dump 2>/progress | dd bs=32k of=$imageDevice &>/dev/null
			then
				errorLogContinue
				systemException \
					"Failed to install image: $imageName -> $imageDevice" \
				"reboot"
			fi
		)&
		echo "cat /progress | dialog \
			--backtitle \"$TEXT_INSTALLTITLE\" \
			--progressbox 3 65
		" > /tmp/progress.sh
		if [ -e /dev/fb0 ];then
			fbiterm -m $UFONT -- bash -e /tmp/progress.sh
		else
			bash -e /tmp/progress.sh
		fi
		clear
	else
		if ! eval $dump | dd bs=32k of=$imageDevice &>/dev/null; then
			systemException \
				"Failed to install image: $imageName -> $imageDevice" \
			"reboot"
		fi
	fi
	if [ -x /usr/bin/dcounter ];then
		errorLogContinue
	fi
	#======================================
	# Check the md5sum of the raw disk
	#--------------------------------------
	Echo "Install complete, checking data..."
	verifyBytes=$((blocks * blocksize))
	verifyMByte=$((verifyBytes / 1048576))
	if [ -x /usr/bin/dcounter ];then
		test -e /progress || mkfifo /progress
		TEXT_VERIFY=$(getText "Verifying %1" $imageDevice)
		dump="cat $imageDevice"
		dump="$dump | dcounter -s $verifyMByte -l \"$TEXT_VERIFY \""
		errorLogStop
		(
			eval $dump 2>/progress |\
				head --bytes=$verifyBytes | md5sum - > /etc/ireal.md5
		)&
		echo "cat /progress | dialog \
			--backtitle \"$TEXT_INSTALLTITLE\" \
			--progressbox 3 65
		" > /tmp/progress.sh
		if [ -e /dev/fb0 ];then
			fbiterm -m $UFONT -- bash -e /tmp/progress.sh
		else
			bash -e /tmp/progress.sh
		fi
		clear
		errorLogContinue
	else
		dd if=$imageDevice bs=1024 |\
			head --bytes=$verifyBytes |\
			md5sum - > /etc/ireal.md5
	fi
	read sum2 dumy < /etc/ireal.md5
	if [ $sum1 != $sum2 ];then
		systemException \
			"Image checksum test failed" \
		"reboot"
	fi
	Echo "Image checksum test: fine :-)"
	Echo "System installation has finished"
	#======================================
	# Umount CD/DVD USB
	#--------------------------------------
	umount /cdrom
	#======================================
	# Reread partition table
	#--------------------------------------
	blockdev --rereadpt $imageDevice
	deviceTest=$(ddn $imageDevice 1)
	if ! waitForStorageDevice $deviceTest;then
		systemException \
			"Partition $deviceTest doesn't appear... fatal !" \
		"reboot"
	fi
	#======================================
	# Setup/Reset values for further boot
	#--------------------------------------
	export imageDiskExclude=$instDisk
	export imageDiskDevice=$imageDevice
	unset stickSerial
}
