#! /bin/sh -e
export LD_LIBRARY_PATH="/target/lib:/target/usr/lib"

. /usr/share/debconf/confmodule

log=/var/log/messages

log() {
    logger -t aboot-installer "$@"
}

error() {
    log "error: $@"
}

info() {
    log "info: $@"
}

# Make sure mtab in the chroot reflects the currently mounted partitions
update_mtab() {
    mtab=/target/etc/mtab
    grep /target /proc/mounts | (
        while read devpath mountpoint fstype options n1 n2 ; do
            devpath=`mapdevfs $devpath`
            mountpoint=`echo $mountpoint | sed s%^/target%%`
            # The sed line removes the mount point for root.
            if [ -z "$mountpoint" ]; then
                mountpoint="/"
            fi
            echo $devpath $mountpoint $fstype $options $n1 $n2
        done ) > $mtab
}

db_progress START 0 5 aboot-installer/progress/title


db_progress STEP 1
db_progress INFO aboot-installer/progress/step_install

if ! apt-install aboot; then
	info "Calling 'apt-install aboot' failed"
	db_input critical aboot-installer/apt-install-failed || [ $? -eq 30 ]
	db_go
	db_get aboot-installer/apt-install-failed
	if [ true != "$RET" ]; then
		db_progress STOP
		exit 1
	fi
fi

db_progress STEP 1
db_progress INFO aboot-installer/progress/step_bootdev


# TODO: detect whether a given disk is using BSD disklabels

for i in `/usr/lib/partconf/find-partitions 2>/dev/null \
	| grep '[[:space:]]ext2[[:space:]]' | cut -f1`
do
	# add it to the list.
	if [ -z "$PARTITIONS" ]; then
		PARTITIONS="`mapdevfs $i`"
	else
		PARTITIONS="${PARTITIONS},`mapdevfs $i`"
	fi
done

if [ -z "$PARTITIONS" ]; then
	# error: no viable ext2 partitions found, throw a debconf message
	# and exit with an error
	error 'No ext2 partitions found'
	db_input critical aboot-installer/no-partitions || [ $? -eq 30 ]
	db_go
	db_progress STOP
	exit 1
fi

# We'll need this to figure out which device /boot is on, just like
# grub does
update_mtab

# Figure out the /boot partition
realbootdev=`chroot /target df /boot \
	| sed -n -e'/^\/dev/ { s/[[:space:]].*//; p }'`

# If the /boot partition is ext2, set is as the default.
if [ -n "`chroot /target mount | grep \"${realbootdev}.*ext2\"`" ]
then
    defaultbootdev="$realbootdev"
fi

if [ "$defaultbootdev" ]; then
    db_set aboot-installer/bootdev "$defaultbootdev"
    prio=medium
else
    prio=high
fi

db_subst aboot-installer/bootdev PARTITIONS $PARTITIONS
db_input $prio aboot-installer/bootdev || [ $? -eq 30 ]
db_go

db_get aboot-installer/bootdev
bootdev=$RET

# Determine the name of the disk, and the partition number where
# aboot.conf is located, from the name of the selected partition.
bootdisk=`echo $bootdev | sed -e's/p*[0-9]*$//'`
partnum=${bootdev##*[a-z]}

db_progress STEP 1
db_subst aboot-installer/progress/step_install_loader BOOTDISK $bootdisk
db_progress INFO aboot-installer/progress/step_install_loader

info "Installing aboot on '$bootdisk'"
if [ -e /var/lib/aboot-installer/aboot-partnum ]; then
	partnum_arg=-f$(cat /var/lib/aboot-installer/aboot-partnum)
fi

chroot /target /sbin/swriteboot $partnum_arg $bootdisk /boot/bootlx
# TODO: should this say something if it fails, like grub-installer does?

db_progress STEP 1
db_subst aboot-installer/progress/step_config_loader PARTNUM $partnum
db_progress INFO aboot-installer/progress/step_config_loader

info "Configuring aboot to look in partition $partnum"
chroot /target /sbin/abootconf $bootdisk $partnum

# Edit /etc/aboot.conf to point to partnum.
ABOOTCONF=/target/etc/aboot.conf

rootdev=`chroot /target df / | sed -n -e'/^\/dev/ { s/[[:space:]].*//; p }'`

sed -e"/^0:/ c\
0:$partnum/vmlinuz ro initrd=/initrd.img root=$rootdev
/^1:/ c\
1:$partnum/vmlinuz.old ro initrd=/initrd.img.old root=$rootdev
" < $ABOOTCONF > ${ABOOTCONF}.new
mv ${ABOOTCONF}.new $ABOOTCONF

db_progress STEP 1

# Possibilities:
#
# If /boot is the chosen ext2 partition, and it's not part of /, there
# must be a reason -- copy /etc/aboot.conf under /boot.
#
# If / is the chosen ext2 partition, and /boot is not part of it, we're
# in trouble; we assumed above they were part of the same partition.  Now,
# as long as /boot is also ext2 and on the same physical device, this
# can be made to work, but we already wrote out a different aboot.conf
# above.  TODO: work on this case later.
#
# If / is the chosen ext2 partition, and /boot *is* part of it, piece of
# cake -- no copy needed.
#
# If we've been given a partition that matches neither /boot nor /,
# do a full copy of the bits we need.
#
if [ "$bootdev" = "$realbootdev" ] ; then
    if [ "$rootdev" != "$bootdev" ] ; then
        db_subst aboot-installer/progress/step_copy_kernel BOOTDEV $bootdev
        db_progress INFO aboot-installer/progress/step_copy_kernel
        mkdir /target/boot/etc/
        cp -a /target/etc/aboot.conf /target/boot/etc/
	# FIXME: we probably really want symlinks_in_boot here,
	# but that requires more finagling of aboot.conf in turn.
	realkernel=`readlink /target/vmlinuz`
	realinitrd=`readlink /target/initrd.img`
	if [ -n "$realkernel" ] ; then
	    ln -s ${realkernel##*/} /target/boot/vmlinuz
	fi
	if [ -n "$realinitrd" ] ; then
	    ln -s ${realinitrd##*/} /target/boot/initrd.img
	fi
    fi
elif [ "$bootdev" != "$rootdev" ] ; then
    # The chosen device is neither / nor /boot; special case.
    db_subst aboot-installer/progress/step_copy_kernel BOOTDEV $bootdev
    db_progress INFO aboot-installer/progress/step_copy_kernel

    # Do we have to figure out whether this device is mounted somewhere?
    mkdir -p /target/realboot
    chroot /target mount -text2 $bootdev /realboot

    # Figure out where the symlinks are pointed (normally boot, but
    # let's be robust)
    realkernel=`readlink /target/vmlinuz`
    realinitrd=`readlink /target/initrd.img`

    # Make the directories we need
    mkdir -p /target/realboot/etc /target/realboot/`dirname realkernel` \
             /target/realboot/`dirname realinitrd`

    # Copy everything we need -- config file, symlinks, symlink targets.
    cp -a /target/etc/aboot.conf /target/realboot/etc/
    cp -a /target/vmlinuz /target/initrd.img /target/realboot/
    cp -a "/target/$realkernel" "/target/realboot/$realkernel"
    cp -a "/target/$realinitrd" "/target/realboot/$realinitrd"

    chroot /target umount /target/realboot
    rmdir --ignore-fail-on-non-empty /target/realboot
fi

# TODO: hooks in /etc/kernel-img.conf, in case we move the device?

db_progress STEP 1
db_progress STOP
