#! /bin/bash

#: Title       : installLegacyGrub
#: Date Created: Sun Oct 14 13:27:19 PDT 2012 
#: Last Edit   : Mon Oct 15 15:45:54 PDT 2012
#: Author      : Agnelo de la Crotche (please_try_again)
#: Version     : 1.0 (alpha)
#: Description : installs Legacy Grub parallel to Grub2
#: Requires    : os-prober, dialog
#: Usage       : installLegacyGrub [partition]

grubdir=/boot/grub
grubmenu=$grubdir/menu.lst
logfile=/var/log/$(basename $0).log

# Grub version
declare GV5272 GVaa75 GV7c3c GV020
GV5272="Legacy Grub"
GVaa75="Legacy Grub"
GV7c3c="Grub2"
GV020="Grub2"

# check if we are root
[ $UID -eq 0 ] || exec echo "You have to run this script as root or sudo."

# we need udevadm and updateLegacyGrub
required="grub udevadm updateLegacyGrub"
for util in $required ; do
	which $util &>/dev/null || exec printf "%s not found.\n" $util
done

# check for grubprobe
grubprobe=$(which grub-probe 2>/dev/null)
[ "$grubprobe" ] || grubprobe=$(which grub2-probe 2>/dev/null)
[ "$grubprobe" ] || exec printf "grub(2)-probe not found.\n"


# Look for Grub stage1 & stage 2
for stage in stage1 stage2 ; do
	[ -f ${grubdir}/$stage ] || exec echo "${grubdir}/$stage not found."
done

[ "$1" ] && part=$1 || read  -p "Please specify a partition: " part
part=$(basename $part)
dev=/dev/$part

# Abort if block device doesn't exist
[ -b $dev ] || exec printf "Partition %s is not a block device.\n" $dev

# Abort if device.map not found
devicemap=/boot/grub2/device.map
[ -f $devicemap ] || devicemap=${grubdir}/device.map
[ -f $devicemap ] || exec printf "Device map not found\n"


function biosdrv  {
DEV=${1:0:8}
nr=${1:8}
[ "$nr" ] && nr=",$(($nr *1 -1))"
# look for device in device.map
eval $(udevadm info --query=property --name=$DEV | awk -F "=" '/DEVLINKS/ { print $1"=\""$2"\""}')
for d in ${DEVLINKS} ; do
	if ( grep -q "$d" $devicemap ); then
		hd="($(grep "$d" $devicemap | sed 's|(\(.*\)).*|\1|')${nr})"
		break
	fi
done
echo $hd
}

declare -l yesno
sgr=$(tput sgr0)

# Warning if boot sector contains Grub2
if ( dd if=$dev bs=512 count=1 2>/dev/null | strings | grep -q -i grub) ; then
	read -p "The boot sector of this partition already contains Grub. Do you want to continue? (If so, type 'YES'):" yesno  
	[ "x$yesno" == "xyes" ] || exec printf "Script cancelled by user.\n" 
	Grubver="GV$(hexdump -v -s 128 -n 2 -e '/1 "%x"' $dev)"
	[ "${!Grubver}" == "Grub2" ] && read -p "Grub2 was found is this partition's boot sector.  Do you really want to continue? (If so, type 'YES'):" yesno  
	[ "x$yesno" == "xyes" ] || exec printf "Script cancelled by user.\n" 
fi

printf "\n\033[31;1mAllright, you know what you are doing.%s\n" $sgr

if [ "$devicemap" != "${grubdir}/device.map" ]; then
	cp $devicemap ${grubdir} && devicemap=${grubdir}/device.map
fi
	
install_part=$(biosdrv $dev)
[ "$install_part" ] || exec printf "%s does not have any corresponding BIOS drive.\n" $dev
 
# look for stage1
grub --batch --no-floppy <<EOF >$logfile
find /boot/grub/stage1
EOF
stage1=($(grep "(hd*" $logfile))

[ ${#stage1[*]} -eq 0 ] && exec printf "No device with stage1 found.\n"

# find out if we are using a separate /boot

bootmnt=$($grubprobe --target=device /boot)
rootmnt=$($grubprobe --target=device /)
if [ "${bootmnt}" == "${rootmnt}" ]; then
	bootdev=$rootmnt
	bootdir="/boot/"
else
	bootdev=$bootmnt
	rootdir="--root-directory=/boot"
	bootdir="/"
fi

# Abort if block device doesn't exist
[ -b $bootdev ] || exec printf "Partition %s is not a block device.\n" $bootdev

stage1dev=$(biosdrv $bootdev)

for s in  ${stage1[*]}; do
	[ "$s" == "$stage1dev" ] && rootdev="$s"
done

[ "$rootdev" ] || exec printf "No stage1 found in %s. \n" %s

printf "Please wait while Writing Grub menu...\n"

updateLegacyGrub -n || exit 1

printf "Installing grub...\n"

grub --batch --no-floppy --device-map=$devicemap <<EOF >>$logfile
root $rootdev
setup --force-lba --stage2=${bootdir}grub/stage2 --prefix=${bootdir}grub ${install_part}
quit
EOF
