#!/bin/bash
# Under the terms of the 'COPYRIGHT.TXT' file.

# Funciones:

# Funcin que escribe el archivo de configuracin para LILO:
write_liloconfig() {
  # Comprobaremos de qu Kernel se trata -- para pasarle el
  # argumento "lba32" a LILO; evitando problemas con el
  # soporte en BIOS de cilndros menores a 1024:
  if grep DKERNEL /proc/cmdline | grep -q gen.k ; then
    LBA="#lba32"
  else
    LBA="lba32"
  fi

  # Esto es para pasarle el parmetro del tipo de sistema de archivos a
  # el cargador de inicio, en este caso sera "ext4", de lo contrario,
  # al correr con ext4 como sistema de archivo, se obtiene un mensaje
  # "couldn't mount because of unsupported optional features (240)":
  if grep /mnt /proc/mounts | grep -q ext4 ; then
    APPEND="append = \"rootfstype=ext4\""
  fi

  cat << EOF > "$1"
# LILO configuration file.

# Global options:
append = "vt.default_utf8=0"
boot = $BOOT_DEV
menu-scheme=kw:Wg:kw:kw
message = /boot/bootmsg.txt
prompt
timeout=900
$LBA
change-rules
  reset
# VESA Framebuffer modes:
# Color:           640x480  800x600  1024x768  1280x1024
#
# 256k             769      771      773       775
# 32k              784      787      790       793
# 64k              785      788      791       794
# 16m              786      789      792       795
vga = normal

# Bootable partitions section:

# Linux partitions:
image = /boot/vmlinuz
  root = $ROOT_DEV
  label = Dragora
  read-only
  $APPEND

# Other operating systems:


EOF

  cat << EOF > ${TMP}/bootmsg.txt

LILO: the Linux Loader!

Select or enter the name of the partition to boot:

Dragora - (Dragora on ${ROOT_DEV})

EOF
}

# Funcin que escribe el archivo de configuracin para GRUB:
write_grubconfig() {
  if grep /mnt /proc/mounts | grep -q ext4 ; then
    APPEND="rootfstype=ext4"
  fi
  cat << EOF > "$1"
# GRUB configuration file.

# Global options:
set timeout=90
set default=0
set menu_color_normal=black/light-gray
set menu_color_highlight=white/green

# VESA Framebuffer modes:
# Color:           640x480  800x600  1024x768  1280x1024
#
# 256k             769      771      773       775
# 32k              784      787      790       793
# 64k              785      788      791       794
# 16m              786      789      792       795

# Bootable partitions section:

# Linux partitions:
menuentry "Dragora" {
  set root=(hd${BOOT_DSC},${BOOT_NUM})
  linux /boot/vmlinuz root=$ROOT_DEV ro vga=normal $APPEND
}

# Other operating systems:


EOF
}

# Men (loop):
while :; do
  dialog \
   --backtitle "Selecting the boot loader" \
   --title "BOOT LOADER" \
   --extra-button \
   --extra-label "Skip" \
   --cancel-label "Abort" \
   --menu \
"Select the boot loader for the system:" 0 0 0 \
   "GRUB" "Grand Unified Bootloader" \
   "LILO" "Linux Loader" \
    2> ${TMP}/return-menu-bootloader
  CODE=$?
  case "$CODE" in
    3)      CODE=0 ; break;;
    1|255)  CODE=99; break;;
  esac

  ROOT_DEV=$(cat ${TMP}/ROOT_DEV)

  BOOT=$(cat ${TMP}/return-menu-bootloader)

  # -- LILO --:
  if [[ $BOOT = LILO ]]; then
    # Chequeo de sanidad:
    if [[ ! -x /mnt/sbin/lilo ]]; then
      dialog \
       --msgbox "Unable to install LILO.\n\nThe package was NOT installed." 0 0
      continue;
    fi
    dialog --backtitle "Boot loader" --title "LILO" --menu \
"If you do not have a boot loader, it is recommended to install \
in the Master Boot Record (MBR), can also overwrite your boot loader.\n\n\
If you already have one, and do not want to overwrite it, you can\n\
install in the superblock of the Root partition.  But it is assumed \
that the partition \"boot flag\" is turned. That is to say, \
the Root partition is bootable.  Otherwise, you can use \
'cfdisk' or 'fdisk'.\n\n\
Select the destination of the boot loader:" 16 72 0 \
     "MBR"  "Install in the Master Boot Record" \
     "Root" "Install in the Superblock" \
      2> ${TMP}/return-menu-bootloader-lilo
     (( $? != 0 )) && continue;

     ANSWER=$(cat ${TMP}/return-menu-bootloader-lilo)

     case "$ANSWER" in
       MBR) # LILO MBR:
         BOOT_DEV=${ROOT_DEV:0:8}
         dialog --title "BOOT LOADER" --sleep 2 --infobox \
"Installing the boot loader in the Master Boot Record (${BOOT_DEV})..." 3 70
         write_liloconfig /mnt/etc/lilo.conf
         cat ${TMP}/bootmsg.txt > /mnt/boot/bootmsg.txt
         /mnt/sbin/lilo -C /mnt/etc/lilo.conf 1> $OUTPUT_TTY 2>&1
         RETCODE=$?
         if (( $RETCODE != 0 )); then
           dialog --title "ERROR" --sleep 5 --infobox \
"An error occurred while installing LILO.\n\n\
You will have to use a boot disk to start the machine.\n\
Check the configuration file for LILO (/etc/lilo.conf)\n\
and reinstall LILO manually.\n\n\
For more help read the man-page, or see the documentation of\n\
LILO in the directory /usr/doc.\n\n\
Also, you can re-run the installer and test\n\
with another boot loader, for example, with\n\
GRUB.\n\nLILO ERROR CODE: $RETCODE" 0 0
         fi
         ;;
     Root) # LILO Root:
       BOOT_DEV=$ROOT_DEV
       dialog --title "BOOT LOADER" --sleep 2 --infobox \
"Installing the boot loader in the Root partition (${BOOT_DEV})..." 3 68
       write_liloconfig /mnt/etc/lilo.conf
       cat ${TMP}/bootmsg.txt > /mnt/boot/bootmsg.txt
       /mnt/sbin/lilo -C /mnt/etc/lilo.conf 1> $OUTPUT_TTY 2>&1
       RETCODE=$?
       if (( $RETCODE != 0 )); then
         dialog --title "ERROR" --sleep 5 --infobox \
"An error occurred while installing LILO.\n\n\
You will have to use a boot disk to start the machine.\n\
Check the configuration file for LILO (/etc/lilo.conf)\n\
and reinstall LILO manually.\n\n\
For more help read the man-page, or see the documentation of\n\
LILO in the directory /usr/doc.\n\n\
Also, you can re-run the installer and test\n\
with another boot loader, for example, with\n\
GRUB.\n\nLILO ERROR CODE: $RETCODE" 0 0
       fi
       ;;
     esac
     # Edicin del archivo de configuracin de LILO:
     if [[ $RETCODE = 0 && -f /mnt/etc/lilo.conf ]]; then
       dialog \
        --backtitle "Edit LILO configuration file" \
        --title "LILO configuration file (lilo.conf)" \
        --ok-label "Save Changes" \
        --cancel-label "Continue" \
        --defaultno \
        --editbox /mnt/etc/lilo.conf 0 0 \
         2> ${TMP}/lilo.conf.edited
       if (( $? == 0 )); then
         ( cd /mnt/etc ; mv lilo.conf lilo.conf.bak )
         cat ${TMP}/lilo.conf.edited > /mnt/etc/lilo.conf
         /mnt/sbin/lilo -C /mnt/etc/lilo.conf 1> $OUTPUT_TTY 2>&1
         RETCODE=$?
         if (( $RETCODE != 0 )); then
           dialog --title "ERROR" --yesno \
"An error occurred while trying to \
update\nthe LILO configuration file.\n\n\
Want to restore the file and continue the installation?:\n\n\
LILO ERROR CODE: $RETCODE" 0 0
           if (( $? == 0 )); then
             ( cd /mnt/etc ; mv lilo.conf.bak lilo.conf )
             /mnt/sbin/lilo -C /mnt/etc/lilo.conf 1> $OUTPUT_TTY 2>&1
             RETCODE=$?
             if (( $RETCODE != 0 )); then
               dialog --title "ERROR" --sleep 5 --infobox \
"An error occurred while installing LILO.\n\n\
You will have to use a boot disk to start the machine.\n\
Check the configuration file for LILO (/etc/lilo.conf)\n\
and reinstall LILO manually.\n\n\
For more help read the man-page, or see the documentation of\n\
LILO in the directory /usr/doc.\n\n\
Also, you can re-run the installer and test\n\
with another boot loader, for example, with\n\
GRUB.\n\nLILO ERROR CODE: $RETCODE" 0 0
             fi
           fi
         else
           rm -f /mnt/etc/lilo.conf.bak
         fi
       fi
     fi
  fi

  # -- GRUB --:
  if [[ $BOOT = GRUB ]]; then
    # Chequeo de sanidad:
    if [[ ! -x /mnt/sbin/grub-install ]]; then
      dialog \
       --msgbox "Unable to install GRUB.\n\nThe package was NOT installed." 0 0
      continue;
    fi
    dialog --backtitle "Boot loader" --title "GRUB" --menu \
"If you do not have a boot loader, it is recommended to install \
in the Master Boot Record (MBR), can also overwrite your boot loader.\n\n\
Select the destination of the boot loader:" 11 58 0 \
     "MBR"  "Install in the Master Boot Record" \
     "Root" "Install in the Superblock" \
      2> ${TMP}/return-menu-bootloader-grub
     (( $? != 0 )) && continue;

     ANSWER=$(cat ${TMP}/return-menu-bootloader-grub)

     case "$ANSWER" in
       MBR) # GRUB MBR:
         # Comprueba si se trata de un volumen lgico:
         if pvs | grep -q dev ; then
           arr=( $(pvs --ignorelockingfailure --noheadings | awk '{ print $1 }') )
           # Muestra en qu disco instalar:
           if (( ${#arr[*]} > 1 )); then
             i=0
             for p in "${arr[@]}"; do
               p=${p/[0-9]*/}
               x[i++]=$p
               x[i++]=""
             done
             # Remueve posibles elementos duplicados:
             x=( $(printf "%s\n" "${x[@]}" | awk '!s[$0]++') )
             dialog --title "GRUB: MBR" --no-cancel --menu \
"More than one disc/partition has been detected.\n\
Please, choose the destination of GRUB:" 0 0 0 "${x[@]}" \
              2> ${TMP}/select-devices-bootloader
             ROOT_DEV=$(cut -f 1 -d ' ' ${TMP}/select-devices-bootloader)
           else
             ROOT_DEV=${arr[0]}
           fi
         fi
         BOOT_DEV=${ROOT_DEV/[0-9]*/}
         # Trataremos de determinar el nmero de disco para GRUB:
         BOOT_DSC=${BOOT_DEV:7:8}
         list=( a b c d e f g h )
         n=${#list[*]}
         for (( i=0; i<n; i++ )); do
           if [[ ${list[i]} = $BOOT_DSC ]]; then
             BOOT_DSC=$i
             break;
           fi
         done
         [[ -z $BOOT_DSC ]] && BOOT_DSC=0;
         BOOT_NUM=${ROOT_DEV/*[a-z]/}
         MSG="(hd${BOOT_DSC},${BOOT_NUM})"
         dialog --title "BOOT LOADER" --sleep 2 --infobox \
"Installing the boot loader in the Master Boot Record $MSG..." 3 67
         mkdir -p /mnt/boot/grub
         chroot /mnt /sbin/grub-install --force $BOOT_DEV &>${OUTPUT_TTY}
         ;;
       Root) # GRUB Root:
         # Comprueba si se trata de un volumen lgico:
         if pvs | grep -q dev ; then
           arr=( $(pvs --ignorelockingfailure --noheadings | awk '{ print $1 }') )
           # Muestra en qu disco instalar:
           if (( ${#arr[*]} > 1 )); then
             i=0
             for p in "${arr[@]}"; do
               x[i++]=$p
               x[i++]=""
             done
             dialog --title "GRUB: Superblock" --no-cancel --menu \
"More than one disc/partition has been detected.\n\
Please, choose the destination of GRUB:" 0 0 0 "${x[@]}" \
              2> ${TMP}/select-devices-bootloader
             ROOT_DEV=$(cut -f 1 -d ' ' ${TMP}/select-devices-bootloader)
           else
             ROOT_DEV=${arr[0]}
           fi
         fi
         BOOT_DEV=${ROOT_DEV/[0-9]*/}
         # Trataremos de determinar el nmero de disco para GRUB:
         BOOT_DSC=${BOOT_DEV:7:8}
         list=( a b c d e f g h )
         n=${#list[*]}
         for (( i=0; i<n; i++ )); do
           if [[ ${list[i]} = $BOOT_DSC ]]; then
             BOOT_DSC=$i
             break;
           fi
         done
         [[ -z $BOOT_DSC ]] && BOOT_DSC=0;
         BOOT_NUM=${ROOT_DEV/*[a-z]/}
         MSG="(hd${BOOT_DSC},${BOOT_NUM})"
         dialog --title "BOOT LOADER" --sleep 2 --infobox \
"Installing the boot loader in the Root partition $MSG..." 3 63
         mkdir -p /mnt/boot/grub
         chroot /mnt /sbin/grub-install --force $ROOT_DEV &>${OUTPUT_TTY}
         ;;
     esac

     write_grubconfig /mnt/boot/grub/grub.cfg

     # Satisfacemos la estipulacin del estndar FHS:
     ( mkdir -p /mnt/etc/grub
       cd /mnt/etc/grub
       ln -sf /boot/grub/grub.cfg grub.cfg
     )

     # Edicin del archivo de configuracin de GRUB:
     dialog \
      --backtitle "Edit GRUB configuration file" \
      --title "GRUB2 configuration file (grub.cfg)" \
      --ok-label "Save changes" \
      --cancel-label "Continue" \
      --defaultno \
      --editbox /mnt/boot/grub/grub.cfg 0 0 \
       2> ${TMP}/grub.cfg.edited
    if (( $? == 0 )); then
      cat ${TMP}/grub.cfg.edited > /mnt/boot/grub/grub.cfg
    fi
    RETCODE=0
  fi

  if [[ $RETCODE ]]; then
    CODE=$RETCODE
    break;
  fi
done

exit $CODE

