#!/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 architecture
arch=$(uname -m)
# get adk target system
target=$(cat /etc/.adktarget)
if [ -z $target ]; then
  print autodetection of target failed
  exit 1
fi

function help {
	cat >&2 <<EOF
Syntax: fwinstall <archive> <device>
EOF
	exit 1
}

if [ -z $1 ]; then
  print no archive given
  help 
fi

if [ -z $2 ]; then
  print no device given
  help 
fi

archive=$1
device=$2
fs=ext4
cfgfssize=16384
tools="parted partprobe sfdisk mkfs.ext2"

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
  if [ $? -ne 0 ]; then
    echo "creating empty partition failed!"
    exit 1
  fi
}

# 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
  if [ $? -ne 0 ]; then
    echo "creating primary partition failed!"
    exit 1
  fi
}

function set_boot_flag {
  print setting bootflag on $1 partition $2
  parted -s $1 set $2 boot on > /dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo "setting bootflag failed!"
    exit 1
  fi
}

function change_part_type {
  print setting partition type on $1 partition $2 to $3
  sfdisk --change-id $1 $2 $3 >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo "changing partition type failed!"
    exit 1
  fi
}

function create_filesystem {
  print creating filesystem $2 on $1 partition $3
  mkfs.ext2 -j -F -q ${1}${3} >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo "creating filesystem on partition failed!"
    exit 1
  fi
}

function mount_fs {
  print mounting ${1}${2} to $4 with filesystem $3
  mount -t $3 ${1}${2} $4
  if [ $? -ne 0 ]; then
    echo "mounting filesystem failed!"
    exit 1
  fi
}

function extract_archive {
  print extracting archive $1 onto $2
  tar -C $2 -xpf $1
  if [ $? -ne 0 ]; then
    echo "archive extraction failed!"
    exit 1
  fi
}

function grub_install {
  print installing bootloader grub
(
  print set default=0
  print set timeout=1
  print serial --unit=0 --speed=115200
  print terminal_output serial
  print terminal_input serial
  consargs="console=ttyS0,115200"
  print
  print 'menuentry "GNU/Linux (OpenADK)" {'
  print "\tlinux /boot/kernel root=${device}1"
  print '}'
) >/mnt/boot/grub/grub.cfg
  grub-install $1 --root-directory /mnt
  if [ $? -ne 0 ]; then
    echo "grub install failed!"
    exit 1
  fi
}

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 $arch {
  (x86|x86_64)
    get_max_size $device
    create_label $device
    create_partition $device ext2 16385 $rootsize
    create_partition $device ext2 $(($rootsize+1)) $(($maxsize-1))
    set_boot_flag $device 1
    change_part_type $device 2 88
    partprobe $device
    sync
    create_filesystem $device $fs 1
    [[ -x /sbin/mdev ]] && mdev -s
    mount_fs $device 1 $fs /mnt
    extract_archive $archive /mnt
    grub_install $device
    fix_perm /mnt
    umount /mnt
    ;;
}

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