#!/usr/bin/env bash
version="20261002"

# Copyright: 2012, 2013 snapshot2usb David Hare
# Copyright: 2013> refracta2usb fsmithred <fsmithred@gmail.com>, David Hare <dzz@???>
# License: GPL-3   (See "/usr/share/common-licenses/GPL-3".)
# This is free software with NO WARRANTY. Use at your own risk!

# SYNOPSIS
#
# First select the device to work on. Then choose a task.
#
# Create Live-USB:
#	check_device()
#	mount it
#	add_live_system()
#		select source(), select_kernel(), select_initrd()
#		copy files:  run copy_iso_files() or setup_findiso()
#		create syslinux directory if one does not exist
#			copy menu and help files from template folder
#			install_syslinux()  
#			Note: Keep copy template separate from install_syslinux so that menu files won't change when reinstalling bootloader.
#	edit_boot_menu
#
#
#
# TODO
#	
#	check memtest entry
#	add utility to zero beginning of device
#

#test only:
#set -x

TITLE="refracta2usb"
_ICON="$(find /usr/share/icons/Adwaita*/24x24 -name applications-utilities.png)"

#old rsync opts:
#rsyncopts="-av --progress"
# new rsync opts better suited for vfat:
rsyncopts="-hvrltD --modify-window=1 --progress"

# What if logged in user is not 1000?
username=$(awk -F: '/1000:1000/ { print $1 }' /etc/passwd)
#username=$(finger|grep -v Login |grep -v root|awk '{print $1}'|uniq)
#username=$(users)

configfile="/etc/refracta2usb.conf"
source "$configfile"

if [ ! -d /home/${username}/.refracta2usb ] ; then
	mkdir -p /home/${username}/.refracta2usb
	# make it user owned:
	chown ${username}:${username} /home/${username}/.refracta2usb
fi

# move to /var/log. We run as root now.
# error_log="/home/${username}/.refracta2usb/refracta2usb.log"
error_log="/var/log/refracta2usb.log"

if [ -f "$error_log" ]; then 
	truncate -s 0 $error_log
else
	touch "$error_log"
fi

exec 2>"$error_log"

# Suppress dbind-WARNING message "noise" when opening yad windows:
export NO_AT_BRIDGE=1

r2u_library="/usr/lib/refracta2usb"
for file in ${r2u_library}/functions/* ; do
	if [ -f "$file" ] ; then
		source "$file"
	fi
done

helpfile="${r2u_library}/help_r2u.txt"

yad_zenity_compat

start_menu="run_task"	# -t option changes this to start with tools menu


show_help () {
	printf "$help_text"
	exit 0
}

help_text=$"
	Usage:  $0  [option]
	
	valid options:
		-h, --help		show this help text
		-v, --version	display the version information
		-d. --debug		debug mode
		-t, --tools		go directly to tools menu after selecting device
		
"

while [[ $1 == -* ]]; do
	case "$1" in
	
		-h|--help)
			show_help ;;
		
		-v|--version)
			printf "\n$version\n\n" 
			exit 0 ;;
			
		-d|--debug)
			DEBUG="yes"
			debug="--debug"
			shift ;;
			
		-t|--tools)
			start_menu="advanced_tasks"
			shift ;;

		*) 
			printf "\t invalid option: $1 \n\n"
			printf "\t Try:  $0 -h for full help. \n\n"
			exit 1 ;;
    esac
done


if [[ "$DEBUG" = "yes" ]] ; then
	echo "Debug mode was set..."
	set -x
fi


if ! [ -t 0 ]; then	# this script must be called from a terminal 
echo " Not a terminal"
yad --window-icon="$_ICON" --title="$TITLE" --width=400 --height=100 --center $ERROR --text=$"\n Please run $TITLE from a terminal" --button="OK":0
exit 1
fi


# Check that xserver is running and user is root.
[[ $DISPLAY ]] || { echo -e $"This program needs to run from within an xsession.. \nExiting..." ; exit 1 ; }
if [[ $(id -u) -ne 0 ]] ; then
	yad --window-icon="$_ICON" --title="${TITLE}..Error" --width=400 --height=100 --center $ERROR  --text=$"
	You need to be root!
"
	exit 1
fi

# Set path for root to include sbins.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Set path for root to include /opt/trinity/bin (/kwrite, /konqueror), if exists
if [ -d "/opt/trinity/bin" ]; then
	export PATH=$PATH:/opt/trinity/bin
fi

### Should this be moved to functions file?
trap cleanup EXIT HUP INT QUIT TERM

##########
# Clear tempfile from previous run
#if [[ -f /tmp/r2u_device ]] ; then
#	rm /tmp/r2u_device
#fi

# Check if we're running a live session.  See patch-init and select-loop.
if [[ -d /lib/live/mount/medium || -d /lib/live/mount/persistence || -d /lib/live/mount/findiso ]] ; then
	live_session="yes"
fi

# new way (excalibur>)
if [[ -d /run/live/medium || -d /run/live/persistence || -d /run/live/findiso ]] ; then
	live_session="yes"
fi

# set to mount device (fat32) user writable
# then we don't need root editor/file-manager
mountopts="-t vfat -o rw,noatime,umask=000"


select_device_gui () {

usbdevlist=$(/usr/sbin/hwinfo --usb --short|grep "/dev/sd"|awk '{print $1}')
usbdevfulllist=$(/usr/sbin/hwinfo --usb --short|grep "/dev/sd"|awk '{print $0}')

if [[ -z "$usbdevfulllist" ]] ; then
	no_device_message=$"\n   ###  WARNING: No usb device was detected. Plug it in and Rescan.  ###  "
	run_task
fi

echo -e "\n\tLIST OF USB DEVICES\n\n$usbdevfulllist\n"
device=$(yad --window-icon="$_ICON" --title="$TITLE" --width=400 --height=200 --center --list --separator="" --column="" --text=$"\nDetected USB devices:\n\n$usbdevfulllist\n\nSelect the target device you want to copy the live image to.\n" $usbdevlist \
	--button="OK":0 --button="Exit":1)
		if [[ $? != 0 ]] ; then
			exit 0
		fi

		if [[ -z $device ]] ; then
			no_device_message=$"\n  You did not select a usb device. Rescan to select one."
			warning_message=$"\n  You did not select a usb device. Rescan to select one."
			warning_dialog
		elif ! [[ -b $device ]] ; then 
			echo "Device $device is not a block device!"
			no_device_message=$"\n  You did not select a usb device; rescan to select one."
			exit_message=$"Device $device is not a block device."
			exit_dialog
		else
			echo "$device" > /tmp/r2u_device
		fi

		if (mount | grep -q "$device"); then

			echo "${device} appears mounted.. attempting to umount.."
			umount ${device}1 || echo "Umounting ${device}1 has failed.. You must resolve this to continue."

			if (mount | grep -q "$device"); then

				text="\n Selected device ${device} has active mount(s) and appears busy. \n\n You must resolve this before running $TITLE.."
				yad  --window-icon="$_ICON" --title=$TITLE $ERROR --width=360 --height=160 --fixed --center --text="$text" --button="Exit":1

				exit 1
			fi
		fi
}


select_source () {

	target_name=$(yad --window-icon="$_ICON" --title=$TITLE --entry --entry-text="" --center --text=$" For multi-boot live-USB, a CD image will be copied to its own directory on your USB drive.  
 Enter a name for that directory. The name will also be used in your boot menu. " \
	--button="OK":0 --button="Exit":1)
		if [[ $? != 0 ]] ; then
#			cleanup2
			exit 0
		fi
		
	if [[ -n $target_name ]] ; then
		target_dir="${target_name}/"
		target_message=$"Target directory:	/$target_name"
		
	else
		target_dir=""
		exit_message=$"No target directory selected for multiboot. "
		exit_dialog
	fi

# Source is iso file	
if [[ $opts =~ ISO ]] ; then	
		isofile=$(yad --file-selection --file-filter="*.[iI][sS][oO]" --file-filter="*" \
	--width=640 --height=480 --center --title=$"Select Live ISO" --window-icon="$_ICON" --text=$"\nSelect the CD image file:" \
	--filename="" --button=OK:0 --button=Quit:1)
		if [[ $? = 1 ]] ; then
#			cleanup2
			run_task
		fi

	if [[ -z "$isofile" ]]; then
		exit_message=$"\nYou did not select a CD image file."
		exit_dialog
	fi

	if ! $(echo $isofile | grep -q .[Ii][Ss][Oo]$); then
		exit_message=$"\nYou did not select a CD image file.."
		exit_dialog
	fi
	
	#mount "$isofile" "$image_mountpoint"
		image_mountpoint="/tmp/isomount" # for all but running live.
		mkdir -p "$image_mountpoint"
		#image_mountpoint=$(df | grep 	"${source_device}1" | awk '{ print $6 }')
		#	above works for usb flash drive, but not for live-CD
		# if $source_device = /dev/sr0 ; then do other stuff, maybe $source_vol is either /dev/sdX1 or /dev/sr0
	mount "$isofile" "$image_mountpoint"
	
	image_size=$(du -h "$isofile" )


# Source is running live-usb
elif [[ $opts =~ live-usb ]] ; then
	source_device=$(yad --window-icon="$_ICON" --title="$TITLE" --width=400 --height=200 --center --list --separator="" --column="" --text=$"Detected USB devices:\n\n$usbdevfulllist\n\nSelect the device that contains the currently running system. (The one you booted from)" $usbdevlist \
	--button="OK":0 --button="Exit":1)
		
		if [[ $? != 0 ]] ; then
			exit 0
		fi

	image_mountpoint=$(df | grep 	"${source_device}1" | awk '{ print $6 }')
	if ! [[ -d "$image_mountpoint" ]] ; then
		exit_message=$"\nNot a live session or wrong version of live-boot."
		exit_dialog
	fi

	livemount=$(yad --file-selection --filename="$image_mountpoint" --directory \
	--width=640 --height=480 --center --title=$"Select Source System" --window-icon="$_ICON" --text=$"If you are copying from a multiboot usb, select the folder that contains the system you want to copy to the second flash drive. Note: If that live system uses the findiso boot option, and that iso has uefi boot files, you should use the ISO_1 task instead.

If you are running from cdrom, the default should be right. (Take the whole thing.)

The file selection window should show 
${image_mountpoint}" \
	--filename="" --button=OK:0 --button=Quit:1)
		if [[ $? = 1 ]] ; then
#			cleanup2
			run_task
		fi

#	if [[ -z "$isofile" ]]; then
#		exit_message=$"\nYou did not select a CD image file."
#		exit_dialog
#	fi

	image_size=$(du -sh "$livemount")


	# Source is live-cd
elif [[ $opts =~ live-cd ]] ; then

	cdromlist=$(/usr/sbin/hwinfo --cdrom --short|grep "/dev/s"|awk '{print $1}')
	cdromfulllist=$(/usr/sbin/hwinfo --cdrom --short|grep "/dev/s"|awk '{print $0}')

	if [[ -z "$cdromfulllist" ]] ; then
		no_device_message=$"\n   ###  WARNING: No cdrom device was detected. What media did you boot?  ###  "
		run_task
	fi


	source_device=$(yad --window-icon="$_ICON" --title="$TITLE" --width=400 --height=200 --center --list --separator="" --column="" --text=$"Detected CDROM devices:\n\n$cdromfulllist\n\nSelect the device that contains the currently running system. (The one you booted from)" $cdromlist \
	--button="OK":0 --button="Exit":1)
		
		if [[ $? != 0 ]] ; then
			exit 0
		fi

	image_mountpoint=$(df | grep 	"$source_device" | awk '{ print $6 }')
	if ! [[ -d "$image_mountpoint" ]] ; then
		exit_message=$"\nNot a live session or wrong version of live-boot."
		exit_dialog
	fi
fi

	target_device="$usb_mountpoint"
	check_size
	if [[ $? = 3 ]] ; then
		cleanup
		run_task
	fi

	multiboot_path_message=$"If the source system is on a multiboot usb, the named directory from the source will be in the paths for kernel, initrd and live-media-path in the final boot menu entry. You will need to edit those paths to remove that directory name."

	
# Open a window with the boot menu from the iso file (or live mount.)
	iso_boot_menu=$(yad --window-icon="$_ICON" --title=$"ISO Boot Menu - For Reference" --file-selection --filename="${image_mountpoint}/*"  --file-filter="*.cfg" \
	--text=$"\nSelect the boot menu from the iso file. (Possibly /isolinux/live.cfg).\n\nYou may need to copy/paste an entry or two into your actual boot menu, which will open in another editor window in a few steps.\n\n${multiboot_path_message}\n" \
	--height 640 --width 480 --center --button=OK:0 --button="Skip":1)

	if [[ -n "$iso_boot_menu" ]] ; then
		yad --window-icon="$_ICON" --title="ISO Boot Menu - For Reference" --text-info --button="Close Window":0 \
		--width 640 --height 480 --posx=-12 < "$iso_boot_menu" &
		sleep 2
	fi
	
	image_source_dir="$image_mountpoint"
	select_kernel_text=$"\nSelect the kernel image for this live system."
	select_kernel
	select_initrd
	select_kernel_text=""
}


copy_iso_files () {
 
if [[ $opts =~ live-usb ]] ; then
	rsync $rsyncopts "$livemount"/ "$usb_mountpoint"/${target_dir}
	local_path=$(echo $local_path | sed -e "s:$target_name/::")
	if [[ $copy_efi_files = "yes" ]] ; then
		rsync  $rsyncopts "$livemount"/boot "$usb_mountpoint"/
		rsync  $rsyncopts "$livemount"/efi "$usb_mountpoint"/
	fi
else	
	rsync -avh --progress "$image_mountpoint"/ "$usb_mountpoint"/${target_dir}
	if [[ $copy_efi_files = "yes" ]] ; then
		rsync  $rsyncopts "$image_mountpoint"/boot "$usb_mountpoint"/
		rsync  $rsyncopts "$image_mountpoint"/efi "$usb_mountpoint"/		
	fi
fi

set_menu_options

	menu_text="
label $target_name
    menu label $target_name
    kernel /${target_name}${local_path}/${kernel_name} 
    append initrd=/${target_name}${local_path}/${initrd_name} boot=live live-media-path=/${target_name}${local_path} ${union_opt} ${netconfig_opt} ${basemount_opt} ${username_opt} ${locale_opt} ${custom_opts} 
"
	echo "$menu_text" > /tmp/boot_menu_text

	#new function (functions/functions.common): tidy up multiple spaces, indents, newlines ++)
	format_boot_menu /tmp/boot_menu_text

	grub_menu_text="
menuentry \"$target_name \" {
    set gfxpayload=keep
    linux   /${target_name}${local_path}/${kernel_name} boot=live live-media-path=/${target_name}${local_path} ${union_opt} ${netconfig_opt} ${basemount_opt} ${username_opt} ${locale_opt} ${custom_opts} 
    initrd  /${target_name}${local_path}/${initrd_name}
}
"
	echo "$grub_menu_text" > /tmp/grub_menu_text

	format_boot_menu /tmp/grub_menu_text
	
	unset menu_opts

	finished_message=$" An entry for $target_name will be added to your boot menu.
 The boot menu will be opened in a text editor for your review.
 
 ${multiboot_path_message}
"
	finished_dialog
}


setup_findiso () {
	
	if ! [[ -d "${usb_mountpoint}/${target_name}" ]] ; then
		mkdir -p "${usb_mountpoint}/${target_name}"
	fi
	
	cp "$kernel_image" "${usb_mountpoint}/${target_dir}"
	cp "$initrd_image" "${usb_mountpoint}/${target_dir}"

	# Not working as expected. No progress stats.
	#cp "$isofile" "${usb_mountpoint}/${target_dir}" | tee >(yad --title=$"Copying ISO file..." --window-icon="$_ICON" --progress --pulsate --auto-close --width 300)

	rsync  $rsyncopts "$isofile" "${usb_mountpoint}/${target_dir}" | tee >(yad --window-icon="$_ICON" --title="$TITLE" --progress-text="Copying ISO file.. Please wait.." --progress --pulsate --auto-close --width 320)

	##cp -a "$image_mountpoint"/isolinux "${usb_mountpoint}/${target_dir}"
	if [[ $copy_efi_files = "yes" ]] ; then
		rsync  $rsyncopts "$image_mountpoint"/boot "$usb_mountpoint"/
		rsync  $rsyncopts "$image_mountpoint"/efi "$usb_mountpoint"/		
	fi

# Open a window with the boot menu from the iso file.	
	
# Create a menu entry.

	isofile_name="${isofile##*/}"

set_menu_options
		
	menu_text="
label $target_name
    menu label $target_name
    kernel /${target_name}/${kernel_name} 
    append initrd=/${target_name}/${initrd_name} boot=live findiso=/${target_name}/${isofile_name} ${union_opt} ${netconfig_opt} ${basemount_opt} ${username_opt} ${locale_opt} ${custom_opts}  
"
	echo "$menu_text" > /tmp/boot_menu_text

	#new function (functions/functions.common): tidy up multiple spaces, indents, newlines ++)
	format_boot_menu /tmp/boot_menu_text

	grub_menu_text="
menuentry \"$target_name \" {
    set gfxpayload=keep
    linux   /${target_name}/${kernel_name} boot=live ${union_opt} findiso=/${target_name}/${isofile_name} ${netconfig_opt} ${basemount_opt} ${username_opt} ${locale_opt} ${custom_opts} 
    initrd  /${target_name}/${initrd_name}
}
"
	echo "$grub_menu_text" > /tmp/grub_menu_text
	
	format_boot_menu /tmp/grub_menu_text

	unset menu_opts
	
	finished_message=$"$isofile_name was copied to ${target_name}

An entry for this will be added to your boot menu.
The boot menu will be opened in an editor for your review.

"

	finished_dialog
}



install_syslinux () {

write_to_mbr="TRUE"  ##### for testing?

# TODO : Check the device is detected else stop..

# Make sure the syslinux directory exists, in case we're reinstalling
# the bootloader without adding a new live system.
if ! [[ -d "$usb_mountpoint"/syslinux ]] ; then
	syslinux_template="${r2u_library}/syslinux"
	rsync  $rsyncopts "$syslinux_template"/ "$usb_mountpoint"/syslinux/
fi


# copy_syslinux_modules so they match the host's version of syslinux.
# These three are needed for syslinux v.6.03 (jessie/sid)
if [[ -f /usr/lib/syslinux/modules/bios/vesamenu.c32 ]] ; then
	syslinux_modules_prefix="/usr/lib/syslinux/modules/bios"
	cp -a "$syslinux_modules_prefix"/ldlinux.c32 "$usb_mountpoint"/syslinux/
	cp -a "$syslinux_modules_prefix"/libcom32.c32 "$usb_mountpoint"/syslinux/
	cp -a "$syslinux_modules_prefix"/libutil.c32 "$usb_mountpoint"/syslinux/
else
	syslinux_modules_prefix="/usr/lib/syslinux"
fi

cp -a "$syslinux_modules_prefix"/vesamenu.c32 "$usb_mountpoint"/syslinux/
cp -a "$syslinux_modules_prefix"/chain.c32 "$usb_mountpoint"/syslinux/

# Syslinux docs say should be umounted to do syslinux and mbr.. but it still works..
syslinux -d syslinux ${device}1

if [[ $write_to_mbr = "TRUE" ]] ; then
	if [[ -f /usr/lib/syslinux/mbr.bin ]] ; then
		syslinux_mbr_bin="/usr/lib/syslinux/mbr.bin"
	elif [[ -f /usr/lib/SYSLINUX/mbr.bin ]] ; then
		syslinux_mbr_bin="/usr/lib/SYSLINUX/mbr.bin"
	elif [[ -f /usr/lib/syslinux/mbr/mbr.bin ]] ; then
		syslinux_mbr_bin="/usr/lib/syslinux/mbr/mbr.bin"
	else
		exit_message=$"\nCould not write to mbr. $syslinux_mbr_bin is missing."
		exit_dialog
	fi
	
	dd bs=440 count=1 conv=notrunc if=$syslinux_mbr_bin of=${device}
		echo "syslinux copied to mbr"
fi

}


add_live_system () {
	
	select_source  # set target dir and select source iso
	check_efi
	$copy_stuff

#Test for /syslinux - do this before making menu
#	if syslinux directory exists, do nothing
#	if syslinux directory does not exist, do all four steps
#	if reinstalling bootloader, do steps 2,3,4
#
#1. (create only) copy menu files and help files from package.
#2. copy *.c32 files from host system
#3. syslinux -d syslinux
#4. dd bs=440 count=1 conv=notrunc if=$syslinux_mbr_bin of=${device}


# Create syslinux directory if one does not exist, and install bootloader.
### TODO: Check if /syslinux.cfg exists elsewhere (/boot/syslinux/ /boot/isolinux/ or /isolinux/
# They are all valid places. Also to be found if so: ldlinux.sys ldlinux.c32
# For example, antiX uses /boot/syslinux ..

	if ! [[ -d "$usb_mountpoint"/syslinux ]] ; then
 yad --window-icon="$_ICON" --title=$"${TITLE}.. Install Bootloader" $WARNING --width=640 --height=240 --center --fixed \
 --text=$"\n There is no /syslinux directory on ${device}1. It looks like you need a bootloader.\n
 If you are already using a different bootloader on this live-USB, e.g. GRUB: \n\
 You should say NO here.\n\n\
 If syslinux is already installed to a directory other than /syslinux:\n\
 You should say NO here.\n\n\
 Install syslinux bootloader to /syslinux?"  \
	--button="Yes":0 --button="No":1
		if [[ $? = 0 ]] ; then
			syslinux_template="${r2u_library}/syslinux"
			rsync  $rsyncopts "$syslinux_template"/ "$usb_mountpoint"/syslinux/
			install_syslinux
		fi
	fi
}


check_efi () {		
	
	echo "image_mountpoint is $image_mountpoint"
	ls "$image_mountpoint"
	echo
	echo "usb_mountpoint is $usb_mountpoint"
	ls "$usb_mountpoint"
	
	if [[ -d "$image_mountpoint"/efi ]] && [[ -d "$image_mountpoint"/boot ]] ; then
		if [[ -d "$usb_mountpoint"/efi ]] && [[ -d "$usb_mountpoint"/boot ]] ; then
			yad --window-icon="$_ICON" --title=$"EFI Boot Files" $QUESTION --center --text=$"\nEFI boot files already exist in the root of the target device. Do you want to replace them?" \
				--button="Don't change":0 --button="Replace files":1
				if [[ $? = 0 ]] ; then
					copy_efi_files="no"
				else	
					copy_efi_files="yes"
					if [[ -f "${usb_mountpoint}/boot/grub/grub.cfg" ]] ; then
		                grub_boot_menu="${usb_mountpoint}/boot/grub/grub.cfg"
						yad --window-icon="$_ICON" --title="GRUB Boot Menu - For Reference" --text-info --button="Close Window":0 \
						--width 640 --height 480 --posx=-100 --posy=60 --text=$"\nThis is the boot menu that will be replaced. You may need to copy some entries to the new menu." < "$grub_boot_menu" &
						sleep 2
					fi
				fi
		else
			copy_efi_files="yes"
		fi

		if ! [[ -f "$usb_mountpoint"/isolinux/isolinux.cfg ]] ; then
			mkdir  "$usb_mountpoint"/isolinux
			# TODO: What is this for?
			touch "$usb_mountpoint"/isolinux/isolinux.cfg
		fi
	fi
	echo "@@@@@@@@@@  copy_efi_files is $copy_efi_files"
}



edit_boot_menu () {

# some options don't need to do menus, e.g. mkloopback without persistence
if ! [[ -f "/tmp/boot_menu_text" ]]; then return; fi
	
# Check if first partition of selected device is mounted for live system.	
	if (df |grep "${device}1" | grep "/lib/live/mount") ; then
		usb_mountpoint=$(df | grep 	"${device}1" | awk '{ print $6 }')

	elif (df |grep "${device}1" | grep "/run/live") ; then
		usb_mountpoint=$(df | grep 	"${device}1" | awk '{ print $6 }')
	else
		usb_mountpoint="/tmp/${device##*/}1"		
	fi	
	
	if ! [[ -d "$usb_mountpoint" ]] ; then
		mkdir "$usb_mountpoint"
	fi
	
	if ! $(grep -q ${device}1 /proc/mounts) ; then
		mount $mountopts ${device}1 "$usb_mountpoint"
	fi

# Set the syslinux boot menu.

	syslinux_dialog_text=$"\n Select the (syslinux) boot menu. Default: syslinux/live.cfg (but *maybe* different)\n"

	boot_menu=$(yad --window-icon="$_ICON" --title="$TITLE" --width 480 --height 480 --fixed --center \
	--file-selection --file-filter="*.[cC][fF][gG]" --file-filter="*" --filename="$usb_mountpoint"/syslinux/live.cfg \
	--text="$syslinux_dialog_text" --button=OK:0 --button=Exit:1)
		if [[ $? != 0 ]] ; then
#			cleanup
			exit 0
		fi
			
		if ! [[ -f "$boot_menu" ]] ; then
			warning_message=$"No syslinux boot menu was selected."
			warning_dialog
			run_task
			return
		fi

		echo "syslinux boot_menu is $boot_menu"
		unset syslinux_dialog_text

# Set the grub boot menu.

	if [[ -f "${usb_mountpoint}/boot/grub/grub.cfg" ]] ; then

		grub_dialog_text=$"\n Select the (grub) boot menu. Default: boot/grub/grub.cfg (but *maybe* different)\n"

		grub_boot_menu=$(yad --window-icon="$_ICON" --title="$TITLE" --width 480 --height 480 --fixed --center \
 	--file-selection --file-filter="*.[cC][fF][gG]" --file-filter="*" --filename="${usb_mountpoint}/boot/grub/grub.cfg" \
	--text="$grub_dialog_text" --button=OK:0 --button=Exit:1)

			if [[ $? != 0 ]] ; then
#				cleanup
				exit 0
			fi
			
			if ! [[ -f "$boot_menu" ]] ; then
				warning_message=$"No grub boot menu was selected."
				warning_dialog
				run_task
				return
			fi

		echo "grub_boot_menu is $grub_boot_menu"
		unset grub_dialog_text
	fi

###########  Don't need tmp file if everything is in one script.
	menu_text=$(cat /tmp/boot_menu_text)
	if [[ -n "$menu_text" ]] ; then
		echo "$menu_text" >> "$boot_menu"
	fi

	grub_menu_text=$(cat /tmp/grub_menu_text)
	if [[ -n "$grub_menu_text" ]] ; then
		echo "$grub_menu_text" >> "$grub_boot_menu"
	fi	
	
	find_editor

	# Open in user's editor:
	#"$editor" ${editor_option} "$boot_menu" 
	su $username -c "$editor ${editor_option} $boot_menu"

	if [[ -n "$grub_boot_menu" ]] ; then
		#"$editor" ${editor_option} "$grub_boot_menu"
		su $username -c "$editor ${editor_option} $grub_boot_menu"
	fi

	# if we call egress now, other functions which use edit_boot_menu will stop here ...
	# files, loop devices and active mounts could be left in /tmp ..
	# anyway, egress is called in run_task.
	#egress

	# Job done, remove these temp files:
	rm -f /tmp/boot_menu_text
	rm -f /tmp/grub_menu_text
}


advanced_tasks () {
#	unset adv_opt
	# Clear $opts from Main Menu - otherwise, we don't go back to it.
	opts=""
	adv_opt=""
	
	adv_opt=$(yad --window-icon="$_ICON" --title=$"${TITLE}.. Tools/Utilities" --list \
     --text=$"\n See Help for explanations and instructions.\n" \
     --column $"Task" --column $"Num" --column $"Description"  \
     --width=625 --height=400  --center \
     --button="OK":0 --button="Exit":1 \
  Help 01 $" Instructions - Read Me!  " \
  Edit 02 $" Edit boot menu on completed USB thumb drive." \
  Bootloader 03 $" (Re)install syslinux to partition and to mbr." \
  Alternate_mbr 04 $" Alternate bootloader. (install-mbr)" \
  Fix_mbr 10 $" Zero the entire mbr, reformat, install syslinux. (fix-mbr)" \
  Patch_initrd 05 $" Rebuild initrd for runtime read/write fat32. (patch-initrd-gui)" \
  Mount_loop 06 $" Mount a loopfile that's not currently used for persistence. " \
  Unmount_loop 07 $" Unmount a loopfile that's not used for persistence. " \
  Delete_loop 08 $" Delete any leftover loop devices (not loopfiles)." \
  File_manager 09 $" Open device in a file-manager." \
  Main_Menu 00 $" Return to the Main Task Menu.")

	if [[ $? != 0 ]] ; then
#		if [[ -n "$device" ]] && $(grep -q ${device}1 /proc/mounts) ; then
#			cleanup
#		fi
		exit 0
	fi


	if [[ $adv_opt =~ Help ]] ; then
	yad --window-icon="$_ICON" --title=$"${TITLE} Help" --text-info --button=$"Close Window":0 --width 640 --height 480 < "$helpfile" &
		sleep 2
	fi


	if [[ $adv_opt =~ Edit ]] ; then
		edit_boot_menu
		egress
	fi


	if [[ $adv_opt =~ Bootloader ]] ; then
		if ! $(grep -q ${device}1 /proc/mounts) ; then
			usb_mountpoint="/tmp/${device##*/}1"
			mkdir /tmp/${device##*/}1
			mount $mountopts ${device}1 "$usb_mountpoint"
		fi
		install_syslinux
		egress
	fi


	if [[ $adv_opt =~ Alternate_mbr ]] ; then
		install_altboot
		egress
	fi


	if [[ $adv_opt =~ Fix_mbr ]] ; then


warning_message=$"\n Automatically prepare the USB device for syslinux: \n\n\
 Zero and reinstall MBR, (re-)format, install syslinux \n\n\
 Fix the device MBR if 'dd' was previously used for an isohybrid. \n\n\
 Possible solution for other USB device boot failure issues. \n\n\
 **WARNING: ALL EXISTING USB DATA WILL BE DELETED\! \n\n\
 Press OK to start or Quit to cancel this operation. \n\n\
 This could take some time. Go to the terminal to see progress."

		yad --window-icon="$_ICON" --title="$TITLE.. Reformat USB device.." --center --width=480 --height=360 --fixed \
		$WARNING --text="$warning_message" --button="OK":0 --button="Quit":1

		if [[ $? = 0 ]] ; then

			autoformat
			run_task
		else
			run_task
		fi
	fi


	if [[ $adv_opt =~ Patch_initrd ]] ; then
		check_device
		usb_mountpoint="/tmp/${device##*/}1"
		mkdir /tmp/${device##*/}1
		mount $mountopts ${device}1 "$usb_mountpoint"
		image_source_dir="$usb_mountpoint"
		select_initrd_text=$"\nSelect the initrd to be patched."
		select_initrd
		copy_initrd
		extract_initrd
		replace_files
		rebuild_initrd
		select_kernel_text=$"\nSelect the kernel that will use this custom initrd."
		select_kernel
		menu_entry_patched
		edit_boot_menu
		umount "$usb_mountpoint"
		egress
	fi


	if [[ $adv_opt =~ File_manager ]] ; then
		check_device
		usb_mountpoint="/tmp/${device##*/}1"
		mkdir /tmp/${device##*/}1
		mount $mountopts /dev/${device##*/}1 "$usb_mountpoint"
		find_file_manager

		# don't open it as root
		#"$file_manager" "$usb_mountpoint"

		if [ "$file_manager" = "/usr/bin/thunar" ]; then
			# Quit thunar daemon or script will not wait
			su $username -c "$file_manager -q && $file_manager"
			# reinstate thunar daemon for user
			su $username -c "$file_manager --daemon &>/dev/null &"
		else #
			su $username -c "$file_manager $usb_mountpoint"
		fi

		umount "$usb_mountpoint"
		egress
	fi


	if [[ $adv_opt =~ Mount_loop ]] ; then
		select_loop_mount
		mount_loop
	fi
	

	if [[ $adv_opt =~ Unmount_loop ]] ; then
		unmount_loop
	fi


	if [[ $adv_opt =~ Delete_loop ]] ; then
		select_loop_device
	fi


	if [[ $adv_opt =~ Main_Menu ]] ; then
			run_task
	fi
}


run_task () {
	opts=""
	opts=$(yad --window-icon="$_ICON" --title=$"${TITLE}.. Main Menu" --list --center  \
     --text=$" Choose a task.
     
 To create a live-USB, you'll need a fat32 partition flagged as bootable.
 If you want a second partition for saving files, you can create it now.
$no_device_message
$plugdev_message
" \
     --list --column $"Task" --column $"Num" --column $"Description"  \
     --width=590 --height=480 \
     --button="OK":0 --button="Exit":1 \
  Help 01 "	Instructions  -  Read Me!   " \
  Options 02 $" Change default settings for this run." \
  Format_1 03 $" Run the disk partitioner. (gparted)" \
  ISO_1  04 $" Create Live-USB from unpacked CD image." \
  ISO_2 05 $" Create Live-USB using intact iso and findiso boot option." \
  Live_1 06 $" Create Live-USB from a running live-usb system." \
  Live_2 07 $" Create Live-USB from a running live-cd system." \
  Persistent 08 $" Create/use a standard persistent partition. (mkpersist)" \
  Loopback 09 $" Create/use a loopback file for persistence. (mkloopback)" \
  Use_loop 10 $" Use an existing loopback file for persistence." \
  Rescan 11 $" ...after plugging in usb device (or to cleanup/unmount)." \
  Tools 00 $" Go directly to the Tools/Utilities Menu." )


	if [[ $? != 0 ]] ; then
		exit 0
	fi

	if [[ $opts =~ "Help" ]] ; then
		yad --window-icon="$_ICON" --title="${TITLE} Help" --text-info --button=$"Close Window":0 --width 640 --height 480 < "$helpfile" &
		sleep 2
		egress
	fi
	
	
	if [[ $opts =~ "ISO_1" ]] ; then
		check_device
		usb_mountpoint="/tmp/${device##*/}1"
		mkdir /tmp/${device##*/}1
		mount $mountopts ${device}1 "$usb_mountpoint"
		copy_stuff="copy_iso_files"
		# check_efi
		add_live_system
		edit_boot_menu
		egress
		# Device is still mounted.
	fi
	
	
	if [[ $opts =~ "ISO_2" ]] ; then
		check_device
		usb_mountpoint="/tmp/${device##*/}1"
		mkdir /tmp/${device##*/}1
		mount $mountopts ${device}1 "$usb_mountpoint"
		copy_stuff="setup_findiso"
		# check_efi
		add_live_system
		edit_boot_menu
		egress
		# Device is still mounted.
	fi

	
	if [[ $opts =~ "Live_1" ]] ;  then
		if [[ $live_session != "yes" ]] ; then
			warning_message=$"Not a live session or wrong version of live-boot."
			warning_dialog
			egress
		fi
		check_device
		usb_mountpoint="/tmp/${device##*/}1"
		mkdir /tmp/${device##*/}1
		mount $mountopts ${device}1 "$usb_mountpoint"
		copy_stuff="copy_iso_files"  ######
		# check_efi
		add_live_system
		edit_boot_menu
		egress
		# Device is still mounted.
	fi

	
	if [[ $opts =~ "Live_2" ]] ;  then
		if [[ $live_session != "yes" ]] ; then
			warning_message=$"Not a live session or wrong version of live-boot."
			warning_dialog
			egress
		fi
		check_device
		usb_mountpoint="/tmp/${device##*/}1"
		mkdir /tmp/${device##*/}1
		mount $mountopts ${device}1 "$usb_mountpoint"	
		copy_stuff="copy_iso_files"
#		check_efi
		add_live_system
		edit_boot_menu
		egress
		# Device is still mounted.
	fi
	
	
	if [[ $opts =~ Format_1 ]] ; then
		if [[ -f /usr/sbin/gparted ]] ; then
			gparted ${device}
		else
			cfdisk ${device}
		fi
		
		egress
	fi

	
	if [[ $opts =~ Options ]] ; then
	not_available
		setup_options
	fi
	
	
	if [[ $opts =~ Persistent ]] ; then
		partition_gui
		sanity_checks
		prepare_config
		encrypt_volume
		write_config
		write_menu_entry
		edit_boot_menu

		if [[ -f /tmp/persistence_label ]] ; then
			rm -f /tmp/persistence_label
		fi
		cleanup1	
		egress
	fi
	
	
	if [[ $opts =~ Loopback ]] ; then
		loopfile_settings
		prepare_device
		setup_file
		format_file
		mount_fs
		write_persistence_conf
		setup_boot_menu
		finished_dialog
		cleanup1
		edit_boot_menu
		egress
	fi


	if [[ $opts =~ "Use_loop" ]] ; then

		if ! $(grep -q ${device}1 /proc/mounts) ; then
			usb_mountpoint="/tmp/${device##*/}1"
			mkdir /tmp/${device##*/}1
			mount $mountopts ${device}1 "$usb_mountpoint"
		fi
		
		image_source_dir="$usb_mountpoint"
		use_existing_loop="yes"
		select_loop_mount
		mount_loop
		PERSISTENCE="yes"
		PERSISTENCE_TYPE="config"
		write_persistence_conf
		setup_boot_menu
		unmount_loop
		edit_boot_menu
		egress
	fi


	if [[ $opts =~ Rescan ]] ; then
		unset no_device_message
		cleanup
		select_device_gui
		egress
	fi
	
	
	if [[ $opts =~ Tools ]] ; then
		advanced_tasks
		egress
	fi

		
	echo $opts | awk -F"|" '{ print $1 }'
}


select_device_gui

"$start_menu"

exit 0
