#!/bin/bash
#
################################################################
#
# Simple GUI for livecd-install 
#
# Urs Beyerle
#
################################################################
#
# Needs dialog or Xdialog to run 
# Xdialog: http://xdialog.dyns.net
#
################################################################
#
  VERSION=0.6
#
################################################################

clean_exit()
{
  rm -rf $TMPDIR
}

exit_now()
{
  clean_exit
  exit $1
}

trap "clean_exit" EXIT


### ------------------------------------------------------------
### Definitions
### ------------------------------------------------------------

### supported filesystem types
FILESYSTEM_TYPES="ext3 ext2 xfs"

### set path and lang
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin"
LANG=en_US.UTF-8

### define name of LiveCD install script
LIVECD_INSTALL=livecd-install

### title and script name
TITLE="LiveCD Install GUI version $VERSION"
MENU_TITLE="LiveCD Install GUI version $VERSION"
SCRIPTNAME=$( basename $0 )

### tmpdir
TMPDIR=/tmp/livecd-install-gui.$$
TMP=$TMPDIR/dialog
mkdir -p $TMPDIR
chmod 700 $TMPDIR

### dialog or xdialog?
DIALOG="dialog"
XDIALOG_HIGH_DIALOG_COMPAT=1
export XDIALOG_HIGH_DIALOG_COMPAT
[ -n "$DISPLAY" ] && [ -x /usr/bin/Xdialog ] && DIALOG="Xdialog"

### LiveCD or LiveDVD
LIVE_MEDIA=LiveCD
[ "$(grep DVD /etc/redhat-release 2>/dev/null)" ] && LIVE_MEDIA=LiveDVD
export LIVE_MEDIA=$LIVE_MEDIA



### ------------------------------------------------------------
### Functions
### ------------------------------------------------------------


### -------------------------------------------------------------
about_message() {

    ABOUT_MESSAGE=$( cat <<EOF
---------------------------------------\n
  $SCRIPTNAME\n
  $TITLE\n
---------------------------------------\n
  (c) 2007, Urs Beyerle\n
\n
  Press OK to continue\n
EOF
)
    [ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$ABOUT_MESSAGE" 15 60 8
    [ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$ABOUT_MESSAGE" 15 80

}


### -------------------------------------------------------------
show_comment() {

    COMMENT=$( cat <<EOF
-------------------------------------------------------------------------\n
   $SCRIPTNAME\n
   $TITLE\n
-------------------------------------------------------------------------\n
\n
        Welcome to the Scientific Linux $LIVE_MEDIA installer
\n\n
                              PLEASE NOTE 
\n\n
This is only a simple installer that installs the $LIVE_MEDIA 
to your hard disk. If you would like to do a more advanced 
and sophisticated installation, download the Scientific Linux 
installer CDs or DVDs.
\n\n
Press OK to continue\n
EOF
)
    [ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$COMMENT" 22 60 8
    [ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$COMMENT" 22 80

}


### -------------------------------------------------------------
something_went_wrong() {

    WRONG_MESSAGE=$( cat <<EOF
Sorry, there was an error during livecd-install !
EOF
)

    [ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$WRONG_MESSAGE" 10 60 10
    [ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$WRONG_MESSAGE" 10 80
}


### -------------------------------------------------------------
goodbye() {

    GOODBYE_MESSAGE=$( cat <<EOF
$LIVE_MEDIA was successfully installed on your hard disk !
EOF
)

    [ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$GOODBYE_MESSAGE" 10 60 10
    [ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$GOODBYE_MESSAGE" 10 80
}


### -------------------------------------------------------------
help_message() {

    HELP_MESSAGE=$( cat <<EOF
   --------------------------------------------------------------------\n
     $SCRIPTNAME\n
     $TITLE\n
   --------------------------------------------------------------------\n
\n
This is the graphical user interface of the $LIVECD_INSTALL script.
Use it to install the $LIVE_MEDIA on your hard disk.
\n\n
The $LIVE_MEDIA can be installed on a Linux
partition, which you may have to create first using tools
like qtparted, gparted, fdisk or parted. All data on the selected
Linux partition will be deleted.\n
It is recommended to
create in addition a Swap partition that will be later
used by the installed Linux system.
\n\n
Please backup your data before resizing any partitions.
\n\n
In order that you can boot into the installed Linux
system, it is further recommended that you choose to install
the bootloader GRUB into the Master Boot Record (MBR)
of your primary boot disk.
\n\n
More options are available, if you run the script 
$LIVECD_INSTALL directly from the command line.
\n\n
See also http://www.livecd.ethz.ch/install.html
\n
EOF
)

    [ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$HELP_MESSAGE" 35 85 12
    [ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$HELP_MESSAGE" 35 85
}



### ------------------------------------------------------------
test_for_livecd_install_script() {

    LIVECD_INSTALL_SCRIPT=$( which $LIVECD_INSTALL 2>/dev/null )
    if [ ! "$LIVECD_INSTALL_SCRIPT" ]; then
	MESSAGE0="Script $LIVECD_INSTALL not found"
	$DIALOG --title "$TITLE" --msgbox "$MESSAGE0" 0 0
	exit_now 1
    fi
}

### ------------------------------------------------------------
test_for_root() {

    if [ "$UID" -ne "0" ]; then
	MESSAGE0="To use this program, you need to be root"
	$DIALOG --title "$TITLE" --msgbox "$MESSAGE0" 0 0
	exit_now 1
    fi
}


### ------------------------------------------------------------
select_fstype() {

    FS_TYPE=""
    MESSAGE1="Please select a file system type for your Linux partition"

    FS_TYPE_LIST=""
    for type in $FILESYSTEM_TYPES; do
	which mkfs.$type >/dev/null 2>&1
	if [ "$?" = "0" ]; then
	    FS_TYPE_LIST="$FS_TYPE_LIST $type"
	    [ $type = "ext3" ] && FS_TYPE_LIST="$FS_TYPE_LIST (recommended) on"
	    [ $type = "ext2" ] && FS_TYPE_LIST="$FS_TYPE_LIST (optional) off"
	    [ $type = "xfs" ]  && FS_TYPE_LIST="$FS_TYPE_LIST (experimental) off"
	fi
    done
    
    $DIALOG --title "$TITLE" --no-cancel --radiolist "$MESSAGE1" 20 60 8 $FS_TYPE_LIST 2>$TMP
    FS_TYPE=$( cat $TMP )
    FS_TYPE_OPT="-fstype $FS_TYPE"

    ### Display a (warn) message if choosing xfs and kernel does not have xfs included

    rpm -ql kernel 2>/dev/null | grep -q \/xfs.ko
    if [ "$?" != "0" ]; then
	if [ $FS_TYPE = "xfs" ]; then
	    XFS_MESSAGE="IMPORTANT NOTE:.\n\n\
Formating the root file system with xfs can causes problems after a regular kernel update.\n
Please run the following command after each kernel update in order to correctly build the initial ram disk:\n\n
# new-kernel-pkg --package kernel --mkinitrd --depmod --install 2.6.18-128.1.14.el5\n\n
(replace 2.6.18-128.1.14.el5 with the version number of the updated kernel)"

            [ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$XFS_MESSAGE" 20 80 12
            [ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$XFS_MESSAGE" 20 100
	fi
    fi
}


### ------------------------------------------------------------
select_install_part() {

    INSTALL_PART=""
    PART_LIST=""
    PARTS=$( LANG=C fdisk -l | grep Linux$ | cut -d" " -f1 )
    if [ ! "$PARTS" ]; then
	NOPART_MESSAGE="No Linux partition found.\n\n\
Please create one first" 
	[ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$NOPART_MESSAGE" 20 80 8
	[ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$NOPART_MESSAGE" 20 100
	exit_now 1
    fi
    for p in $PARTS; do
	PART_LIST="$PART_LIST $p Linux-Partiton off"
    done
    MESSAGE1="Please select a partition to install the $LIVE_MEDIA"
    $DIALOG --title "$TITLE" --no-cancel --radiolist "$MESSAGE1" 20 60 8 $PART_LIST 2>$TMP
    INSTALL_PART=$( cat $TMP )
}


### ------------------------------------------------------------
select_swap_part() {

    SWAP_PART=""
    PART_LIST=""
    PARTS=$( LANG=C fdisk -l | grep "Linux swap" | cut -d" " -f1 )
    if [ ! "$PARTS" ]; then
	NOSWAP_MESSAGE="No Swap partition found.\n\n\
You can install the $LIVE_MEDIA without having\n\
a Swap partition, but it is not recommended.\n\n\
Continue ?" 
	$DIALOG --title "$TITLE" --yesno "$NOSWAP_MESSAGE" 15 60 8
	return $?
    fi

    for p in $PARTS; do
	PART_LIST="$PART_LIST $p Swap-Partiton off"
    done
    MESSAGE2="Please select a SWAP partition"
    $DIALOG --title "$TITLE" --no-cancel --radiolist "$MESSAGE2" 15 60 5 $PART_LIST \
    NONE "Do not use a swap partition (not recommended)" off 2>$TMP
    SWAP_PART=$( cat $TMP )
    [ "$SWAP_PART" = "NONE" ] && SWAP_PART=""
    return 0
}


### ------------------------------------------------------------
ask_root_password() {

    PASSWORD=""
    PWD_MESSAGE1="Please enter a new root password or press return \
to keep the current root password. \
(Please note, an empty root password is NOT recommended !)"
    PWD_MESSAGE2="Retype new password:"

    while [ ! $PASSWORD ]; do
	$DIALOG --title "$TITLE"  --insecure  --no-cancel --passwordbox "$PWD_MESSAGE1" 15 60 2>$TMP
	PASSWORD1=$( cat $TMP )
	rm -f $TMP
	[ ! $PASSWORD1 ] && break
	$DIALOG --title "$TITLE"  --insecure  --no-cancel --passwordbox "$PWD_MESSAGE2" 15 60 2>$TMP
	PASSWORD2=$( cat $TMP )
	rm -f $TMP
	if [ "$PASSWORD1" = "$PASSWORD2" ]; then
	    PASSWORD=$PASSWORD1
	    echo $PASSWORD | passwd --stdin root >/dev/null
	fi
    done
    return 0
}


### ------------------------------------------------------------
ok_continue() {

    OK_MESSAGE="\n$LIVE_MEDIA will be installed on $INSTALL_PART.\n\
All data on $INSTALL_PART will be deleted !!\n\n"
    if [ $SWAP_PART ]; then
	OK_MESSAGE="${OK_MESSAGE}$SWAP_PART will be used as Swap partition.\n\n"
    fi
    if [ $MBR_DISK ]; then
	OK_MESSAGE="${OK_MESSAGE}GRUB will be installed as bootloader into the\n\
Master Boot Record (MBR) of disk $MBR_DISK.\n\n"
    fi
    OK_MESSAGE="${OK_MESSAGE}Is this ok ?\n"

    if [ $DIALOG = "Xdialog" ]; then 
	$DIALOG --title "$TITLE" --default-no --yesno "$OK_MESSAGE" 15 60 8 && return 0
    fi
    if [ $DIALOG = "dialog" ]; then
	$DIALOG --title "$TITLE" --yesno "$OK_MESSAGE" 15 60 && return 0
    fi
    return 1
}


### ------------------------------------------------------------
select_mbr_disk() {

    MBR_DISK=""
    DISK_LIST=""
    DISKS=$( LANG=C fdisk -l | grep ^Disk | cut -d":" -f1 | cut -d" " -f2 )
    for p in $DISKS; do
	DISK_LIST="$DISK_LIST $p Disk off"
    done
    MESSAGE3="Please select a disk to install the bootloader GRUB"
    $DIALOG --title "$TITLE" --no-cancel --radiolist "$MESSAGE3" 15 60 5 $DISK_LIST \
    NONE "Do not install GRUB (not recommended)" off 2>$TMP
    MBR_DISK=$( cat $TMP )
    return 0
}


### ------------------------------------------------------------
run_qtparted() {

    QTPARTED=$( which qtparted 2>/dev/null )
    if [ ! $QTPARTED ]; then
	NO_QTPARTED_MESSAGE="Sorry, qtparted not found.\n\n\
Please use an other tool like gparted, fdisk, parted."
	[ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$NO_QTPARTED_MESSAGE" 10 60 8
	[ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$NO_QTPARTED_MESSAGE" 10 80
    else
	$QTPARTED >/dev/null 2>&1 &
    fi
}


### ------------------------------------------------------------
run_gparted() {

    GPARTED=$( which gparted 2>/dev/null )
    if [ ! $GPARTED ]; then
	NO_GPARTED_MESSAGE="Sorry, gparted not found.\n\n\
Please use an other tool like fdisk, parted or qtparted."
	[ $DIALOG = "Xdialog" ] && $DIALOG --title "$TITLE" --infobox "$NO_GPARTED_MESSAGE" 10 60 8
	[ $DIALOG = "dialog" ]  && $DIALOG --title "$TITLE" --msgbox  "$NO_GPARTED_MESSAGE" 10 80
    else
	$GPARTED >/dev/null 2>&1 &
    fi
}


### ------------------------------------------------------------
start_message() {

    START_INSTALL_MESSAGE="The $LIVECD_INSTALL script will be now started in a separate window (maybe with a short delay).\n\n
Depending on your hardware and the size of the $LIVE_MEDIA the installation will take between 10-40 minutes.\n\n
Press OK to continue\n"

     if [ $DIALOG = "Xdialog" ]; then 
	 $DIALOG --title "$TITLE" --infobox "$START_INSTALL_MESSAGE" 13 60 8 && return 0
     fi
     if [ $DIALOG = "dialog" ]; then 
	 $DIALOG --title "$TITLE" --msgbox  "$START_INSTALL_MESSAGE" 13 80   && return 0
     fi
     retrun 1
}


### ------------------------------------------------------------
show_fdisk() {

    fdisk -l > /$TMPDIR/fdisk_l
    height=$(( $( cat /$TMPDIR/fdisk_l | wc -l ) + 8 ))
    [ $DIALOG = "Xdialog" ] && LANG=C $DIALOG --title "${TITLE}: fdisk -l" --no-cancel --logbox /$TMPDIR/fdisk_l $height 80
    [ $DIALOG = "dialog" ]  && LANG=C $DIALOG --title "${TITLE}: fdisk -l" --textbox /$TMPDIR/fdisk_l $height 80
}


### ------------------------------------------------------------
run_livecd_install() {

    LIVECD_INSTALL_OPTIONS="-y $FS_TYPE_OPT $NOGRUB $SWAP_PART_OPT $MBR_DISK_OPT $INSTALL_PART"

    rm -f $TMPDIR/command
    cat > $TMPDIR/command <<EOF
#!/bin/bash
echo
echo "Run: $LIVECD_INSTALL $LIVECD_INSTALL_OPTIONS"
$LIVECD_INSTALL $LIVECD_INSTALL_OPTIONS 
if [ "\$?" = "0" ]; then
    echo success > $TMPDIR/livecd_install_finished
else
    echo failed > $TMPDIR/livecd_install_finished
fi
echo
echo -n "- Press [ENTER] close this window - "
read -s
EOF
    chmod 755 $TMPDIR/command

    start_message || return 1

    C_TITLE="$LIVECD_INSTALL $LIVECD_INSTALL_OPTIONS"

    if [ "$( which konsole 2>/dev/null )" ]; then
	konsole --schema BlackOnLightYellow.schema -T "$C_TITLE" \
                --vt_sz 120x35 -e $TMPDIR/command >/dev/null 2>&1
    elif [ "$( which gnome-terminal 2>/dev/null )" ]; then
	gnome-terminal -t "$C_TITLE" \
                --geometry 120x35 -e $TMPDIR/command >/dev/null 2>&1
    elif [ "$( which xterm 2>/dev/null )" ]; then    
	xterm -sb -title "$C_TITLE" -geometry 120x40+20+20 -e $TMPDIR/command
    fi
}


### ------------------------------------------------------------
install_livecd() {

    # clean variables
    INSTALL_PART=""
    SWAP_PART_OPT=""
    MBR_DISK_OPT=""

    select_install_part
    select_fstype
    if [ "$INSTALL_PART" != "" ]; then
	select_swap_part
	if [ "$?" = "0" ]; then
	    select_mbr_disk
	    [ "$MBR_DISK" = "NONE" ] && NOGRUB="-nogrub" && MBR_DISK=""
	    ask_root_password
	    ok_continue && break 
	fi
    fi
    INSTALL_PART=""
}


### ------------------------------------------------------------
main_menu() {

    MENU_1="Install the $LIVE_MEDIA"
    MENU_2="Run gparted  (create/resize partitions)"
    MENU_3="Run qtparted (only for resizing NTFS partitions)"
    MENU_4="Show partition table(s) of installed disk(s)"
    MENU_5="Help"
    MENU_6="About"
    MENU_7="Quit"
    
    while true; do
	
	$DIALOG --title "$TITLE" \
	    --menu "$MENU_TITLE" 15 60 7\
	    1 "$MENU_1" \
	    2 "$MENU_2" \
	    3 "$MENU_3" \
	    4 "$MENU_4" \
	    5 "$MENU_5" \
	    6 "$MENU_6" \
	    7 "$MENU_7" \
	    2> $TMP

	if [ "$?" != "0" ]; then
	    # cancel pressed
	    echo canceled >  $TMPDIR/livecd_install_finished
	    break
	fi

	CHOICE=$(cat $TMP)

	case "$CHOICE" in
         1)
	   install_livecd ;;	
	 2)
           run_gparted ;;
	 3)
           run_qtparted ;;
         4)
           show_fdisk ;;
         5)
           help_message ;;
         6)
           about_message ;;
         7)
           exit_now ;;
        esac
done

}


### ------------------------------------------------------------
### Main Program
### ------------------------------------------------------------

### requirements
test_for_livecd_install_script
test_for_root

### show comment on installer
show_comment

while true; do

    ### main menu
    main_menu
    [ "$SWAP_PART" ] && export SWAP_PART_OPT="-swap=$SWAP_PART"
    [ "$MBR_DISK" ]  && export MBR_DISK_OPT="-mbr=$MBR_DISK"
    export INSTALL_PART=$INSTALL_PART
    export LIVECD_INSTALL=$LIVECD_INSTALL

    ### run $LIVECD_INSTALL
    if [ $INSTALL_PART ]; then
	rm -f $TMPDIR/livecd_install_finished
	run_livecd_install
	while [ ! -e $TMPDIR/livecd_install_finished ]; do sleep 1; done
	[ $( cat $TMPDIR/livecd_install_finished ) = "success" ] && break
    fi
    [ $( cat $TMPDIR/livecd_install_finished ) = "canceled" ] && break
    something_went_wrong
    INSTALL_PART=""
done

[ ! $( cat $TMPDIR/livecd_install_finished ) = "canceled" ] && goodbye

exit_now 0