#!/bin/sh
set -e

# Set up quik, a boot loader for OldWorld PowerMacs and some non-Apple
# powerpc systems.

. /usr/share/debconf/confmodule

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

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

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

writefile () {
    cat >>"$1" || die quik-installer/conferr "Error writing $2"
}

findfs () {
    mount | grep "on /target${1%/} " | cut -d' ' -f1
}

db_progress START 0 0 quik-installer/progress

die () {
    template="$1"
    shift

    error "$@"
    db_input critical "$template" || [ $? -eq 30 ]
    db_go
    db_progress STOP
    exit 10
}

# Install quik in /target

db_progress INFO quik-installer/progress/apt-install

# Yes, it's a bit silly that we install yaboot. However, where else are we
# going to get ofpath?
if ! apt-install quik yaboot powerpc-utils; then
    info "Calling 'apt-install quik yaboot powerpc-utils' failed"
    # Hm, unable to install quik into /target/, what should we do?
    db_input critical quik-installer/apt-install-failed || [ $? -eq 30 ]
    if ! db_go; then
	db_progress STOP
	exit 10 # back up to menu
    fi
    db_get quik-installer/apt-install-failed
    if [ "$RET" != true ]; then
	db_progress STOP
	exit 10
    fi
fi

# Find the root partition and check that quik can cope with it.

db_progress STEP 1
db_progress INFO quik-installer/progress/checking

mountvirtfs () {
    fstype="$1"
    path="$2"
    if grep -q "[[:space:]]$fstype\$" /proc/filesystems && \
       ! grep -q "^[^ ]\+ \+$path " /proc/mounts; then
	mkdir -p "$path" || \
	    die quik-installer/mounterr "Error creating $path"
	mount -t "$fstype" "$fstype" "$path" || \
	    die quik-installer/mounterr "Error mounting $path"
	trap "umount $path" HUP INT QUIT KILL PIPE TERM EXIT
    fi
}

# ofpath needs proc in /target
mountvirtfs proc /target/proc
# ofpath needs sysfs in /target for 2.6
mountvirtfs sysfs /target/sys

root_devfs="$(findfs /)"
[ "$root_devfs" ] || die quik-installer/noroot 'No root partition found'

root="$(mapdevfs "$root_devfs")"
info "root partition: $root"
# If ATA (/dev/hd), then it must be on the first disk (/dev/hda).
if [ "${root#/dev/hd}" != "$root" ] && [ "${root#/dev/hda}" = "$root" ]; then
    die quik-installer/root_not_on_first_disk '/ not on first disk'
fi

boot_devfs="$(findfs /boot)"
[ "$boot_devfs" ] || boot_devfs="$root_devfs"
boot="$(mapdevfs "$boot_devfs")"
info "boot partition: $boot"
if [ "$boot_devfs" != "$root_devfs" ]; then
    # TODO: Is this still required, now that we put kernel symlinks in
    # /boot?
    die quik-installer/boot_not_on_root '/boot not on /'
fi

if ! grep '[[:space:]]/target[[:space:]]ext2[[:space:]]' /proc/mounts \
   >/dev/null; then
    die quik-installer/root_not_ext2 '/ not ext2'
fi

# Generate quik.conf

db_progress STEP 1
db_progress INFO quik-installer/progress/conf

partnr="`printf %s "$root" | sed 's/[^0-9]*\([0-9]\)/\1/'`"
disk="`printf %s "$boot" | sed 's/[0-9].*//'`"

if [ -e /target/boot/vmlinux ]; then
    kernel=/boot/vmlinux
else
    kernel=/vmlinux
fi

if [ -e /target/boot/initrd.img ]; then
    initrd=/boot/initrd.img
elif [ -e /target/initrd.img ]; then
    initrd=/initrd.img
else
    initrd=
fi

realkernel="$(readlink "/target$kernel")" || \
    die quik-installer/resolve_vmlinux \
	"readlink $kernel failed with exit status $?"
if [ "${realkernel#/}" = "$realkernel" ]; then
    # target symlink is relative
    realkernel="${kernel%/*}/$realkernel"
fi

# TODO: throw an error here rather than just forgetting about the initrd;
# can't fix this now due to the string freeze.
realinitrd="$(readlink "/target$initrd")" || \
    realinitrd=
if [ "$realinitrd" ] && [ "${realinitrd#/}" = "$realinitrd" ]; then
    # target symlink is relative
    realinitrd="${initrd%/*}/$realinitrd"
fi

rm -f /target/etc/quik.conf

writequikconf() {
    writefile /target/etc/quik.conf quik.conf
}

writequikconf <<EOF
## quik.conf generated by debian-installer

init-message="Debian GNU/Linux PowerPC (sarge)"
default=Linux
timeout=100
root=$root
partition=$partnr

## Do not point image= to a symlink, quik can't follow symlinks
image=$realkernel
	label=Linux
	read-only
EOF
if [ "$realinitrd" ]; then
    writequikconf <<EOF
	initrd=$realinitrd
EOF
fi
if [ "$video" ]; then
    writequikconf <<EOF
	append="video=$video"
EOF
fi

# Install bootstrap loader

db_progress STEP 1
db_progress INFO quik-installer/progress/install

db_get debian-installer/kernel/subarchitecture
SUBARCH="$RET"
info "subarchitecture: $SUBARCH"

# Warn that the system may not be bootable after this.
case $SUBARCH in
    powermac_oldworld)
	WARNING_TEMPLATE=quik-installer/oldworld_warning
	;;
    *)
	WARNING_TEMPLATE=quik-installer/non_oldworld_warning
	;;
esac
db_input critical "$WARNING_TEMPLATE" || [ $? -eq 30 ]
db_go || exit 10
db_get "$WARNING_TEMPLATE"
[ "$RET" = true ] || exit 10

chroot /target quik -v -f || \
    die quik-installer/quikerr "quik failed with exit status $?"

# Configure OpenFirmware (OldWorld only)

db_progress STEP 1
db_progress INFO quik-installer/progress/openfirmware

if [ "$SUBARCH" = powermac_oldworld ]; then
    ofpath="`chroot /target ofpath "$disk"`"
    info "ofpath $disk: $ofpath"
    chroot /target nvsetenv boot-device "${ofpath}0" || \
	die quik-installer/boot-device_failed \
	    "nvsetenv boot-device \"${ofpath}0\" failed with exit status $?"
    chroot /target \
	nvsetenv boot-command "begin ['] boot catch 1000 ms cr again" ||
	die quik-installer/boot-command_failed \
	    "nvsetenv boot-command failed with exit status $?"
fi

# Done!

db_progress STEP 1
db_progress STOP

db_input medium quik-installer/success || [ $? -eq 30 ]
db_go
