# openmamba boot loader recovery script
# Copyright (c) 2007-2011 by Silvan Calarco <silvan.calarco@mambasoft.it>
#
# Released under the terms of the GNU GPLv3 License

VERSION=0.7
TEXTDOMAIN=bootrecover
TEXTDOMAINDIR=/opt/kde3/share/locale/
INSTALL_DATE=`date +%Y%m%d-%H%M`
LOG_FILE=/var/log/bootrecover-$INSTALL_DATE.log
MOUNTPOINT=/mnt/install
KERNEL_RELEASE=`uname -r`

function abort() {
   [ "$DCOPID" ] && {
      dcop $DCOPID KommanderIf setText progressText $"Installation aborted; press Next to see the error log."
      dcop $DCOPID KommanderIf setText finallabel $"Installation aborted :-("
      dcop $DCOPID KommanderIf setEnabled next true
   }
   exit 1
}

function finished() {
   [ "$DCOPID" ] && {
      dcop $DCOPID KommanderIf setText progressText $"Installation completed; press Next to continue."
      dcop $DCOPID KommanderIf setText progressBar 100
      dcop $DCOPID KommanderIf setText installTopLabel $"Installation completed."
      dcop $DCOPID KommanderIf setText installInfoLabel ""
      dcop $DCOPID KommanderIf setEnabled next true
      dcop $DCOPID KommanderIf setEnabled ProgressGroupBox true
   }
   exit 1
}

function dcop_write() {
   [ "$DCOPID" ] && {
      dcop $DCOPID KommanderIf setText progressText "$1"
      dcop $DCOPID KommanderIf setText progressBar $2
   }
}

function apt_parser() {
   while read line; do
      [ "$DCOPID" ] && {
         echo $line
         dcop $DCOPID KommanderIf setText progressText2 "$line"
      }
   done
}

cp_parser_count=0
date_start=`date +%s`

function cp_parser() {
   while read line; do
      let cp_parser_count+=1
      if [ $cp_parser_count -ge 100 ]; then
         [ "$DCOPID" ] && {
            CP_LINE=`echo ${line/*$MOUNTPOINT/}`
	    MOUNT_SPACE=`du -sh $MOUNTPOINT`
	    MOUNT_SPACE=${MOUNT_SPACE/$MOUNTPOINT/}
	    let TIME_ELAPSED=\(`date +%s`-$date_start\)/60
	    
            dcop $DCOPID KommanderIf setText progressText2 $"\
Copying: '$CP_LINE
${MOUNT_SPACE}bytes copied
Installation time: $TIME_ELAPSED minutes"
         }
	 cp_parser_count=0
      fi
   done
}

export PATH=$PATH:/sbin:/usr/sbin:/opt/kde3/bin

INPUT_FILE=$1
[ "$2" -a "$3" ] && DCOPID="--user $3 $2"

echo $"\
openmamba boot loader recovery script - version $VERSION
Copyright (c) 2007-2011 by Silvan Calarco <silvan.calarco@mambasoft.it>
"

dcop_write $"Starting installation..." 5

[ $INPUT_FILE ] || {
   echo $"Error: this script must be called by bootloader.kmdr; aborting." >&2
   abort
}

[ -r $INPUT_FILE ] || {
   echo $"Error: cannot read input file $INPUT_FILE; aborting." >&2
   abort
}

. $INPUT_FILE

[ $INSTALL_DEVICE ] || {
   echo $"Error: installation device is not defined in $INPUT_FILE; aborting." >&2
   abort
}

INSTALL_DISK_DEVICE=${INSTALL_DEVICE:0:8}
MOUNTPOINT=$INSTALL_MOUNTPOINT

[ -d $MOUNTPOINT ] || {
   echo $"Error: mount point $MOUNTPOINT does not exist or is not a directory; aborting." >&2
   abort
}

[ -e $MOUNTPOINT/etc/openmamba-release ] || {
   echo $"Error: file $MOUNTPOINT/etc/openmamba-release does not exist; aborting." >&2
   abort
}

[ -e $MOUNTPOINT/usr/sbin/grub-install ] || {
   echo $"Error: file $MOUNTPOINT/usr/sbin/grub-install missing; aborting." >&2
   abort
}

dcop_write $"Binding system dirs to new mountpoint..." 73
mount -o bind /dev $MOUNTPOINT/dev || {
   echo $"Error: could not mount $MOUNTPOINT/dev; aborting." >&2
   abort
}

mount -o bind /sys $MOUNTPOINT/sys || {
   echo $"Error: could not mount $MOUNTPOINT/sys; aborting." >&2
   abort
}

mount -o bind /proc $MOUNTPOINT/proc || {
   echo $"Error: could not mount $MOUNTPOINT/proc; aborting." >&2
   abort
}


if [ "$INSTALL_BOOTLOADER_DEVICE" -o "$INSTALL_BOOTLOADER_DEVICE_EFI" ]; then

   for k in $MOUNTPOINT/boot/vmlinuz-*; do 
      KVER=${k/*\/boot\/vmlinuz-}
      dcop_write $"Recreating initramfs for $KVER kernel..." 82
      echo $"Recreating initramfs for $KVER kernel" | tee -a $LOG_FILE
      chroot $MOUNTPOINT mkinitrd -f /boot/initramfs-${KVER}.img ${KVER}
   done

   if [ "$INSTALL_BOOTLOADER_DEVICE_EFI" ]; then
      # EFI
      dcop_write $"Installing bootloader on ""$INSTALL_BOOTLOADER_DEVICE_EFI (EFI)..." 90
      echo $"Installing grub bootloader on ""$INSTALL_BOOTLOADER_DEVICE_EFI (EFI)" | tee -a $LOG_FILE
      [ -e $MOUNTPOINT/boot/efi ] || mkdir -p $MOUNTPOINT/boot/efi
      mount $INSTALL_BOOTLOADER_DEVICE_EFI $MOUNTPOINT/boot/efi
      grub-install --root-directory=$MOUNTPOINT --efi-directory=$MOUNTPOINT/boot/efi --target=x86_64-efi \
         --bootloader-id="openmamba Boot Manager" --recheck --no-floppy
      umount $MOUNTPOINT/boot/efi

      INSTALL_BOOTLOADER_DEVICE_EFI_BYID=$INSTALL_BOOTLOADER_DEVICE_EFI
      for f in `ls /dev/disk/by-id/*`; do 
         if [ "$INSTALL_BOOTLOADER_DEVICE_EFI" = "`readlink -f $f`" ]; then
            INSTALL_BOOTLOADER_DEVICE_EFI_BYID=$f
            break
         fi
      done
      sed -i "/^GRUB_INSTALL_DEVICE.*/d" $MOUNTPOINT/etc/sysconfig/grub
      cat >> $MOUNTPOINT/etc/sysconfig/grub << _EOF
GRUB_INSTALL_DEVICE_EFI=$INSTALL_BOOTLOADER_DEVICE_EFI_BYID
_EOF

   else
      # BIOS
      dcop_write $"Installing bootloader on $INSTALL_BOOTLOADER_DEVICE..." 90
      echo $"Installing grub bootloader on $INSTALL_BOOTLOADER_DEVICE" | tee -a $LOG_FILE
      grub-install $INSTALL_BOOTLOADER_DEVICE --root-directory=$MOUNTPOINT --target=i386-pc --recheck --no-floppy

      INSTALL_BOOTLOADER_DEVICE_BYID=$INSTALL_BOOTLOADER_DEVICE
      for f in `ls /dev/disk/by-id/*`; do 
         if [ "$INSTALL_BOOTLOADER_DEVICE" = "`readlink -f $f`" ]; then
            INSTALL_BOOTLOADER_DEVICE_BYID=$f
            break
         fi
      done
      sed -i "/^GRUB_INSTALL_DEVICE.*/d" $MOUNTPOINT/etc/sysconfig/grub
      cat >> $MOUNTPOINT/etc/sysconfig/grub << _EOF
GRUB_INSTALL_DEVICE=$INSTALL_BOOTLOADER_DEVICE_EFI_BYID
_EOF

      [ "$INSTALL_BOOTLOADER_DEVICE_SETBOOTABLE" = "1" -a \
        "${INSTALL_BOOTLOADER_DEVICE:8:2}" ] && {
         parted ${INSTALL_BOOTLOADER_DEVICE:0:8} \
                set ${INSTALL_BOOTLOADER_DEVICE:8:2} boot on || \
            echo $"Warning: there was an error setting bootloader partition as bootable." >&2
      }
   fi

   [ "$INSTALL_BOOTLOADER_CHAINLOAD" ] && {
      # configure boot chainloader for e.g. windows
      GRUB_OTHER_TITLES=()
      for i in ${INSTALL_BOOTLOADER_CHAINLOAD[*]}; do
         # FIXME: missing conversion from device to grub (hdx,y) form
	 unset ID_FS_UUID
	 eval `blkid $i -o udev`
         if [ "$ID_FS_UUID" ]; then
	    if [ "$ID_FS_TYPE" = "ntfs" ]; then
	       [ "$ID_FS_LABEL" ] &&
	          ID_FS_LABEL="Windows ($ID_FS_LABEL)" || ID_FS_LABEL="Windows"
	    elif [ "${ID_FS_TYPE:0:3}" = "fat" ]; then
	       [ "$ID_FS_LABEL" ] &&
	          ID_FS_LABEL="Win/DOS ($ID_FS_LABEL)" || ID_FS_LABEL="Windows/DOS"
	    else
	       [ "$ID_FS_LABEL" ] &&
	          ID_FS_LABEL="Other OS ($ID_FS_LABEL)" || ID_FS_LABEL="Other OS"	    
	    fi
	    [ "$ID_FS_LABEL" ] || ID_FS_LABEL="W"
	    GRUB_OTHER_DEVICES=(${GRUB_OTHER_DEVICES[*]} /dev/disk/by-uuid/$ID_FS_UUID)
	    GRUB_OTHER_TITLES=(${GRUB_OTHER_TITLES[*]} "\"$ID_FS_LABEL\"")
	 else
	    GRUB_OTHER_DEV=$i
            for o in `seq 1 ${#DEV_NAME_ORIG[*]}`; do
               [ "${DEV_NAME_ORIG[o-1]}" = "${i:5:3}" ] && {
	           GRUB_OTHER_DEV=${DEV_NAME_DEST[o-1]}${i:8:2}
	   	   break
               }
	    done
	    GRUB_OTHER_DEVICES=(${GRUB_OTHER_DEVICES[*]} $GRUB_OTHER_DEV)
	    GRUB_OTHER_TITLES=(${GRUB_OTHER_TITLES[*]} "\"Windows on $GRUB_OTHER_DEV\"")
	 fi
      done
      sed -i "/^GRUB_OTHER_.*/d" $MOUNTPOINT/etc/sysconfig/grub
      cat >> $MOUNTPOINT/etc/sysconfig/grub << _EOF
GRUB_OTHER_DEVICES=(${GRUB_OTHER_DEVICES[*]})
GRUB_OTHER_TITLES=(${GRUB_OTHER_TITLES[*]})
_EOF
   }

   chroot $MOUNTPOINT update-grub | tee -a $LOGFILE
else
   echo $"Info: skipping bootloader installation" | tee -a $LOG_FILE
fi

## MBR backup
#echo "Installing MBR record on $INSTALL_DISK_DEVICE" | tee -a $LOG_FILE
#dd if=$INSTALL_DISK_DEVICE of=$MOUNTPOINT/boot/mbr-backup bs=1 count=512
#install-mbr $INSTALL_DISK_DEVICE

umount $MOUNTPOINT/dev
umount $MOUNTPOINT/sys
umount $MOUNTPOINT/proc
sync
finished

echo $"Installation done. You can now reboot to start the freshly installed system." | tee -a $LOG_FILE

exit 0
