#!/bin/bash
#
# knoppix-remaster - Copyright (c) 2004 by Fabian Franz <knoppix-remaster@fabian-franz.de> & Ian Naylor <iank@pitech.plus.com>
#
# License: GPL

# setup dialog

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

TITLE=$"Knoppix Remastering"
REMASTER_MASTER=/KNOPPIX.build/Knoppix.Master/KNOPPIX-CUSTOM

#
# functions
#

remaster_cleanup()
{
	[ -n "$REMASTER_CLEANUP_SWAP" ] && $DIALOG --title "$TITLE" --yesno $"Do you want to get rid of swapfile $REMASTER_SWAP_CHOICE/swapfile?\nIf you do not answer yes, you'll have to cleanup it yourself once you've finished." 0 0 && swapoff "$REMASTER_SWAP_CHOICE"/swapfile && rm -f "$REMASTER_SWAP_CHOICE"/swapfile
}

remaster_abort()
{
	[ -n "$REMASTER_PROGRESSPID" ] && kill $REMASTER_PROGRESSPID
	$DIALOG --title $"Error" --msgbox $"Fatal error: ""$@"$"\nExiting." 0 0
	exit 1
}

remaster_error_yesno()
{
	$DIALOG --title $"Error" --yesno $"Error: ""$@"$"\nDo you want to try again?" 0 0 || exit 1
	false
}

remaster_progressbar()
{
	REMASTER_START=$(df $REMASTER_CHOICE  | awk '{ print $3 }' | tail -n1 )
	while [ -d /proc/$! ];
	do
		REMASTER_PROGRESS=$(df $REMASTER_CHOICE  | awk '{ print $3 }' | tail -n1 )
		let REMASTER_PROGRESS=$REMASTER_PROGRESS-$REMASTER_START
		let REMASTER_PERC=($REMASTER_PROGRESS*100)/$REMASTER_NEEDED_SIZE
		[ "$REMASTER_PERC" -lt "100" ] && echo $REMASTER_PERC
		sleep $2
	done | $DIALOG --title "$TITLE" --gauge "$1" 0 0
}

# Create or choose an existing remaster 

remaster_create()
{
	$DIALOG --title "$TITLE" --msgbox $"The script needs a place where it can store the remaster.\nIn the next screen you'll be able to choose that directory." 0 0
	REMASTER_START="/"
	[ -d "$1" ] && REMASTER_START="$1"
	while true
	do
		REMASTER_CHOICE=$($DIALOG --stdout --title $"Select new remaster directory" --fselect "$REMASTER_START" 0 0) || exit 1

		mkdir -p $REMASTER_MASTER
	
		remaster_check_mount_options || continue

		let REMASTER_NEEDED_SIZE=($(df /cdrom /KNOPPIX | awk '{ N+=$3 } END { N+=(500000*0); print N }')*115)/100 
		REMASTER_HAVE_SIZE=$(df $REMASTER_CHOICE  | awk '{ print $4 }' | tail -n1 )
		{ [ "$REMASTER_NEEDED_SIZE" -lt "$REMASTER_HAVE_SIZE" ] || remaster_error_yesno $"Not enough space available on $REMASTER_CHOICE."; } || continue

		( remaster_progressbar $"Copying files... This may take a while." 10 ) &
		REMASTER_PROGRESSPID=$!

		cp -a /KNOPPIX/* $REMASTER_CHOICE/ || remaster_abort $"Could not copy files to $REMASTER_CHOICE.\nPlease cleanup the directory." 
		cp -a $REMASTER_SCRIPTS $REMASTER_CHOICE || remaster_abort $"Could not copy scripts to $REMASTER_CHOICE.\nPlease cleanup the directory."
	
		(cd /cdrom; find . -size -10000k -type f -exec cp -p --parents {} $REMASTER_CHOICE/$REMASTER_MASTER/ \;) # TODO: Add error handling
		kill $REMASTER_PROGRESSPID
		REMASTER_PROGRESSPID=""

		REMASTER_PARTINFO=$(df -T $REMASTER_CHOICE | tail -1 | awk '{ print $1 "\t" $7 "\t" $2 }')
		cat << EOF > $REMASTER_CHOICE/etc/fstab
/proc      /proc       proc   defaults            0 0
/sys       /sys        sysfs  noauto              0 0
$REMASTER_PARTINFO            defaults            0 0
EOF
		break
	done
}

remaster_choose()
{
	REMASTER_START="/"
	[ -d "$1" ] && REMASTER_START="$1"
	while true
	do
		REMASTER_CHOICE=$($DIALOG --stdout --title $"Select already existing remaster directory" --fselect "$REMASTER_START" 0 0) || exit 1
		
		{ [ -d "$REMASTER_CHOICE"/KNOPPIX.build/ ] || remaster_error_yesno "$REMASTER_CHOICE seems not to be an Remaster directory."; } || continue

		remaster_check_mount_options || continue

		break
	done
}

#
# check if the mount options are correct, and if not: correct it
#

remaster_check_mount_options()
{
	REMASTER_MOUNT_DEV=$(df "$REMASTER_CHOICE" | tail -1 | cut -d" " -f1)
	# we have to remount right ...
	mount -o remount,rw,suid,dev "$REMASTER_MOUNT_DEV" || remaster_error_yesno $"Remounting rw,suid,dev of $REMASTER_MOUNT_DEV failed."
}


# Do several things with the remaster

remaster_chroot()
{
	cp -f /etc/dhcpc/resolv.conf "$REMASTER_CHOICE"/etc/dhcpc/
	chroot "$REMASTER_CHOICE" mount /proc
	chroot "$REMASTER_CHOICE" mount /sys 2>/dev/null
  
	chroot "$REMASTER_CHOICE" su -
  
	chroot "$REMASTER_CHOICE" umount /proc 2>/dev/null
	chroot "$REMASTER_CHOICE" umount /sys 2>/dev/null
}

remaster_create_compressed_fs()
{
        REMASTER_CLEANUP=""
	$DIALOG --title "$TITLE" --yesno $"Do you want to cleanup your remaster?" 0 0 && REMASTER_CLEANUP="yes"
	cp -f /etc/dhcpc/resolv.conf "$REMASTER_CHOICE"/etc/dhcpc/
	CREATE_COMPRESSED_FS="yes" CLEANUP="$REMASTER_CLEANUP" COMPRESSION_BEST="${REMASTER_COMPRESSION_BEST:+--best}" chroot "$REMASTER_CHOICE" /KNOPPIX.build/Knoppix-3.4.mkcompressed "$REMASTER_MASTER" auto
}

remaster_create_iso_fs()
{
	CREATE_ISO_FS="yes" chroot "$REMASTER_CHOICE" /KNOPPIX.build/Knoppix-3.4.mkcompressed "$REMASTER_MASTER" auto
}

# TODO: Add nice dialogs for editing options

remaster_edit_options()
{

	[ -z "$REMASTER_COMPRESSED_FILESYSTEM" ] && REMASTER_COMPRESSED_FILESYSTEM="KNOPPIX_FS"
	[ -z "$REMASTER_COMPRESSED_AUTHOR" ] && REMASTER_COMPRESSED_AUTHOR="UKUUG Hackers"
	[ -z "$REMASTER_COMPRESSED_HOMEPAGE" ] && REMASTER_COMPRESSED_HOMEPAGE="www.ukuug.org"

	[ -z "$REMASTER_FILESYSTEM" ] && REMASTER_FILESYSTEM="KNOPPIX"
	[ -z "$REMASTER_AUTHOR" ] && REMASTER_AUTHOR="UKUUG Hackers"
	[ -z "$REMASTER_HOMEPAGE" ] && REMASTER_HOMEPAGE="www.ukuug.org"

	cat <<EOF > "$REMASTER_CHOICE"/KNOPPIX.build/remaster_config
REMASTER_COMPRESSED_FILESYSTEM="$REMASTER_COMPRESSED_FILESYSTEM"
REMASTER_COMPRESSED_AUTHOR="$REMASTER_COMPRESSED_AUTHOR"
REMASTER_COMPRESSED_HOMEPAGE="$REMASTER_COMPRESSED_HOMEPAGE"

REMASTER_FILESYSTEM="$REMASTER_FILESYSTEM"
REMASTER_AUTHOR="$REMASTER_AUTHOR"
REMASTER_HOMEPAGE="$REMASTER_HOMEPAGE"

REMASTER_COMPRESSION_BEST="$REMASTER_COMPRESSION_BEST" # say yes here to use the best compression, leave blank if you do not want it
EOF
	
	mcedit  "$REMASTER_CHOICE"/KNOPPIX.build/remaster_config
	
	. "$REMASTER_CHOICE"/KNOPPIX.build/remaster_config
}

remaster_load_sort_file()
{
	REMASTER_SORT_FILE=$($DIALOG --stdout --title $"Select sort file" --fselect "$(pwd)/" 0 0) || return 1
	[ -f "$REMASTER_SORT_FILE" ] && cp -f "$REMASTER_SORT_FILE" "$REMASTER_CHOICE"/KNOPPIX.build/mkisofs.sort
}

remaster_menu()
{
	while true
	do
		CHOICE=$($DIALOG --title "$TITLE" --stdout --menu $"Choose one action" 0 70 7 \
			$"1 Chroot" $"Chroot into your remaster" \
			$"2 Create compressed fs" $"Create the compressed filesystem" \
			$"3 Create isofs" $"Create the ISO file" \
			$"4 Edit options" $"Edit several options (like author)" \
			$"5 Load sort file" $"Load a sort file to optimize your remaster" \
			$"6 Quit" $"Quit the program") || break
		case "$CHOICE" in 
			$"1 Chroot")
				remaster_chroot
			;;
			$"2 Create compressed fs")
				remaster_create_compressed_fs
			;;
			$"3 Create isofs")
				remaster_create_iso_fs
			;;
			$"4 Edit options")
				remaster_edit_options
			;;
			$"5 Load sort file")
				remaster_load_sort_file
			;;
			$"6 Quit")
				break
			;;
		esac
done
}

remaster_create_swapfile()
{
	REMASTER_SWAP_CHOICE=$($DIALOG --stdout --title $"Select directory where to put the swapfile (will be called swapfile)" --fselect "$(pwd)/" 0 0) || exit 1
	REMASTER_SWAP_SIZE=$($DIALOG --stdout --title "$TITLE" --inputbox $"How large (in MB) do you want the swap file to be?" 0 0 500) || exit 1
	
	# start progressbar
	let REMASTER_NEEDED_SIZE=$REMASTER_SWAP_SIZE*1024
	REMASTER_CHOICE="$REMASTER_SWAP_CHOICE"
	
	( remaster_progressbar $"Creating swapfile... This may take a while." 1 ) &
	REMASTER_PROGRESSPID=$!

	unset REMASTER_NEEDED_SIZE
	unset REMASTER_CHOICE
	
	dd if=/dev/zero of="$REMASTER_SWAP_CHOICE"/swapfile bs=1M count=$REMASTER_SWAP_SIZE || remaster_abort $"Could not create swapfile."
	mkswap "$REMASTER_SWAP_CHOICE"/swapfile || remaster_abort $"mkswap on $REMASTER_SWAP_CHOICE/swapfile failed."
	swapon "$REMASTER_SWAP_CHOICE"/swapfile || remaster_abort $"swapon on $REMASTER_SWAP_CHOICE/swapfile failed."
	export REMASTER_SWAP_CHOICE

	# kill the progressbar
	kill $REMASTER_PROGRESSPID
	REMASTER_PROGRESSPID=""

	#re-exec the program
	exec $0 "$1" "cleanup_swap"
}

#
# main program
#

trap "remaster_cleanup" EXIT

REMASTER_SCRIPTS=""

[ -d "/usr/share/knoppix-remaster/KNOPPIX.build" ] && REMASTER_SCRIPTS=/usr/share/knoppix-remaster/KNOPPIX.build
[ -d "$(pwd)/KNOPPIX.build" ] && REMASTER_SCRIPTS=$(pwd)/KNOPPIX.build

[ -n "$REMASTER_SCRIPTS" ] || remaster_abort $"Could not find KNOPPIX.build scripts.\nMake sure they can be found in /usr/share/knoppix-remaster/ or in the current directory."
[ $UID -eq 0 ] || remaster_abort $"You have to be root to use this script."

[ "$2" = "cleanup_swap" ] && REMASTER_CLEANUP_SWAP=yes

REMASTER_MEMORY=$(cat /proc/meminfo | egrep "^MemTotal|^SwapTotal" | awk '{ N+=$2; } END { print N }')
if [ "$REMASTER_MEMORY" -lt "1000000" ] 
then
	if [ -z "$REMASTER_CLEANUP_SWAP" ]
	then
		$DIALOG --title "$TITLE" --yesno  $"Not enough memory. You need at least 1 GB of RAM+Swap available for a Knoppix CD.\nDo you want to create a swapfile?" 0 0 || exit 1
		remaster_create_swapfile "$1" 
		# the above should never return so we are exiting here
		exit 2
	else
		remaster_error_yesno $"Not enough memory. The created swapfile is not big enough."
		export REMASTER_CLEANUP_SWAP=""
		swapoff $REMASTER_SWAP_CHOICE/swapfile || remaster_abort $"swapoff on $REMASTER_SWAP_CHOICE/swapfile failed."
		rm -f $REMASTER_SWAP_CHOICE/swapfile || remaster_abort $"Removing $REMASTER_SWAP_CHOICE/swapfile failed."
		exec $0 "$1"
	fi
fi

$DIALOG --title "$TITLE" --yesno $"Do you want to create a new remaster?" 0 0

if [ $? -eq 0 ]
then
	remaster_create "$1"
else
	remaster_choose "$1"
fi


# {Q: We now have a usable remaster environment in $REMASTER_CHOICE and $REMASTER_MASTER is set to the master directory }

[ -f "$REMASTER_CHOICE"/KNOPPIX.build/remaster_config ] && . "$REMASTER_CHOICE"/KNOPPIX.build/remaster_config

remaster_menu
