#!/bin/sh
# vim: et sw=2 sts=2 ts=2 tw=0:
#
# Copyright 2013 - 2015 Dimitris Tzemos <djemos@slackel.gr>
# Copyright 2014 Cyrille Pontvieux <jrd@salixos.org>
# 
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

initialize() {
  if [ ! -d "$TMP" ]; then
    mkdir -p "$TMP"
    chmod 700 "$TMP"
  fi
  # T_PX is the root device. Used in the Slackware installer.
  # The variable name is kept the same here, for consistence.
  if [ -n "$!" ] && [ -d "$1" ]; then
    T_PX="$1"
  elif [ -r $TMP/SeTT_PX ]; then
    T_PX=$(cat $TMP/SeTT_PX)
  else
    T_PX=/
  fi
  cd "$T_PX"
  # Determine the root partition (such as /dev/hda2)
  if [ -n "$2" ] && [ -e "$2" ]; then
    DEV="$2"
  elif [ -r $TMP/SeTrootdev ]; then
    DEV=$(cat $TMP/SeTrootdev)
  else
    #DEV=$(df .|sed -rn '$s/^([^ \t]+)[ \t].*/\1/p')
    DEV="`mount | cut -f 1 -d " " | sed -n "1 p"`"
  fi
  [ -n "$DEV" ] || exit 1
  # Set OS name
  # are we on a running system?
  if [ -r etc/slackware-version ]; then
    OS="Salix $(sed -e 's/^Slackware //' etc/slackware-version)"
  else
    OS="Salix"
  fi
  # Title
  BACKTITLE="$OS - GRUB Installer"
}

check_for_efi_partitions() {
	rm -f $TMP/SeTefipartitions
	touch $TMP/SeTefipartitions

	# Scan for EFI partitions:
	for drive in sda sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl sdm sdn sdo sdp ; do
	 if fdisk -l /dev/$drive 2> /dev/null | grep -wq "GPT\|gpt" ; then
	  gdisk -l /dev/$drive 2> /dev/null | grep -w EF00 | while read efisp ; do
      echo /dev/$drive$(expr $(echo "$efisp" | cut -b 1-4)) >> $TMP/SeTefipartitions
     done
    fi
   done

	if [ "$(cat $TMP/SeTefipartitions)" = "" ]; then # No EFI partitions
		rm -f $TMP/SeTefipartitions
		if [ -d /sys/firmware/efi ]; then
		 exit
		fi 
	fi

	# Initially, we will just take the first EFI partition found, which
	# will probably be on /dev/sda:
	PREFERRED_EFI_PARTITION="$(cat $TMP/SeTefipartitions | head -n 1)"

	# But we will also test to see if there is an EFI partition on the same
	# device as the root partition, and if so, prefer that:
	if [ -r $TMP/SeTrootdev ]; then
	  if grep -q "$(cat $TMP/SeTrootdev | cut -b 1-8)" $TMP/SeTefipartitions ; then
		PREFERRED_EFI_PARTITION="$(grep "$(cat $TMP/SeTrootdev | cut -b 1-8)" $TMP/SeTefipartitions | head -n 1)"
	  fi
	fi

	# This file is no longer needed:
	rm -f $TMP/SeTefipartitions

	if [ -d /sys/firmware/efi ]; then #EFI
		# Mount the partition on /mnt/boot/efi or /boot/efi:
		if [ ! -d "$T_PX/boot/efi" ]; then
		  mkdir -p $T_PX/boot/efi
		fi
		mount ${PREFERRED_EFI_PARTITION} $T_PX/boot/efi 1> /dev/null 2> /dev/null


		# If there's no vfat mounted on /boot/efi or /mnt/boot/efi, forget it:
		if ! mount | grep vfat | grep -wq /boot/efi ; then
		  if ! mount | grep vfat | grep -wq /mnt/boot/efi ; then
			if [ "$T_PX" = "/" ]; then
			  echo "ERROR:  No EFI System Partition mounted on /boot/efi."
			fi
			exit
		  fi
		fi
	fi

	if [ -d /sys/firmware/efi ]; then
		# Figure out the device and partition number of the ESP:
		if mount | grep vfat | grep -wq /boot/efi ; then
		  EFI_DEVICE=$(mount | grep vfat | grep -w /boot/efi | cut -b 1-8)
		  EFI_PARTITION=$(mount | grep vfat | grep -w /boot/efi | cut -f 1 -d ' ' | cut -b 9-)
		else
		  EFI_DEVICE=$(mount | grep vfat | grep -w /mnt/boot/efi | cut -b 1-8)
		  EFI_PARTITION=$(mount | grep vfat | grep -w /mnt/boot/efi | cut -f 1 -d ' ' | cut -b 9-)
		fi
	fi

	# There better be a kernel:
	if [ ! -r $T_PX/boot/vmlinuz ]; then
	  if [ "$T_PX" = "/" ]; then
		echo "ERROR:  No kernel found at /boot/vmlinuz."
	  fi
	  exit
	fi
}

ask_append() {
  dialog \
    --title 'OPTIONAL GRUB_CMDLINE_LINUX_DEFAULT="<kernel parameters>" LINE' \
    --inputbox \
"Some systems might require extra parameters to be passed to the kernel. \
If you needed to pass parameters to the kernel when you booted the Slackware \
bootdisk, you'll probably want to enter the same ones here.  Most \
systems won't require any extra parameters.  If you don't need any, just \
hit ENTER to continue.\n\
" 12 72 2> $TMP/reply
  RETVAL=$?
  return $RETVAL
}

append_grub_conf() {
  ask_append;
  GRUB_CMDLINE_LINUX_DEFAULT="quiet $(cat $TMP/reply)"
  UTFVT='vt.default_utf8=1'
  sed -i "
    s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT='$GRUB_CMDLINE_LINUX_DEFAULT'/;
    s/GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX='$UTFVT'/;
    " etc/default/grub
}

install_grub() {
	# Setup Menu
	if [ ! -d /sys/firmware/efi ]; then #csm
		  dialog --backtitle "$BACKTITLE" \
				 --title ' INSTALL GRUB2 ' \
				 --menu "\nWhere do you want to install the boot loader?" 0 0 0 \
			"MBR" "Install in $(echo "$DEV"|sed 's/[0-9]$//') (recommended) " \
			"ROOT" "Install in $DEV (Expert)" \
			"EXIT" "Quit (Do not install GRUB)" \
			2> $TMP/option_menu.txt
		  OPTION="$(cat $TMP/option_menu.txt)"
		  if [ "$OPTION" = "MBR" ]; then
			DEVICE="$(echo "$DEV"|sed 's/[0-9]$//')"
		  elif [ "$OPTION" = "ROOT" ]; then
			DEVICE="$DEV"
		  else
			clear && exit 1
		  fi
		  # Confirm Installation
		  dialog --backtitle "$BACKTITLE" \
				 --title ' CONTINUE? ' \
				 --yesno "\n This will install the GRUB2 bootloader \n in $DEVICE \n " 0 0 || exit 1
		  # install grub2
		  TEXT="Installing bootloader in $DEVICE...\n "
			chroot "$T_PX" grub-install --target=i386-pc --boot-directory=/boot --recheck --force $DEVICE 2>&1 |\
			while read LINE; do
				TEXT="$TEXT \n$LINE"
				dialog --backtitle "$BACKTITLE" --title ' INSTALLING GRUB2 ' --infobox "$TEXT" 0 0
			done
			sleep 3
	fi

	if [ -d /sys/firmware/efi ]; then # EFI
			dialog --backtitle "$BACKTITLE" \
				 --title ' CONTINUE? ' \
				 --yesno "\n This will install the GRUB2 bootloader \n on EFI \n " 0 0 || exit 1
			chroot "$T_PX" grub-install --efi-directory /boot/efi --boot-directory /boot/ --target=x86_64-efi 2>&1 |\
			while read LINE; do
				TEXT="$TEXT \n$LINE"
				dialog --backtitle "$BACKTITLE" --title ' INSTALLING GRUB2 ' --infobox "$TEXT" 0 0
			done
			sleep 3
	fi
  
	# Update boot menu
	TEXT="Updating boot/grub/grub.cfg...\n "
	chroot "$T_PX" update-grub 2>&1 |\
	while read LINE; do
		TEXT="$TEXT \n$LINE"
		dialog --backtitle "$BACKTITLE" --title ' UPDATING GRUB2 ' --infobox "$TEXT" 0 0
	done
	sleep 1
}

# Check for root
[ $(id -u) -eq 0 ] || exit 1
# Create temporary directory
TMP=/var/log/setup/tmp
T_PX='' # passed as first argument by the installer
DEV='' # passed as second argument by the installer
BACKTITLE=''
initialize "$@"
check_for_efi_partitions
cd "$T_PX"
append_grub_conf
install_grub
rm -f $TMP/reply $TMP/option_menu.txt 2>/dev/null || true
