#!/bin/sh
#
# vliloconf
# This is a rewriten of liloconf, from Slackware 9.1 by Patrick V.
# Only the SIMPLE method was taken
# - add Xdialog
# - suggest MBR 
# - make boot-message.txt ONLY if not exist 
# - change menu-scheme to blue
# - add graphics mode if /boot/boot.bmp.conf exist
# - Fix autodetect bootable DOS partition
# - Fix autodetect root device 
# - Autodetect other Linux partitions
# - Add menu to add partitions
# - Can include initrd
# - Always run from root directory !

vdir=$(dirname $0)
. $vdir/vasm-functions

TMP=/var/log/setup/tmp
mkdir -p $TMP

# VARIABLES
TP_X=${1:-/}
if [ "$TP_X" = "/" ]; then
    ROOT_DIR=""
else
    ROOT_DIR=$TP_X
fi

# Determine the root partition (such as /dev/hda2)
ROOT_DEVICE=$2
if [ -z "$ROOT_DEVICE" ]; then
  ROOT_DEVICE=`cat /etc/fstab | awk '{if ($2 == "/") {print $1}}' `
  # This must be successfull
  if [ -z "$ROOT_DEVICE" ]; then
    ROOT_DEVICE=`mount | awk '{if ($3 == "/") {print $1}}'`
  fi
fi

# Figure out where the kernel is:
mkdir -p $ROOT_DIR/boot
if [ -r $ROOT_DIR/boot/vmlinuz ]; then
  KERNEL=$ROOT_DIR/boot/vmlinuz
elif [ -r $ROOT_DIR/vmlinuz ]; then
  KERNEL=$ROOT_DIR/vmlinuz
else
  errorbox "Cannot found kernel (vmlinuz). LILO install aborted"
  clean_exit 1
fi

LILO_CONF="$ROOT_DIR/etc/lilo.conf"

installcolor()
{
 if [ "$ROOT_DIR" ]; then
  lilo -r $T_PX -m /boot/map -C /etc/lilo.conf 1> /dev/null 2> /dev/null
 else
  lilo 1> /dev/null 2> /dev/null
 fi
 SUCCESS=$?

 if [ ! "$SUCCESS" = "0" ]; then # edit file to try lba32 mode:
  cat $T_PX/etc/lilo.conf | while read line ; do
   echo $line
   if [ "$line" = "# Start LILO global section" ] ; then
     echo "lba32 # Allow booting past 1024th cylinder with a recent BIOS"
   fi
  done > $T_PX/etc/lilo.conf.lba32
  mv $T_PX/etc/lilo.conf.lba32 $T_PX/etc/lilo.conf
  if [ "$ROOT_DIR" ]; then
   lilo -r $T_PX -m /boot/map -C /etc/lilo.conf 1> /dev/null 2> /dev/null
  else
   lilo 1> /dev/null 2> /dev/null
  fi
  SUCCESS=$?
 fi

 if [ ! "$SUCCESS" = "0" ]; then # some LILO error occured
  $DCMD --backtitle "$BACKTITLE" --title "LILO INSTALL ERROR # $SUCCESS" --msgbox \
  "Sorry, but the attempt to install LILO has returned an error, so LILO \
has not been correctly installed.  You'll have to use a bootdisk \
to start your \
machine instead.  It should still be possible to get LILO working by \
editing the /etc/lilo.conf and reinstalling LILO manually.  See the \
LILO man page and documentation in /usr/doc/lilo/ for more help." 11 60
  clean_exit 1
 fi
}

menu_boot()
{
$DCMD --backtitle "$BACKTITLE" --title "LILO INSTALL" --menu "\n
LILO (Linux Loader) allows you to boot various operating systems on
multiple partitions. To use it, you must install LILO on either:\n
 1. The Master Boot Record of your first hard drive. Use this except\n
    you are using another boot manager (e.g GRUB, PQMagic, NT Loader)\n
 2. The boot sector of your Linux partition. Then you need to:\n
      a) make the partition bootable (using fdisk for example).\n
      b) use another boot manager to boot this partition.\n
 3. A formatted floppy disk. The safest and the slowest.\n
Which option would you like?" \
20 74 4 \
"MBR" "install to Master Boot Record (simplest)" \
"SECTOR" "install to boot sector (need more manual setting)" \
"FLOPPY" "install to a formatted floppy in /dev/fd0 (A:)" \
"SKIP" "do not install LILO" \
2> $freply

 result=$?
 [ $result != 0 ] && return $result

reply="`cat $freply`"
case "$reply" in
  MBR)
  MBR_TARGET=/dev/sda
  echo $MBR_TARGET > $TMP/LILOMBR
  cat /proc/partitions | while read LINE ; do
   MAJOR="`echo $LINE | cut -f 1 -d ' '`"
   MINOR="`echo $LINE | cut -f 2 -d ' '`"
   if [ ! "$MINOR" = "0" -a ! "$MINOR" = "64" ]; then # ingore whole devices to weed out CD drives
    if [ "$MAJOR" = "3" ]; then
     MBR_TARGET=/dev/hda
     echo $MBR_TARGET > $TMP/LILOMBR
    elif [ "$MAJOR" = "22" -a ! "$MBR_TARGET" = "/dev/hda" ]; then
     MBR_TARGET=/dev/hdc
     echo $MBR_TARGET > $TMP/LILOMBR
    elif [ "$MAJOR" = "33" -a ! "$MBR_TARGET" = "/dev/hda" -a ! "$MBR_TARGET" = "/dev/hdc" ]; then
     MBR_TARGET=/dev/hde
     echo $MBR_TARGET > $TMP/LILOMBR
    elif [ "$MAJOR" = "34" -a ! "$MBR_TARGET" = "/dev/hda" -a ! "$MBR_TARGET" = "/dev/hdc" -a ! "$MBR_TARGET" = "/dev/hde" ]; then
     MBR_TARGET=/dev/hdg
     echo $MBR_TARGET > $TMP/LILOMBR
    fi
   fi
  done
  LILO_TARGET=`cat $TMP/LILOMBR`
  ;;
 SECTOR)
  LILO_TARGET="$ROOT_DEVICE"
  ;;
 FLOPPY)
  LILO_TARGET="/dev/fd0"
  ;;
 *)
  clean_exit
  ;;
esac 
return 0
}

# Menu to check if we want to use VESA framebuffer support:
menu_fb() {

  # if FB is not supported, skip
  if ! cat /proc/devices | grep "29 fb" 1> /dev/null ; then
    return $1
  fi

  $DCMD --backtitle "$BACKTITLE" --title "LILO FRAME BUFFER CONSOLE" \
  --default-item 1024x768x256 --menu "\n
It seems that your kernel supports the Linux frame buffer console.
If we enable this, it will allow more rows and columns of text on
the screen and give you a cool penguin logo at boot time. However,
the frame buffer text console is slower than the standard and not
every video card or monitor supports all of these video modes.\n
So, do you want this feature or just standard?" 20 72 6 \
  "standard" "Use the standard Linux console (the safe choice)" \
  "640x480x256" "Frame buffer console, 640x480x256" \
  "800x600x256" "Frame buffer console, 800x600x256" \
  "1024x768x256" "Frame buffer console, 1024x768x256" \
  "640x480x32k" "Frame buffer console, 640x480x32k" \
  "800x600x32k" "Frame buffer console, 800x600x32k" \
  "1024x768x32k" "Frame buffer console, 1024x768x32k" \
  "640x480x64k" "Frame buffer console, 640x480x64k" \
  "800x600x64k" "Frame buffer console, 800x600x64k" \
  "1024x768x64k" "Frame buffer console, 1024x768x64k" \
  2> $freply
  
  result=$?
  [ $result != 0 ] && return $result
  
  CONSOLETYPE="`cat $freply`"
  if [ "$CONSOLETYPE" = "1600x1200x16m" ]; then
    CONSOLENUM=799
  elif [ "$CONSOLETYPE" = "1600x1200x64k" ]; then
    CONSOLENUM=798
  elif [ "$CONSOLETYPE" = "1600x1200x32k" ]; then
    CONSOLENUM=797
  elif [ "$CONSOLETYPE" = "1600x1200x256" ]; then
    CONSOLENUM=796
  elif [ "$CONSOLETYPE" = "1280x1024x16m" ]; then
    CONSOLENUM=795
  elif [ "$CONSOLETYPE" = "1280x1024x64k" ]; then
    CONSOLENUM=794
  elif [ "$CONSOLETYPE" = "1280x1024x32k" ]; then
    CONSOLENUM=793
  elif [ "$CONSOLETYPE" = "1280x1024x256" ]; then
    CONSOLENUM=775
  elif [ "$CONSOLETYPE" = "1024x768x16m" ]; then
    CONSOLENUM=792
  elif [ "$CONSOLETYPE" = "1024x768x64k" ]; then
    CONSOLENUM=791
  elif [ "$CONSOLETYPE" = "1024x768x32k" ]; then
    CONSOLENUM=790
  elif [ "$CONSOLETYPE" = "1024x768x256" ]; then
    CONSOLENUM=773
  elif [ "$CONSOLETYPE" = "800x600x16m" ]; then
    CONSOLENUM=789
  elif [ "$CONSOLETYPE" = "800x600x64k" ]; then
    CONSOLENUM=788
  elif [ "$CONSOLETYPE" = "800x600x32k" ]; then
    CONSOLENUM=787
  elif [ "$CONSOLETYPE" = "800x600x256" ]; then
    CONSOLENUM=771
  elif [ "$CONSOLETYPE" = "640x480x16m" ]; then
    CONSOLENUM=786
  elif [ "$CONSOLETYPE" = "640x480x64k" ]; then
    CONSOLENUM=785
  elif [ "$CONSOLETYPE" = "640x480x32k" ]; then
    CONSOLENUM=784
  elif [ "$CONSOLETYPE" = "640x480x256" ]; then
    CONSOLENUM=769
  fi
  return 0
}

menu_param()
{

$DCMD --backtitle "$BACKTITLE" --title "LILO OPTIONAL PARAMETERS" --inputbox "\n
Some systems may need extra kernel parameters to boot properly.\n
For example:\n
  hdc=ide-scsi : use SCSI emulation for IDE CDWRITER on /dev/hdc\n
  nohotplug    : turnoff hotplug (including USB)\n
  noapic       : turnoff Advanced Programmable Interrupt Controller\n
Most systems work fine without any parameters. So if you have no 
idea, just leave this empty:" 16 75 2> $freply

result=$?
[ $result != 0 ] && return $result
 
  APPEND="`cat $freply`"
  return 0
}

menu_os()
{
###########################
## Build array of
#LILO_TYPE
#LILO_PART
#LILO_LABEL
#LILO_DESC
#LILO_TABLE

infobox "Detecting operating systems ..."

count=0
## Bootable windows partition first
PART=`fdisk -l | grep -E '^/dev/.* \* .*(FAT16)' | cut -f 1 -d ' '`
if [ "$PART" ]; then
  let count=count+1
  LILO_PART[$count]="$PART"
  LILO_LABEL[$count]="DOS"
  LILO_DESC[$count]="DOS ($PART)"
fi

PART=`fdisk -l | grep -E '^/dev/.* \* .*(FAT32|HPFS|NTFS|Win)' | cut -f 1 -d ' '`
if [ "$PART" ]; then
  let count=count+1
  LILO_PART[$count]="$PART"
  LILO_LABEL[$count]="Windows"
  LILO_DESC[$count]="Windows ($PART)"
fi

## Add current root
let count=count+1
LILO_PART[$count]="$ROOT_DEVICE"
LILO_LABEL[$count]="Linux"
LILO_DESC[$count]="Linux ($ROOT_DEVICE)"

## Add current root
let count=count+1
LILO_PART[$count]="$ROOT_DEVICE"
LILO_LABEL[$count]="Linux-tui"
LILO_DESC[$count]="Linux Text mode ($ROOT_DEVICE)"

## Add current root
let count=count+1
LILO_PART[$count]="$ROOT_DEVICE"
LILO_LABEL[$count]="Linux-gui"
LILO_DESC[$count]="Linux Graphic mode ($ROOT_DEVICE)"

## Add additional Linux
mkdir -p /tmp/lilo_mount &> /dev/null
for PART in `fdisk -l | grep -E '83 *Linux' | cut -f 1 -d ' '`; do
  if [ "$PART" != "$ROOT_DEVICE" ]; then
     if mount $PART /tmp/lilo_mount &> /dev/null; then
	if [ -r /tmp/lilo_mount/boot/vmlinuz ]; then
	    # Find out the distro
	    # Check for GNU/Linux distributions
	    if [ -f /tmp/lilo_mount/etc/vector-version ]; then
	      distribution="Vector"
	    elif [ -f /tmp/lilo_mount/etc/sysconfig/vector ]; then
	      distribution="Vector"
	    elif [ -f /tmp/lilo_mount/etc/slackware-version ]; then
	      distribution="Slackware"
	    elif [ -f /tmp/lilo_mount/etc/SuSE-release -o -f /etc/UnitedLinux-release ]; then
	      distribution="Suse"
	    elif [ -f /tmp/lilo_mount/etc/gentoo-release ]; then
	      distribution="Gentoo"
	    elif [ -f /tmp/lilo_mount/etc/debian_version ]; then
	      distribution="Debian"
	    elif [ -f /tmp/lilo_mount/etc/mandrake-release ]; then
	      distribution="Mandrake"
	    elif [ -f /tmp/lilo_mount/etc/redhat-release ]; then
	      distribution="Redhat"
	    elif [ -f /tmp/lilo_mount/etc/fedora-release ]; then
	      distribution="Fedora"
	    else
	      distribution="Linux"
	    fi
	    let count=count+1
	    num="`echo $PART | cut -b6-`"
	    LILO_PART[$count]="$PART"
	    LILO_LABEL[$count]="$distribution-$num"
	    LILO_DESC[$count]="$distribution Linux ($PART)"
	fi 
	umount /tmp/lilo_mount     
     fi
  fi  
done

## Show menu for selection
TEXT="\n
We have detected the following Operating systems in your computer.
Please select the ones you want to be included in the LILO boot menu:"
TITLE="LILO BOOT MENU"

echo '$DCMD --backtitle "$BACKTITLE" --title "$TITLE" --checklist "$TEXT" 18 70 6 \' > $fmenu

for (( ii=1; ii <= $count ; ii=ii+1 )); do
  echo "'${LILO_LABEL[$ii]}' '${LILO_DESC[$ii]}' on \\" >> $fmenu
done
echo '2> $freply' >> $fmenu

. $fmenu

result=$?
[ $result != 0 ] && return $result

if [ "$CMD" = "" ]; then
  CHOICES=`cat $freply | sed -e 's/"/ /g' -e 's/  / /g'`
else
  CHOICES=`cat $freply | sed -e 's!/! !g' -e 's/  / /g'`
fi

############################################################
# Here we go 

# Make a new boot_message if not exist


cat << EOF > $T_PX/etc/lilo.conf
# LILO configuration file
# generated by 'liloconfig'
#
# Start LILO global section
EOF
if [ "$APPEND" ]; then
  echo "append=\"$APPEND\"" >> $T_PX/etc/lilo.conf
fi
 cat << EOF >> $T_PX/etc/lilo.conf
boot = $LILO_TARGET
prompt
timeout = 1200
# Override dangerous defaults that rewrite the partition table:
change-rules
  reset
EOF


# USE bitmap if exist, otherwise text mode
if [ -r $T_PX/boot/boot.bmp.conf ]; then
  cat $T_PX/boot/boot.bmp.conf >> $T_PX/etc/lilo.conf
else
  ## make boot message
  if [ ! -f $T_PX/boot/boot_message.txt ]; then
    cat << EOF > $T_PX/boot/boot_message.txt
Please select the partition you would like to boot then press [enter].
If you want to boot another Linux partition, you may type
boot: linux root=<partition-name>

EOF
  fi

  cat << EOF >> $T_PX/etc/lilo.conf
menu-scheme = wb:bw:wb:bw
menu-title = "Welcome to LILO boot menu"
message = /boot/boot_message.txt
EOF
fi

 if [ "$CONSOLETYPE" = "standard" ]; then
   cat << EOF >> $T_PX/etc/lilo.conf
# Normal VGA console
vga = normal
EOF
else
   cat << EOF >> $T_PX/etc/lilo.conf
# VESA framebuffer console @ $CONSOLETYPE
vga = $CONSOLENUM
# Normal VGA console
# vga = normal
EOF
fi

   cat << EOF >> $T_PX/etc/lilo.conf
# VESA framebuffer console @ 1024x768x64k
# vga=791
# VESA framebuffer console @ 1024x768x32k
# vga=790
# VESA framebuffer console @ 1024x768x256
# vga=773
# VESA framebuffer console @ 800x600x64k
# vga=788
# VESA framebuffer console @ 800x600x32k
# vga=787
# VESA framebuffer console @ 800x600x256
# vga=771
# VESA framebuffer console @ 640x480x64k
# vga=785
# VESA framebuffer console @ 640x480x32k
# vga=784
# VESA framebuffer console @ 640x480x256
# vga=769

default = Linux

# End LILO global section
EOF

# Detect initrd
ROOT_INITRD=""
if [ -f /boot/initrd.gz ]; then
    ROOT_INITRD="initrd = /boot/initrd.gz"
fi

infobox "Making lilo.conf ..."

number=0
for (( ii=1; ii <= $count ; ii=ii+1 )); do
  # Skip if not chosen
  if ! echo $CHOICES | grep -qw ${LILO_LABEL[$ii]}; then
    continue
  fi
  number=`expr $number '+' 1` 

  TABLE="`echo ${LILO_PART[$ii]} | cut -b1-8`"
  case ${LILO_LABEL[$ii]} in
     "DOS"|"Windows")
cat << EOF >> $T_PX/etc/lilo.conf
# Partition $number : DOS/Windows 
other = ${LILO_PART[$ii]}
    label = ${LILO_LABEL[$ii]}
    table = $TABLE

EOF
    ;;

     "Linux")
  cat << EOF >> $T_PX/etc/lilo.conf
# Partition $number: Linux GUI mode
image = $KERNEL
 root = $ROOT_DEVICE
 label = Linux
 append = "$APPEND"
 read-only
 $ROOT_INITRD
EOF
    ;;

     "Linux-tui")
  cat << EOF >> $T_PX/etc/lilo.conf
# Partition $number: Linux TUI mode
image = $KERNEL
 root = $ROOT_DEVICE
 label = Linux-tui
 append = "2 $APPEND"
 read-only
 $ROOT_INITRD
EOF
    ;;

     "Linux-gui")
  cat << EOF >> $T_PX/etc/lilo.conf
# Partition $number: Linux GUI mode
image = $KERNEL
 root = $ROOT_DEVICE
 label = Linux-gui
 append = "5 $APPEND"
 read-only
 $ROOT_INITRD
EOF
    ;;

    *)
    if mount ${LILO_PART[$ii]} /tmp/lilo_mount; then
	cp -u /tmp/lilo_mount/boot/vmlinuz /boot/vmlinuz-${LILO_LABEL[$ii]}
	INITRD=`ls -1 /tmp/lilo_mount/boot/initrd.* 2>/dev/null | head -n1`
	if [ "$INITRD" ]; then
	    cp -u $INITRD /boot/initrd-${LILO_LABEL[$ii]}
	fi
	umount /tmp/lilo_mount
    fi
    INITRD=""
    if [ -f /boot/initrd-${LILO_LABEL[$ii]} ]; then
	INITRD="initrd = /boot/initrd-${LILO_LABEL[$ii]}"
    fi
    if [ -f /boot/vmlinuz-${LILO_LABEL[$ii]} ]; then
	cat << EOF >> $T_PX/etc/lilo.conf
# Partition $number: Linux
image = /boot/vmlinuz-${LILO_LABEL[$ii]}
  root = ${LILO_PART[$ii]}
  label = ${LILO_LABEL[$ii]}
  read-only
  $INITRD
EOF
  else
    infobox "Cannot install ${LILO_LABEL[$ii]}. Skipped." "ERROR"
    sleep 3  
  fi
esac
    
done

rmdir /tmp/lilo_mount

 # Done, now we must install lilo:
 infobox "Installing LILO ... "
 installcolor;
 # cat /etc/lilo.conf
 infobox "Installing LILO DONE"
 
 clean_exit 0
}

############################
# MAIN MENU
wizard menu_boot menu_fb menu_param menu_os menu_finish
