#!/bin/mksh
# This file is part of the OpenADK project.
# install OpenADK to a block/flash device

if [ $(id -u) -ne 0 ];then
	print installation is only possible as root
	exit 1
fi

# get adk target system
target=$(cat /etc/.adktarget)
if [ -z $target ];then
	print autodetection of target failed
	exit 1
fi

function mikrotik-rb532-help {
	cat >&2 <<EOF
Syntax: adkinstall [-c|-n] <archive>
	-c: compact flash install
	-n: nand install
	-f: filesystem for compact flash
	-h: help text
EOF
	exit 1
}

function ibm-x40-help {
	cat >&2 <<EOF
Syntax: adkinstall <archive>
	-d: create data partition
	-f: filesystem (default ext4)
	-h: help text
EOF
	exit 1
}

function pcengines-apu-help {
	cat >&2 <<EOF
Syntax: adkinstall <archive>
	-f: filesystem (default ext4)
	-h: help text
EOF
	exit 1
}


case $target {
(ibm-x40)
	cfgfssize=32768
	data=
	fs=ext4
	while getopts "f:d:" ch; do
	case $ch in
		d)
			data=$OPTARG
			;;
		f)
			fs=$OPTARG
			;;
		*)
			ibm-x40-help
			exit 1
			;;
	esac
	done
	shift $((OPTIND - 1))
	if [ -z $1 ];then
		ibm-x40-help
	else
		archive=$1
	fi
	;;
(pcengines-apu)
	cfgfssize=32768
	fs=ext4
	while getopts "f:" ch; do
	case $ch in
		f)
			fs=$OPTARG
			;;
		*)
			pcengines-apu-help
			exit 1
			;;
	esac
	done
	shift $((OPTIND - 1))
	if [ -z $1 ];then
		pcengines-apu-help
	else
		archive=$1
	fi
	;;
(mikrotik-rb532)
	cfgfssize=32768
	nand=0
	cf=0
	fs=ext4
	while getopts "cnf:" ch; do
	case $ch in
		c)
			cf=1
			fs=ext4
			;;
		n)
			nand=1
			fs=yaffs2
			;;
		f)
			fs=$OPTARG
			;;
		*)
			mikrotik-rb532-help
			exit 1
			;;
	esac
	done
	shift $((OPTIND - 1))
	if [ -z $1 ];then
		mikrotik-rb532-help
	else
		archive=$1
	fi
	;;
(*)
	print target $target not supported
	exit 1
	;;
}

if [ "$target" = "mikrotik-rb532" ];then
	if [ $cf -eq 0 -a $nand -eq 0 ];then
		print "you either install on cf (-c) or nand (-n)"
		mikrotik-rb532-help
	fi
fi

tools="parted partprobe sfdisk mkfs.$fs"

f=0
for tool in $tools;do
	if ! which $tool >/dev/null; then
		echo "checking if $tool is installed... failed"
		f=1
	fi
done
if [ $f -eq 1 ];then exit 1;fi

# create empty partition table
function create_label {
	print "creating empty partition table"
	parted -s $1 mklabel msdos > /dev/null 2>&1
}

# get max size of disk in sectors
function get_max_size {
	maxsize=$(env LC_ALL=C parted $1 -s unit s print |awk '/^Disk/ { print $3 }'|sed -e 's/s//')
	rootsize=$(($maxsize-$cfgfssize))
	print device has $maxsize sectors. using $rootsize for root.
}

# create partition, with fstype start and end in sectors
function create_partition {
	print creating partition on $1
	parted -s $1 unit s mkpart primary $2 $3 $4 > /dev/null 2>&1
}

function set_boot_flag {
	print setting bootflag on $1 partition $2
	parted -s $1 set $2 boot on > /dev/null 2>&1
}

function change_part_type {
	print setting partition type on $1 partition $2 to $3
	sfdisk --change-id $1 $2 $3 >/dev/null 2>&1
}

function create_filesystem {
	print creating filesystem $2 on $1 partition $3
	mkfs.$2 -F -q ${1}${3}
}

function mount_fs {
	print mounting ${1}${2} to $4 with filesystem $3
	mount -t $3 ${1}${2} $4
}

function extract_archive {
	print extracting archive $1 onto $2
	tar -C $2 -xpf $1
}

function grub_install {
	print installing bootloader grub
(
        print set default=0
        print set timeout=1
        print serial --unit=0 --speed=$speed
        print terminal_output serial
        print terminal_input serial
        consargs="console=ttyS0,$speed"
        print
        print 'menuentry "GNU/Linux (OpenADK)" {'
        print "\tlinux /boot/kernel root=/dev/sda1"
        print '}'
) >/mnt/boot/grub/grub.cfg
	grub-install $1 --root-directory /mnt
}

function fix_perm {
	print fixing permissions
	chmod 1777 ${1}/tmp
	[[ -f ${1}/usr/bin/sudo ]] && chmod 4755 ${1}/usr/bin/sudo
	[[ -f ${1}/usr/bin/Xorg ]] && chmod 4755 ${1}/usr/bin/Xorg
}

case $target {
(ibm-x40)
	get_max_size /dev/sda
	create_label /dev/sda
	if [ -z $data ];then
		create_partition /dev/sda ext2 16385 $rootsize
		create_partition /dev/sda ext2 $(($rootsize+1)) $(($maxsize-1))
		set_boot_flag /dev/sda 1
		change_part_type /dev/sda 2 88
	else
		datasize=$(($data*1024*2))
		echo datasize is: $datasize
		echo create partition from 16385 to $(($rootsize-$datasize))
		create_partition /dev/sda ext2 16385 $(($rootsize-$datasize))
		echo create partition from $(($rootsize-$datasize+1)) to $(($maxsize-$cfgfssize-1))
		create_partition /dev/sda ext2 $(($rootsize-$datasize+1)) $(($maxsize-$cfgfssize-1))
		echo create partition from $(($maxsize-$cfgfssize)) to $(($maxsize-1))
		create_partition /dev/sda ext2 $(($maxsize-$cfgfssize)) $(($maxsize-1))
		set_boot_flag /dev/sda 1
		change_part_type /dev/sda 3 88

	fi
	partprobe /dev/sda
	sync
	sleep 2
	if [ -z $data ];then
		create_filesystem /dev/sda $fs 1
	else
		create_filesystem /dev/sda $fs 1
		create_filesystem /dev/sda $fs 2
	fi
	mdev -s
	mount_fs /dev/sda 1 $fs /mnt
	extract_archive $archive /mnt
	if [ ! -z $data ];then
		echo creating data dir and fstab entry
		mkdir /mnt/data
		echo "/dev/sda2	/data	ext4	rw	0	0" >> /mnt/etc/fstab 
	fi
	grub_install /dev/sda
	fix_perm /mnt
	umount /mnt
	;;
(pcengines-apu)
	get_max_size /dev/sda
	create_label /dev/sda
	create_partition /dev/sda ext2 16385 $rootsize
	create_partition /dev/sda ext2 $(($rootsize+1)) $(($maxsize-1))
	set_boot_flag /dev/sda 1
	change_part_type /dev/sda 2 88
	partprobe /dev/sda
	sync
	sleep 2
	create_filesystem /dev/sda $fs 1
	mdev -s
	mount_fs /dev/sda 1 $fs /mnt
	extract_archive $archive /mnt
	grub_install /dev/sda
	fix_perm /mnt
	umount /mnt
	;;
(mikrotik-rb532)
	if (( cf )); then
		get_max_size /dev/sda
		create_label /dev/sda
		create_partition /dev/sda ext2 1 16384
		create_partition /dev/sda ext2 16385 $rootsize
		create_partition /dev/sda ext2 $(($rootsize+1)) $(($maxsize-1))
		set_boot_flag /dev/sda 1
		change_part_type /dev/sda 1 27
		change_part_type /dev/sda 3 88
		partprobe /dev/sda
		sync
		sleep 2
		create_filesystem /dev/sda $fs 2
		mdev -s
		mount_fs /dev/sda 2 $fs /mnt
		extract_archive $archive /mnt
		print installing kernel to cf disk /dev/sda1
       		dd if=/mnt/boot/kernel of=/dev/sda1 bs=2048 >/dev/null 2>&1
		fix_perm /mnt
		umount /mnt
	fi
	if (( nand )); then
		mount_fs /dev/mtdblock 1 $fs /mnt
       		rm -rf /mnt/* >/dev/null 2>&1
       		mkdir /mnt/boot
		mount_fs /dev/mtdblock 0 $fs /mnt/boot
		extract_archive $archive /mnt
		fix_perm /mnt
		umount /mnt/boot
		umount /mnt
	fi
	;;
}

echo "successfully installed OpenADK on $target."
exit 0
