#!/bin/sh
set -e

. /usr/share/debconf/confmodule

newline="
"

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

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

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

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

lvm_vg () {
	# Map from /dev/mapper/<vg>-<lv> to /dev/<vg>/<lv> for 
	# Dup of code in partman.
	vglv=${1#/dev/mapper/}
	vglv=`echo "$vglv" | sed -e 's/\([^-]\)-\([^-]\)/\1 \2/' | sed -e 's/--/-/g'`
	vg=`echo "$vglv" | cut -d" " -f1`
	lv=`echo "$vglv" | cut -d" " -f2`
	lvdisplay -c "/dev/$vg/$lv"| sed 's/^[^:]*:\([^:]*\):.*$/\1/'
}

first_pv () {
	pvdisplay -c | grep "^[^:]*:$1:" | sed 's/^ *\([^:]*\):.*$/\1/' | head -n 1
}

rootfs_devfs=$(findfs /)
bootfs_devfs=$(findfs /boot)
[ -n "$bootfs_devfs" ] || bootfs_devfs="$rootfs_devfs"

rootfs=$(mapdevfs $rootfs_devfs)

bootvg=$(lvm_vg $bootfs_devfs)
if [ -n "$bootvg" ]; then
	bootfs_devfs=$(first_pv $bootvg)
fi

bootfs=$(mapdevfs $bootfs_devfs)

prefix=$(echo "$bootfs_devfs" | sed 's/\(\/dev\/[a-z]\+\).*/\1/')

if [ "$prefix" != /dev/md ]; then
	disc_offered_devfs=$(find $prefix -name disc | head -n 1)
else
	disc_offered_devfs="$bootfs_devfs"
fi
disc_offered=$(mapdevfs "$disc_offered_devfs")

db_capb backup

db_subst lilo-installer/bootdev disc "$disc_offered"
db_subst lilo-installer/bootdev part "$bootfs"

db_input high lilo-installer/bootdev || [ $? -eq 30 ]
db_go || exit 10 # back up

db_get lilo-installer/bootdev

case "$RET" in
  *Master*) bootdev=$(mapdevfs $disc_offered_devfs)  ;;
  *Debian*)
    bootdev=$(mapdevfs $bootfs_devfs)
    part=$(echo $bootdev | sed 's/.*\([0-9]\)/part\1/')
  ;;
  *Advanced*)
    not_done=1
    db_set lilo-installer/manual_bootdev "$disc_offered_devfs" || true

    while [ $not_done -eq 1 ]; do
      db_input critical lilo-installer/manual_bootdev || true
      db_go || exit 10
      db_get lilo-installer/manual_bootdev

      if [ -b "$RET" ]; then
        case "$RET" in
          /dev/ide*|/dev/discs/*|/dev/scsi/*)
	    bootdev="$(mapdevfs $RET)"
	    not_done=0
	    part=$(echo $bootdev | sed 's/.*\([0-9]\)/part\1/')
	  ;;
	  /dev/[hs]d[a-z][0-9])
	    bootdev=$RET;
	    not_done=0
	    part=$(echo $bootdev | sed 's/.*\([0-9]\)/part\1/')
	  ;;
	esac
      fi

      if [ $not_done -eq 1 ]; then
        db_subst lilo-installer/manual_bootdev_error path "$RET"
	db_input critical lilo-installer/manual_bootdev_error || true
	db_go || exit 10
      fi
    done
	  
  ;;
esac

db_subst lilo-installer/progress_active bootdev "$bootdev"
db_subst lilo-installer/progress_running bootdev "$bootdev"

db_progress start 0 4 lilo-installer/progress_title

db_progress info lilo-installer/progress_active

# If installing to a partition (not MBR), offer to make it active
if echo "${bootdev}" | grep -q '[0-9]$'; then
    # Installing to a partition, check if it is already marked active
    if ! fdisk -l ${disc_offered_devfs} | grep "^/dev[a-z0-9/]\+${part} " | grep -q '\*'; then
        # partition is not marked active, offer to make it so
        db_input high lilo-installer/activate-part || [ $? -eq 30 ]
        if ! db_go; then
	  db_progress stop
	  exit 10 # back up
	fi
        db_get lilo-installer/activate-part
        if [ "${RET}" = "true" ]; then
            pnum=$(echo ${bootdev} | sed 's/^.*\([0-9]\+\)$/\1/')
            echo -n "I: Setting partition to active..." >&2
            sfdisk -A${pnum} ${disc_offered_devfs}
            echo "done." >&2
        fi
    fi
fi

db_progress step 1

# Use a serial console if current default console is a serial port.
# default console is last listed
OLDIFS="$IFS"
IFS=" "
for arg in $(cat /proc/cmdline); do
  case "$arg" in
    console=*)
      defconsole=$arg
    ;;
  esac
done
IFS="$OLDIFS"

defconsole=$(sed -e 's/.*console=/console=/' /proc/cmdline)
if echo "${defconsole}" | grep -q console=ttyS; then
    PORT=$(echo "${defconsole}" | sed -e 's%^console=ttyS%%' -e 's%,.*%%')
    SPEED=$(echo "${defconsole}" | sed -e 's%^console=ttyS[0-9]\+,%%' -e 's% .*%%')
    SERIAL="${PORT},${SPEED}"

    db_subst lilo-installer/serial-console PORT "ttyS${PORT}"
    db_subst lilo-installer/serial-console SPEED "${SPEED}"
    db_input medium lilo-installer/serial-console || [ $? -eq 30 ]
    if ! db_go; then
      db_progress stop
      exit 10 # back up
    fi
fi

db_progress info lilo-installer/progress_lilo_conf

user_params=$(echo $(user-params)) || true
if [ -n "$user_params" ]; then
  APPEND="    append=\"$user_params\""
fi

#write out lilo.conf

if [ "${SERIAL}" ]; then
  SERIAL_CONSOLE="serial=${SERIAL}"
else
  SERIAL_CONSOLE="# serial="
fi

if [ "${SERIAL}" ]; then
  if [ -n "$user_params" ]; then
    APPEND="	append=\"$user_params console=ttyS${SERIAL}\""
  else
    APPEND="	append=\"console=ttyS${SERIAL}\""
  fi
fi

if [ -e "/target/initrd.img" ]; then
  INITRD="	initrd=/initrd.img"
  OLD_INITRD="${INITRD}.old"
fi

cat > /target/etc/lilo.conf <<EOF
# /etc/lilo.conf - See: \`lilo(8)' and \`lilo.conf(5)',
# ---------------       \`install-mbr(8)', \`/usr/share/doc/lilo/',
#                       and \`/usr/share/doc/mbr/'.

# +---------------------------------------------------------------+
# |                        !! Reminder !!                         |
# |                                                               |
# | Don't forget to run \`lilo' after you make changes to this     |
# | conffile, \`/boot/bootmess.txt' (if you have created it), or   |
# | install a new kernel.  The computer will most likely fail to  |
# | boot if a kernel-image post-install script or you don't       |
# | remember to run \`lilo'.                                       |
# |                                                               |
# +---------------------------------------------------------------+

# Specifies the boot device.  This is where Lilo installs its boot
# block.  It can be either a partition, or the raw device, in which
# case it installs in the MBR, and will overwrite the current MBR.
#
boot=${bootdev}

# Specifies the device that should be mounted as root. (\`/')
#
root=${rootfs}

# Enable map compaction:
# Tries to merge read requests for adjacent sectors into a single
# read request. This drastically reduces load time and keeps the
# map smaller.  Using \`compact' is especially recommended when
# booting from a floppy disk.  It is disabled here by default
# because it doesn't always work.
#
# compact

# Installs the specified file as the new boot sector
# You have the choice between: text, bmp, and menu
# Look in lilo.conf(5) manpage for details
#
#install=menu

# Specifies the location of the map file
#
map=/boot/map

# You can set a password here, and uncomment the \`restricted' lines
# in the image definitions below to make it so that a password must
# be typed to boot anything but a default configuration.  If a
# command line is given, other than one specified by an \`append'
# statement in \`lilo.conf', the password will be required, but a
# standard default boot will not require one.
#
# This will, for instance, prevent anyone with access to the
# console from booting with something like \`Linux init=/bin/sh',
# and thus becoming \`root' without proper authorization.
#
# Note that if you really need this type of security, you will
# likely also want to use \`install-mbr' to reconfigure the MBR
# program, as well as set up your BIOS to disallow booting from
# removable disk or CD-ROM, then put a password on getting into the
# BIOS configuration as well.  Please RTFM \`install-mbr(8)'.
#
# password=tatercounter2000

# Specifies the number of deciseconds (0.1 seconds) LILO should
# wait before booting the first image.
#
delay=20

# You can put a customized boot message up if you like.  If you use
# \`prompt', and this computer may need to reboot unattended, you
# must specify a \`timeout', or it will sit there forever waiting
# for a keypress.  \`single-key' goes with the \`alias' lines in the
# \`image' configurations below.  eg: You can press \`1' to boot
# \`Linux', \`2' to boot \`LinuxOLD', if you uncomment the \`alias'.
#
# message=/boot/bootmess.txt
#	prompt
#	delay=100
#	timeout=100

# Specifies the VGA text mode at boot time. (normal, extended, ask, <mode>)
#
# vga=ask
# vga=9
#
vga=normal

# Kernel command line options that apply to all installed images go
# here.  See: The \`boot-prompt-HOWTO' and \`kernel-parameters.txt' in
# the Linux kernel \`Documentation' directory.
#
# append=""
 
# If you used a serial console to install Debian, this option should be
# enabled by default.
${SERIAL_CONSOLE}

#
# Boot up Linux by default.
#
default=Linux

image=/vmlinuz
	label=Linux
	read-only
#	restricted
#	alias=1
${APPEND}
${INITRD}

image=/vmlinuz.old
	label=LinuxOLD
	read-only
	optional
#	restricted
#	alias=2
${APPEND}
${OLD_INITRD}


# If you have another OS on this machine to boot, you can uncomment the
# following lines, changing the device name on the \`other' line to
# where your other OS' partition is.
#
# other=/dev/hda4
#	label=HURD
#	restricted
#	alias=3
EOF

# Add other OSes.
probed="$(os-prober)" || true
count=2

OLDIFS="$IFS"
IFS="$newline"

if [ -n "$probed" ]; then
  for os in $probed; do
    IFS="$OLDIFS"
    partition=$(echo "$os" | cut -d: -f1)
    mappedpartition=$(mapdevfs $partition)
    label=$(echo "$os" | cut -d: -f3)
    type=$(echo "$os" | cut -d: -f4)
    case "$type" in
        chain)
            cat >> /target/etc/lilo.conf <<EOF
other=$mappedpartition
	label=$label
#	restricted
#	alias=$count
EOF
        ;;
	*)
	    info "unhandled: $os"
	;;
    esac
    IFS="$newline"
  done
  IFS="$OLDIFS"
fi

db_progress step 1

db_progress info lilo-installer/progress_installing

mount -t proc none /target/proc || true

if ! apt-install lilo ; then
	info "Calling 'apt-install lilo' failed"
	# Hm, unable to install lilo into /target/, what should we do?
	db_input critical lilo-installer/apt-install-failed || [ $? -eq 30 ]
	if ! db_go; then
		db_progress stop
		exit 10 # back up to menu
	fi
	db_get lilo-installer/apt-install-failed
	if [ true != "$RET" ] ; then
		db_progress stop
		exit 1
	fi
fi

db_progress step 1

db_progress info lilo-installer/progress_running

ERRCODE=0
chroot /target /sbin/lilo || ERRCODE=$?
if [ "$ERRCODE" != 0 ]; then
    db_subst lilo-installer/failed ERRCODE "$ERRCODE"
    db_input critical lilo-installer/failed || [ $? -eq 30 ]
    db_progress stop
    db_go || exit 10 # back up
    exit 1
fi

umount /target/proc || true

db_progress step 1

db_progress stop

sed -e 's/do_bootloader = no/do_bootloader = yes/' -e 's/postinst_hook = \/sbin\/update-grub//' -e 's/postrm_hook   = \/sbin\/update-grub//' < /target/etc/kernel-img.conf > /target/etc/kernel-img.conf.$$
mv /target/etc/kernel-img.conf.$$ /target/etc/kernel-img.conf
