#! /bin/sh
# 
# Gtkdialog box for the mount command. Part of SliTaz tools.
#
VERSION=20100328

# Check if user is root.
check_root()
{
	if test $(id -u) != 0 ; then
		echo -e "
You must be root to run `basename $0`. Please type 'su' and 
root password to become super-user.\n"
		exit 0
	fi
}

# This function is used after each screen to contine or abort install.
check_retval()
{
	case $retval in
		1)
			rm -f /tmp/floppybox.grub.menu
			echo -e "\nVoluntary exit.\n" && exit 0 ;;
		255)
			rm -f /tmp/floppybox.grub.menu
			echo -e "ESC pressed.\n" && exit 0 ;;
	esac
}

# check or list floppy devices.
list_floppy()
{
	local list
	list=""
	for i in /sys/devices/platform/floppy.*/block:*; do
		[ -d $i ] || continue
		list="$list ${i#*block:}"
	done
	[ -n "$1" ] || echo $list
	[ -n "$list" ]
}

# dialog to select the floppy device
select_floppy()
{
	DEVICE="$DIALOG --title \" Floppy device \" --backtitle \"Boot Floppy Creation\" --clear --extra-button --extra-label \"Format\" --colors --radiolist \"
Select boot device
\" 18 70 50"
	on=on
	for i in $(list_floppy); do
		DEVICE="$DEVICE /dev/$i 'Floppy in $i' $on"
		on=off
	done
	DEVICE="$DEVICE floppy \"floppy image file boot.fd\" $on"
	DEVICE="$DEVICE cdrom \"cdrom image file boot.iso\" off 2>&1 1>&3"
	exec 3>&1
	DEVICE=`eval $DEVICE`
	retval=$?
	exec 3>&-
	check_retval
	if [ "$retval" = "3" ]; then
		case "$DEVICE" in
		/dev/*) fdformat -n $DEVICE;;
		esac
    	fi
}

# Build menu for grub or grub4dos
mkmenu()
{
if [ "$1" = "grub4dos" ]; then
	SAVEDEFAULT="save default"
	cat > /tmp/floppybox.grub.menu <<EOT
# grub4dos menu
default /default
EOT
else
	SAVEDEFAULT="savedefault"
	cat > /tmp/floppybox.grub.menu <<EOT
# grub menu
default saved
EOT
fi
cat >> /tmp/floppybox.grub.menu <<EOT
timeout 8
color yellow/brown light-green/black

EOT
entry=0
[ -f /boot/gpxe ] && entry=$(($entry + 1)) && cat >> /tmp/floppybox.grub.menu <<EOT
title gPXE (Boot from the Web, PXE/iSCSI/AoE support)
	kernel /boot/gpxe $(dd if=/boot/gpxe bs=1 skip=519 count=255 2>/dev/null | strings)

EOT
[ -f /usr/share/boot/btmgr -a -f /usr/share/boot/memdisk.lzma ] \
	&& entry=$(($entry + 1)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Smart Boot Manager (text - boot floppy, hard disk or CD/DVD)
	kernel /boot/memdisk floppy c=80 h=2 s=18
	initrd /boot/btmgr.gz

EOT
http://mirror.slitaz.org/boot/plpbt.bin
[ -f /usr/share/boot/plpbt.bin ] \
	&& entry=$(($entry + 1)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Plop Boot Manager (graphic - boot floppy, hard disk, CD/DVD or USB)
	kernel /boot/plpbt.bin

EOT
[ -f /usr/share/boot/etherboot ] && entry=$(($entry + 1)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Etherboot (LAN boot, PXE or NBI)
	kernel /boot/etherboot

EOT
[ -f /usr/share/boot/memtest.lzma -a -f /usr/share/boot/memdisk.lzma ] \
&& entry=$(($entry + 1)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Memtest86+ (Test system memory)
	kernel /boot/memdisk floppy c=80 h=2 s=18
	initrd /boot/memtest.gz

EOT
[ "$1" = "grub4dos" ] && entry=$(($entry + 3)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Windows (scan ntldr)
	fallback $(($entry -3 + 1))
        find --set-root /ntldr
	chainloader /ntldr
	$SAVEDEFAULT --wait=2

title Windows (scan cmldr)
	fallback $(($entry -3 + 2))
        find --set-root /cmldr
        chainloader /cmldr
	$SAVEDEFAULT --wait=2

title Windows (scan io.sys)
	fallback $(($entry -3 + 3))
        find --set-root /io.sys
        chainloader /io.sys
	$SAVEDEFAULT --wait=2

EOT
entry=$(($entry + 3)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Windows (example on /dev/hda1)
	rootnoverify (hd0,0)
	chainloader +1
	$SAVEDEFAULT

title Slitaz Frugal (example on /dev/hda1)
	root (hd0,0)
	kernel /boot/bzImage rw root=/dev/null vga=normal
	initrd /boot/rootfs.gz
	$SAVEDEFAULT

title Slitaz Installed (example on /dev/hda2)
	root (hd0,1)
	kernel /boot/bzImage ro root=/dev/hda2 vga=normal
	$SAVEDEFAULT

EOT
[ "$1" = "grub4dos" ] && entry=$(($entry + 1)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Slitaz cdrom image (example on /dev/hda1, DEFRAGMENTED)
        map (hd0,0)/boot/slitaz-cooking.iso (hd1)
        map --hook
        kernel (hd1)/boot/bzImage rw root=/dev/null vga=normal
        initrd (hd1)/boot/rootfs.gz
	$SAVEDEFAULT

EOT
false && [ -f /usr/share/boot/grub.exe.lzma ] && entry=$(($entry + 1)) && cat >> /tmp/floppybox.grub.menu <<EOT
title Grub4Dos
	kernel /boot/grub/grub.exe --config-file="configfile (fd0)/boot/grub/menu4dos.lst"

EOT
}

# Install grub or grub4dos on floppy
install_grub()
{
	LOOP=""
	GRUB_DEV=${DEVICE#/dev/}
	GRUB_DEV=${GRUB_DEV%% *}
	case "$DEVICE" in
	floppy*)
		LOOP="-o loop"
		GRUB_DEV=fd0
		DEVICE=boot.fd
		dd if=/dev/zero of=$DEVICE bs=18k count=80;;
	esac
	grep -qs "^# $2 menu" /tmp/floppybox.grub.menu || mkmenu $2
	case "$DEVICE" in
	/dev/*|boot.fd)
		yes y | mke2fs $DEVICE
		mkdir /media/floppy
		mount $LOOP $DEVICE /media/floppy
		if [ "$2" = "grub4dos" ]; then
			mkdir -p /media/floppy/boot
			unlzma -c /usr/share/boot/grldr.lzma > /media/floppy/grldr
			cp $1/boot/* /media/floppy/boot 2> /dev/null
			cp /tmp/floppybox.grub.menu /media/floppy/menu.lst
			umount -d /media/floppy
			bootlace --floppy --sectors-per-track=18 --heads=2 \
				 --chs --ext2 $DEVICE
		else
			mkdir -p /media/floppy/boot/grub
			cp /usr/lib/grub/i386-pc/stage? /media/floppy/boot/grub
			cp -a $1/boot /media/floppy
			cp /tmp/floppybox.grub.menu /media/floppy/boot/grub/menu.lst
			grub-set-default --root-directory=/media/floppy 0
			echo "($GRUB_DEV) $(losetup | grep $DEVICE | cut -d: -f1)" > $1/device.map
			[ -n "$LOOP" ] && LOOP="--device-map=$1/device.map"
			grub $LOOP --batch <<EOT
root ($GRUB_DEV)
setup ($GRUB_DEV)
quit
EOT
			umount -d /media/floppy
		fi ;;
	cdrom*)
		mkdir -p $1/boot/grub 2> /dev/null
		cp /tmp/floppybox.grub.menu $1/boot/grub/menu.lst
		if [ "$2" = "grub4dos" ]; then
			unlzma -c /usr/share/boot/grldr.lzma > $1/boot/grub/grldr
			genisoimage -R -o boot.iso -b boot/grub/grldr \
				-c boot/boot.cat -no-emul-boot -boot-load-seg 0x1000 \
				-hide boot/boot.cat -input-charset iso8859-1 $1
		else
			cp /usr/lib/grub/i386-pc/stage2_eltorito $1/boot/grub
			genisoimage -R -o boot.iso -b boot/grub/stage2_eltorito \
				-c boot/boot.cat -no-emul-boot -boot-load-size 4 \
				-hide boot/boot.cat -input-charset iso8859-1 \
				-boot-info-table $1
		fi ;;
	esac
}

# Build /init for floppies from iso image
buildinit()
{
	mv $1/init $1/init.org
	cat > $1/init <<EOTEOT
#!/bin/sh

mount -t proc proc /proc
total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
# the floppy driver may not be included in kernel
insmod /lib/modules/*/kernel/drivers/block/floppy.ko.gz 2> /dev/null
# loram may put floppy.ko.gz module in /lib
insmod /lib/floppy.ko.gz 2> /dev/null
umount /proc
while read name min num count file md5; do
	[ -e \$file ] && continue
	[ \$total -lt \$min ] && break
	while [ \$count -ne 0 ]; do
		tmp="\$(dd if=/dev/fd0 count=1 2> /dev/null | md5sum)"
		echo -n "Insert floppy \$num for \$name and press Enter or Q to skip"
		while true; do
			echo -n ":"
			read -t 10 answer < /dev/tty0
			case "\$answer" in
			Q*|q*|A*|a*) break 3;;
			esac
			dd if=/dev/fd0 count=1 > /tmp/bs.\$\$ 2> /dev/null
			[ -s /tmp/bs.\$\$ ] || continue
			[ "\$(md5sum < /tmp/bs.\$\$)" != "\$tmp" ] || continue
			rm -f /tmp/bs.\$\$
			break
		done
		dd if=/dev/fd0 of=/tmp/rootfs.\$num 2> /dev/null || continue
		cat /tmp/rootfs.\$num >> /tmp/rootfs
		rm -f /tmp/rootfs.\$num
		num=\$((\$num+1))
		count=\$((\$count-1))
	done
	echo "\$md5  /tmp/rootfs" | md5sum -c || break
	cpio -idmu < /tmp/rootfs > /dev/null 2>&1 ||
	( zcat /tmp/rootfs 2> /dev/null || unlzma -c /tmp/rootfs ) | cpio -idmu
	rm -f /tmp/rootfs*
done <<EOT
$(while read line; do echo $line; done)
EOT
mv -f /init.org /init || sh
exec /init
EOTEOT
	chmod +x $1/init
}

# write a 32 bits data
# usage: storelong offset data32 file
storelong()
{
	printf "00000  %02X %02X %02X %02X \n" \
		$(( $2 & 255 )) $(( ($2>>8) & 255 )) \
		$(( ($2>>16) & 255 )) $(( ($2>>24) & 255 )) | \
	hexdump -R | dd bs=1 conv=notrunc of=$3 seek=$(( $1 )) 2> /dev/null
}

# read a 32 bits data
# usage: getlong offset file
getlong()
{
	dd if=$2 bs=1 skip=$(( $1 )) count=4 2> /dev/null | \
		hexdump -e '"" 1/4 "%d" "\n"'
}

# output floppy images set
floppysetcat()
{
	KERNEL="$1"
	INITRD="$2"
	shift 2
	CMDLINE="$@"

	# bzImage offsets
	SetupSzOfs=497
	SyssizeOfs=500
	CodeAdrOfs=0x214
	RamfsAdrOfs=0x218
	RamfsLenOfs=0x21C
	ArgPtrOfs=0x228

	# boot+setup address
	SetupBase=0x90000

	stacktop=0x9E00

	bs=/tmp/bs$$

	# Get and patch boot sector
	dd if=$KERNEL bs=512 count=1 of=$bs 2> /dev/null
	uudecode <<EOT | dd of=$bs conv=notrunc 2> /dev/null
begin-base64 644 -
/L+6nWgAkAcGF4n8McC5HQDzq1sfD6mg8X1ABlfFd3ixBvOlZWaPR3gGH8ZF
+D/6l1hB6CsBvgACA3QO6HYBWwseKAJ0K1PoUgFe6GcBsCDNELAIzRBO6GYB
PAh0A4gErTk2KAJ08Og/ATwKdeCIfP6J5v9MEP9MGL/0AYFNHP+Ax0UwAJyw
D7EFtJOJRBywAYlEFJhmmNPgSGYDBWbT6GgAEAe/gAAp+JxzAgHHMdtQVujm
AF65AIC0h/5EHM0VWJ133KEaAki/HAKxCThEHHK4k80T6gAAIJCwRijIvtsB
6NMAXesjgPkTcgQ4wXdjgP4CcgQ45ndkYIH9AAZ0KgZSUVOWtAJQsQa1BMHF
BLAPIegEkCcUQCfojQD+zXXssCDNEOK06JcAmM0TYVJQKMh3ArABmDn4cgKJ
+FC0As0TlV5YWnKgT0GAxwJOdfg4wXVFiMj+xrEBOOZ1O4j0/sW2ADou8AFy
L4D9UHIqtQBgvt4B/kQMU+g6AFvoQQB1FlKYzRO4AQLNE1rQ1Dpk/nXqRgjk
deVhlY7hT4zhiehHdYoWB7AxLAO0DrsHAM0QPA1088OwDejv/6wIwHX4w79s
BLFbZQINuA0BZToNdArNFnT0mM0Wju9Hw1g6AEluc2VydCBkaXNrIDEuBw0A
AA==
====
EOT

	# Get setup
	setupsz=$(getlong $SetupSzOfs $bs)
	setupszb=$(( $setupsz & 255 ))
	dd if=$KERNEL bs=512 skip=1 count=$setupszb 2> /dev/null >> $bs

	# Store cmdline after setup
	if [ -n "$CMDLINE" ]; then
		echo -n "$CMDLINE" | dd bs=512 count=1 conv=sync 2> /dev/null >> $bs
		storelong ArgPtrOfs $(( $SetupBase + $stacktop )) $bs
	fi

	# Compute initramfs size
	initrdlen=0
	padding=0
	for i in $( echo $INITRD | sed 's/,/ /' ); do
		[ -s "$i" ] || continue
		initrdlen=$(( $initrdlen + $padding ))
		padding=$(stat -c %s $i)
		initrdlen=$(( $initrdlen + $padding ))
		padding=$(( 4096 - ($padding & 4095) ))
		[ $padding -eq 4096 ] && padding=0
	done
	Ksize=$(( $(getlong $SyssizeOfs $bs)*16 ))
	Kpad=$(( (($Ksize+4095)/4096)*4096 - Ksize ))
	if [ $initrdlen -ne 0 ]; then
		Kbase=$(getlong $CodeAdrOfs $bs)
		storelong $RamfsAdrOfs \
			$(( (0x1000000 - $initrdlen) & 0xFFFF0000 )) $bs
		storelong $RamfsLenOfs $initrdlen $bs
	fi

	# Output boot sector + setup + cmdline
	dd if=$bs 2> /dev/null

	# Output kernel code
	dd if=$KERNEL bs=512 skip=$(( $setupszb + 1 )) 2> /dev/null

	# Pad to next sector
	Kpad=$(( 512 - ($(stat -c %s $KERNEL) & 511) ))
	[ $Kpad -eq 512 ] || dd if=/dev/zero bs=1 count=$Kpad 2> /dev/null

	# Output initramfs
	padding=0
	for i in $( echo $INITRD | sed 's/,/ /' ); do
		[ -s "$i" ] || continue
		[ $padding -ne 0 ] && dd if=/dev/zero bs=1 count=$padding
		dd if=$i 2> /dev/null
		padding=$(( 4096 - ($(stat -c %s $i) & 4095) ))
		[ $padding -eq 4096 ] && padding=0
	done

	# Cleanup
	rm -f $bs
}

# Create boot floppy set from kernel, initrd & cmdline
floppyset()
{
	floppysetcat $@ | split -b 1440k /dev/stdin floppy$$
	i=1
	ls floppy$$* | while read file ; do
		output=floppy.$(printf "%03d" $i)
		cat $file /dev/zero | dd bs=1k count=1440 of=$output conv=sync 2> /dev/null
		rm -f $file
		i=$(( $i + 1 ))
	done
}

# Create boot floppy set from a SliTaz ISO image
floppysetfromiso()
{
	mkdir /tmp/iso$$
	mount -o loop,ro $1 /tmp/iso$$
	rootfs="$(ls /tmp/iso$$/boot/rootfs*.gz 2> /dev/null | tail -1)"
	bzimage=/tmp/iso$$/boot/bzImage
	if [ -z "$rootfs" -o ! -s $bzimage ]; then
		umount -d /tmp/iso$$
		rm -rf /tmp/iso$$
		echo "Not a SliTaz ISO image !"
		return 1
	fi
	mkdir -p /tmp/rootfs$$/fs
	n=1
	for i in $(ls /tmp/iso$$/boot/rootfs*.gz | sort -r); do
		mkdir /tmp/rootfs$$/$n
		ln -s $i /tmp/rootfs$$/$n
		n=$(($n + 1))
	done
	echo "Unpack rootfs..."
	( zcat $rootfs 2> /dev/null | unlzma -c $rootfs ) | \
		( cd /tmp/rootfs$$/fs ; cpio -idm > /dev/null )
	if [ $(unlzma -c $rootfs 2> /dev/null| wc -c) -gt $(stat -c %s $rootfs) ]; then
		if [ $(du -ck $rootfs $bzimage | awk 'END { print $1 }') -gt 15296 ]; then
	# The rootfs.gz file is too big, extract a minimum bootfs with busybox stuff
			echo "Extract bootfs..."
			mv /tmp/rootfs$$/fs /tmp/rootfs$$/fs0
			for i in lib bin sbin usr/bin usr/sbin ; do
				mkdir -p /tmp/rootfs$$/fs/$i
			done
			cd /tmp/rootfs$$/fs0
			dir=$(echo lib/modules/*/kernel/drivers/block)
			mkdir -p ../fs/$dir
			[ -f $dir/floppy.ko.gz ] && mv $dir/floppy.ko.gz ../fs/$dir
			for i in dev init mnt proc sys tmp ; do
				mv $i ../fs
			done
			mv lib/lib[cm][.-]* lib/ld-* ../fs/lib
			for i in $(bin/busybox | awk '{ if (s) printf "%s",$0 }
				   /Currently/ { s=1 }' | sed 's/,//g'); do
				for j in bin sbin usr/bin usr/sbin ; do
					[ -e $j/$i ] && mv $j/$i ../fs/$j/$i
				done
			done
			mv bin/busybox ../fs/bin
			rm -f ../1/*
			find | cpio -o -H newc | lzma e ../1/rootfs.gz -si
			cd - > /dev/null
			rm -rf /tmp/rootfs$$/fs0
		else
	# The rootfs.gz file fit in 15Mb, no need to split it.
			rm -rf /tmp/rootfs$$/1
		fi
	else
	# This is a loram rootfs.gz, extract loram bootstrap
		echo "Split loram rootfs..."
		hexdump -C $rootfs | grep " 30 37 30 37 " | \
		while read offset rem; do
			offset=$((0x$offset / 4))
			for i in 1 2 3 4; do
				tag=$(dd if=$rootfs bs=4 skip=$offset count=2 2> /dev/null)
				if [ "07070100" != "$tag" ]; then
					offset=$(($offset + 1))
					continue
				fi
				dd if=$rootfs skip=$(($offset / 1024)) bs=4k count=1 2> /dev/null | \
				dd skip=$(($offset % 1024)) bs=4 of=/tmp/rootfs$$/1/root 2> /dev/null
				dd if=$rootfs skip=$((1 + ($offset / 1024) )) bs=4k \
					>> /tmp/rootfs$$/1/root 2> /dev/null
				rm -f /tmp/rootfs$$/1/rootfs*
				break 2
			done
		done
	fi
	# Create extra rootfs floppies
	for i in /tmp/rootfs$$/[1-9]*/root* ; do
		[ -f $i ] || continue
		echo "Create floppies for rootfs $(basename $(dirname $i) )..."
		case "$(dd if=$i bs=1 count=4 2> /dev/null)" in
		0707) cat $i ;;
		*)    zcat $i 2> /dev/null || unlzma -c $i ;;
		esac | cpio -t > $(dirname $i)/files.list
		sed -i '/ blocks$/d' $(dirname $i)/files.list
		x=$(readlink $i)
		[ -n "$x" ] || x=$i
		pad=$(( $(stat -c %s $x ) % 1474560 ))
		[ $pad -ne 0 ] && pad=$(( 1474560 - $pad ))
		dd if=/dev/zero bs=1 count=$pad 2> /dev/null | cat $i - | \
		split -b 1440k /dev/stdin $(dirname $i)/floppy
	done
	selection="$(grep append /tmp/iso$$/boot/isolinux/common.cfg | sed 's/.*append //')"
	[ -n "$selection" ] || selection="0 slitaz"
	set -- $selection
	selection=""
	while [ -n "$2" ]; do
		[ ! -d /tmp/rootfs$$/1 -a -z "$4" ] && break
		case "$1" in
		*G)	selection="$2 $(( ${1%G} * 1024 * 1024 )) $selection" ;;
		*M)	selection="$2 $(( ${1%M} * 1024 )) $selection" ;;
		*)	selection="$2 $1 $selection" ;;
		esac
		shift 2
	done
	echo "Create /init ..."
	base=100
	set -- $selection
	for i in /tmp/rootfs$$/[1-9]* ; do
		[ -d $i ] || continue
		while read file; do
			[ -e $i/../fs/$file ] && continue
			[ $(grep -- "$file" $i/../*/files.list | wc -l) -eq 1 ] &&
			break
		done < $i/files.list
		printf "%s %s %03d %d %s %s\n" \
			$1 $2 $base $(ls $i/floppy* | wc -l) $file \
			$(cat $i/floppy* | md5sum - | awk '{print $1}')
		base=$(($base + 100))
		shift 2
	done | buildinit /tmp/rootfs$$/fs
	cmdline="$(grep append /tmp/iso$$/boot/isolinux/isolinux.cfg | tail -n 1 | sed 's/.*gz //')"
	( cd /tmp/rootfs$$/fs ; find | cpio -o -H newc ) | lzma e /tmp/rootfs$$/rootfs -si
	echo "Create first stage boot floppies..."
	floppyset $bzimage /tmp/rootfs$$/rootfs $cmdline
	base=100
	for i in /tmp/rootfs$$/[1-9]* ; do
		[ -d $i ] || continue
		j=0
		for f in $i/floppy* ; do
			mv $f $(printf "floppy.%03d" $(( $base + $j )) )
			j=$(($j + 1))
		done
		base=$(($base + 100))
	done
	rm -rf /tmp/rootfs$$
	umount -d /tmp/iso$$
	rm -rf /tmp/iso$$
}

# Show new boot floppy set
dialogwritefloppyset()
{
	if ! list_floppy check; then
		du -h floppy.???
		return
	fi
	while true; do
	exec 3>&1
	IMAGE=`$DIALOG --title " Write floppy image " \
		--backtitle "Boot floppy set creation on $DEVICE" --clear \
		--colors --radiolist "
    Insert a blank floppy in drive and
select the floppy image you what to write.
" 18 46 46 \
		$(on="on"; for i in floppy*; do echo "$i $(du -h $i | cut -f1) $on "; on="off"; done) 2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	dd if=$IMAGE of=$DEVICE
	done
}

dialognofloppyset()
{
	cat << EOT
The boot loader can't load the kernel and the initramfs in the first 16Mb
of RAM. The total size exceed 15Mb. No floppy image is created.
EOT
}

# Check for iso 9660 image
isiso()
{
	mkdir /tmp/iso$$
	mount -o loop,ro $1 /tmp/iso$$ 2> /dev/null
	status=$?
	umount -d /tmp/iso$$ 2> /dev/null
	rm -rf /tmp/iso$$
	return $status
}

dialogfloppyset()
{
	: ${DIALOG=dialog}
	while true; do
	exec 3>&1
	KERNEL=`$DIALOG --title " Select a Linux kernel or a SliTaz iso " \
		--backtitle "Boot floppy set creation on $DEVICE" --clear \
		--colors --fselect "$PWD" 10 70 \
		2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	[ -f $KERNEL ] && break
	done
	if isiso $KERNEL ; then
		bootfloppybox call mkisofloppies $KERNEL
		dialogwritefloppyset
		return
	fi
	exec 3>&1
	INITRD=`$DIALOG --title " Select an Initramfs " \
		--backtitle "Boot floppy set creation on $DEVICE" --clear \
		--colors --fselect "$PWD" 10 70 \
		2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	[ -f "$INITRD" ] || INITRD=""
	exec 3>&1
	CMDLINE=`$DIALOG --title " Enter boot command line " \
		--backtitle "Boot floppy set creation on $DEVICE" --clear \
		--colors --inputbox "Kernel command line" 10 70 "rw root=/dev/null autologin" \
		2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	bootfloppybox call mkfloppies $KERNEL $INITRD $CMDLINE &&
	dialogwritefloppyset ||
	dialognofloppyset
}

#
# Create floppy image set
#
export IMAGE_SET='
<window title="Image set generator" icon-name="gtk-floppy">
  <vbox>
    <text use-markup="true">
      <label>
"
<b>Create a boot floppy set</b>
"
      </label>
    </text>
    <notebook labels="Slitaz only|Any linux">
    <frame Slitaz only (no size limit)>
    <vbox>
    <text wrap="false" width-chars="44" use-markup="true">
      <label>
"
Slitaz distro use a floppy boot flavor as first
stage boot to break the tiny loader 15Mb limit.
"
      </label>
    </text>
    <hbox>
      <text use-markup="true">
        <label>"<b>Slitaz ISO : </b>"</label>
      </text>
      <entry accept="filename">
        <label>Select a Slitaz ISO image</label>
        <variable>ISO</variable>
      </entry>
      <button>
        <input file stock="gtk-open"></input>
        <action type="fileselect">ISO</action>
      </button>
    </hbox>
    <hbox>
      <text use-markup="true">
        <label>"<b>Output directory : </b>"</label>
      </text>
      <entry accept="directory">
        <label>Select output directory</label>
        <variable>FILE_DIRECTORY</variable>
        <default>/tmp</default>
      </entry>
      <button>
        <input file stock="gtk-open"></input>
        <action type="fileselect">FILE_DIRECTORY</action>
      </button>
    </hbox>
    <hbox>
      <button>
        <input file icon="forward"></input>
        <label>Create image set from ISO boot</label>
	<action>cd $OUTPUTDIR; bootfloppybox call mkisofloppiesxterm $ISO</action>
        <action type="closewindow">IMAGE_SET</action>
      </button>
    </hbox>
    </vbox>
    </frame>
    <frame Any Linux distribution (max total size 14-15Mb)>
    <vbox>
    <text wrap="false" width-chars="44" use-markup="true">
      <label>
"
The total size of the kernel and the initramfs must be
lower than 14-15Mb due to the tiny boot loader design.
"
      </label>
    </text>
    <hbox>
      <text use-markup="true">
        <label>"<b>Kernel      : </b>"</label>
      </text>
      <entry accept="filename">
        <label>Select a linux kernel</label>
        <variable>KERNEL</variable>
      </entry>
      <button>
        <input file stock="gtk-open"></input>
        <action type="fileselect">KERNEL</action>
      </button>
    </hbox>
    <hbox>
      <text use-markup="true">
        <label>"<b>Initramfs : </b>"</label>
      </text>
      <entry accept="filename">
        <label>Select an initramfs/initrd file</label>
        <variable>INITRD</variable>
      </entry>
      <button>
        <input file stock="gtk-open"></input>
        <action type="fileselect">INITRD</action>
      </button>
    </hbox>
    <hbox>
      <text use-markup="true">
        <label>"<b>Cmdline   : </b>"</label>
      </text>
      <entry>
        <label>Enter kernel arguments</label>
        <variable>CMDLINE</variable>
        <default>rw root=/dev/null autologin</default>
      </entry>
    </hbox>
    <hbox>
      <text use-markup="true">
        <label>"<b>Output directory : </b>"</label>
      </text>
      <entry accept="directory">
        <label>Select output directory</label>
        <variable>OUTPUT_DIRECTORY</variable>
        <default>/tmp</default>
      </entry>
      <button>
        <input file stock="gtk-open"></input>
        <action type="fileselect">OUTPUT_DIRECTORY</action>
      </button>
    </hbox>
    <hbox>
      <button>
        <input file icon="forward"></input>
        <label>Create image set</label>
	<action>cd $OUTPUTDIR; bootfloppybox call mkfloppies $KERNEL $INITRD $CMDLINE</action>
        <action type="closewindow">IMAGE_SET</action>
      </button>
    </hbox>
    </vbox>
    </frame>
    </notebook>
    <hbox>
      <button>
        <input file icon="gtk-close"></input>
        <action type="closewindow">IMAGE_SET</action>
      </button>
    </hbox>
  </vbox>
</window>
'

#
# Read/write floppy images
#
export FLOPPY_IMAGE='
<window title="Floppy image manager" icon-name="gtk-floppy">
  <vbox>
    <frame Floppy disk drive>
      <hbox>
        <text use-markup="true">
          <label>"<b>Device : </b>"</label>
        </text>
	<combobox>
          <variable>DEVICE</variable>'
FLOPPY_DEV=""
for i in $(list_floppy); do
	FLOPPY_DEV="$FLOPPY_DEV
	  <item>/dev/$i</item>"
done
	FLOPPY_IMAGE="$FLOPPY_IMAGE$FLOPPY_DEV
	</combobox>
        <button>
          <label>Format floppy</label>
          <input file icon=\"media-floppy\"></input>
	  <action>fdformat -n $DEVICE</action>
        </button>
      </hbox>
    </frame>
    <frame Floppy image file>
      <hbox>
        <text use-markup=\"true\">
          <label>\"<b>File : </b>\"</label>
        </text>
        <entry accept=\"filename\">
          <label>Select a floppy image</label>
          <variable>IMAGE</variable>
        </entry>
        <button>
          <input file stock=\"gtk-open\"></input>
          <action type=\"fileselect\">IMAGE</action>
        </button>
      </hbox>
    </frame>
    <hbox>
      <button>
        <input file icon=\"reload\"></input>
        <label>Create image set</label>
	<action type=\"launch\">IMAGE_SET</action>
      </button>
      <button>
        <input file icon=\"go-jump\"></input>
        <label>Write image to floppy</label>
        <action>dd if=\$IMAGE of=\$DEVICE</action>
      </button>
      <button>
        <input file icon=\"undo\"></input>
        <label>Get floppy image</label>
        <action>dd if=\$DEVICE of=\$IMAGE</action>
      </button>
      <button>
        <input file icon=\"gtk-close\"></input>
        <action type=\"closewindow\">FLOPPY_IMAGE</action>
      </button>
    </hbox>
  </vbox>
</window>
"

gtkdialogshowfloppyset()
{
#
# Show floppy image set
#
IMAGE_SHOW='
<window title="Image set" icon-name="gtk-floppy">
  <vbox>
    <text use-markup="true">
      <label>
"
<b>Boot floppy images</b>
"
      </label>
    </text>
    <tree>
        <width>50</width><height>140</height>
    	<label>Size|File</label>
    	<input>du -h floppy.??? | sed "s/\t/|/" </input>
    </tree>
    <hbox>
'
	[ 0$1 -gt $((15 * 1024 * 1024)) ] &&  IMAGE_SHOW="$IMAGE_SHOW
    <frame WARNING>
    <text>
      <label>
\"This floppy set breaks 15Mb limit ($1 bytes).
It should not be able to complete boot process.\"
      </label>
    </text>
    </frame>
    </hbox>
    <hbox>
"
	list_floppy check && IMAGE_SHOW="$IMAGE_SHOW
      <button>
        <input file icon=\"media-floppy\"></input>
	<label>Manage images</label>
	<action type=\"launch\">FLOPPY_IMAGE</action>
      </button>
"
	IMAGE_SHOW="$IMAGE_SHOW
      <button>
        <input file icon=\"gtk-close\"></input>
        <action type=\"closewindow\">IMAGE_SET</action>
      </button>
    </hbox>
  </vbox>
</window>
"
	export IMAGE_SHOW
	gtkdialog --program=IMAGE_SHOW
}

while true; do

if [ "$1" == "call" ]; then
	case "$2" in
	mkmenu) mkmenu $3;;
	mkisofloppiesxterm)
		shift 2
		xterm -geometry 80x16 -title "Build boot floppies from ISO" \
			-e "$0 call mkisofloppies $@ ; echo -e \"----\nENTER to continue...\" && read close"
		gtkdialogshowfloppyset
		;;
	mkisofloppies)
		shift 2
		floppysetfromiso $@
		;;
	mkfloppies)
		shift 2
		floppyset $@
		sz=$(cat floppy.* | wc -c)
		if [ -n "$XAUTHORITY" ]; then
			gtkdialogshowfloppyset $sz
		else
			if [ $sz -gt $((15 * 1024 * 1024)) ]; then
				cat <<EOT
This floppy set breaks 15Mb limit ($sz bytes).
It should not be able to complete boot process.
EOT
			fi
		fi
		;;
	install)
		DIR=/tmp/mkbootfloppy$$
		mkdir -p $DIR
		DEVICE=$4
		file=$5
		case "$3" in
		dialog*)
			shift 2
			$@
			;;
		grub*)
			mkdir -p $DIR/boot/grub
			[ -f /usr/share/boot/btmgr -a -f /usr/share/boot/memdisk.lzma ] \
				&& cat /usr/share/boot/btmgr /dev/zero | \
				   dd bs=18k count=80 | gzip -9 > \
				   $DIR/boot/btmgr.gz \
				&& unlzma -c /usr/share/boot/memdisk.lzma > \
					$DIR/boot/memdisk
			[ -f /usr/share/boot/plpbt.bin ] \
			  	&& cp /usr/share/boot/plpbt.bin $DIR/boot
			[ -f /usr/share/boot/etherboot ] \
				&& cp /usr/share/boot/etherboot $DIR/boot
			[ -f /boot/gpxe ]\
				&& cp /boot/gpxe $DIR/boot
			[ -f /usr/share/boot/memtest.lzma -a \
			  -f /usr/share/boot/memdisk.lzma ] \
				&& unlzma -c /usr/share/boot/memtest.lzma | \
				   cat - /dev/zero | dd bs=18k count=80 | \
				   gzip -9 > $DIR/boot/memtest.gz \
				&& unlzma -c /usr/share/boot/memdisk.lzma > \
					$DIR/boot/memdisk
			install_grub $DIR $3
			;;
		*)
    			case "$file" in
    			*.lzma) action="unlzma -c";;
    			*.gz)   action="zcat";;
    			*)      action="cat";;
    			esac
			case "$DEVICE" in
			/dev/*) $action $file > $DEVICE;;
			flopp*) $action $file | cat - /dev/zero | \
						dd bs=18k count=80 > boot.fd;;
			cdrom*)
				mkdir -p $DIR/boot/grub
				case "$3" in
				btmgr|memtest)
					$action $file | cat - /dev/zero | \
						dd bs=18k count=80 | \
						gzip -9 > $DIR/boot/$3.gz
					unlzma -c /usr/share/boot/memdisk.lzma \
						> $DIR/boot/memdisk
					cat > /tmp/floppybox.grub.menu << EOT
# grub menu
timeout 0
title $3
kernel /boot/memdisk floppy c=80 h=2 s=18
initrd /boot/$3.gz
EOT
					;;
				*)	$action $file > $DIR/boot/$3
					cat > /tmp/floppybox.grub.menu << EOT
# grub menu
timeout 0
title $3
kernel /boot/$3
EOT
					;;
				esac
				install_grub $DIR grub
				;;
			esac
			;;
		esac
		rm -rf $DIR
		;;
	get-plop)
		mkdir -p /tmp/get-plop$$
		PLOP_URL=http://mirror.slitaz.org/boot/plpbt.bin
		wget -O - $PLOP_URL  > /tmp/get-plop$$/plpbt.bin
		VERSION="$(strings /tmp/get-plop$$/plpbt.bin \
		  | grep 'Boot Manager v' | sed 's/.* v\([0-9\.]*\) .*/\1/')"
		mkdir -p $(dirname /tmp/get-plop$$/plop-$VERSION/fs/$3)
		mv /tmp/get-plop$$/plpbt.bin \
		   /tmp/get-plop$$/plop-$VERSION/fs/$3
		if [ -s /tmp/get-plop$$/plop-$VERSION/fs/$3 ]; then 
			cat > /tmp/get-plop$$/plop-$VERSION/receipt <<EOT
PACKAGE="plop"
VERSION="$VERSION"
CATEGORY="non-free"
SHORT_DESC="Plop boot manager."
WEB_SITE="http://www.plop.at/en/bootmanager.html"
EOT
			( cd /tmp/get-plop$$ ; tazpkg pack plop-$VERSION )
			tazpkg install /tmp/get-plop$$/plop-$VERSION.tazpkg
		fi
		rm -rf /tmp/get-plop$$
		;;
	*)	echo "Invalid command $0 $@" 1>&2
		exit 1;;
	esac
	exit 0
fi

if [ -z "$XAUTHORITY" ]; then

    : ${DIALOG=dialog}
    
    DEVICE=/dev/fd0
    list_floppy check || DEVICE="floppy"
    while true; do
	exec 3>&1
	ID_SOURCE=`$DIALOG --title " Choose a boot floppy " \
		--backtitle "Boot Floppy Creation on $DEVICE" --clear \
		--extra-button --extra-label "Change floppy" \
		--colors --radiolist "
Create a floppy or a cdrom to boot a LiveCD in a PXE network...
May need a floppy disk in drive. Erase the whole floppy disk.
		" 18 70 50\
		FloppySet	"Boot Slitaz with floppies only." on \
		SmartBtmgr	"Boot any partition or ATAPI CD-ROM." off \
		Plop		"Boot USB harddisk floppy or CD/DVD." off \
		Etherboot	"Replacement for proprietary PXE ROMs." off \
		gPXE		"Boot from http://boot.slitaz.org/" off \
		Memtest86+	"Memory failures detection tool." off \
		Grub4DOS	"Enhanced grub version supporting NTFS." off \
		Grub		"Boot loader with command shell." off \
		2>&1 1>&3`
	retval=$?
	exec 3>&-
	check_retval
	if [ "$retval" = "3" ]; then
		select_floppy
		continue;
	fi
	while read key file pkg; do
		[ "$key" = "$ID_SOURCE" ] || continue
		if [ ! -f "$file" ]; then
			$DIALOG --title " Install package " --colors \
				--backtitle "Boot Floppy Creation" --clear \
				--yes-label "Install" \
				--no-label "Quit" \
				--yesno "The package $pkg is not yet installed. Install it ?" 18 70
			retval=$?
			if [ "$pkg" = "plop" ]; then
				bootfloppybox call get-plop $file
			else
				tazpkg get-install $pkg
			fi
		fi
		bootfloppybox call install "$pkg" "$DEVICE" "$file"
		exit 0
	done <<EOT
FloppySet /bin/dd dialogfloppyset
SmartBtmgr /usr/share/boot/btmgr btmgr
Plop /usr/share/boot/plpbt.bin plop
Etherboot /usr/share/boot/etherboot etherboot
gPXE /boot/gpxe gpxe
Memtest86+ /usr/share/boot/memtest.lzma memtest
Grub4DOS /usr/share/boot/grldr.lzma grub4dos
Grub /usr/sbin/grub grub
EOT
    done
fi
#
# Describe gPXE arguments.
#
export HELP='
<window title="gPXE forced url" icon-name="gtk-floppy">
<vbox>
  <text use-markup="true">
    <label>"
<b>Web boot parameters</b>"
    </label>
  </text>
  <frame>
    <text wrap="true" width-chars="58" use-markup="true">
      <label>
"Without parameters (i.e. with an empty Boot URL) gPXE will perform a normal PXE boot: IP configuration with DHCP and download the DHCP bootfile with TFTP.

You can override the DHCP bootfile with a Boot URL such as <i>tftp://192.168.0.1/pxe/pxeloader</i>, <i>http://mirror.slitaz.org/pxe/pxelinux.0</i>, or <i>x-tftm://192.168.0.201//lts/vmlinuz.ltsp</i>.

You can override IP configuration too (useful without a DHCP server), example: <i>ip=192.168.0.10/24 gw=192.168.0.1 dns=192.168.0.1 nodhcp url=http://mirror.slitaz.org/pxe/pxelinux.0</i>

The <i>nodhcp</i> keyword avoids dhcp timeouts and the <i>url=</i> keyword is optional when the url is the only one argument.

Comma separated URL lists are supported. The PXE client will try to load the first URL. If the load fails, it will try the next URL, and so on. 
"
      </label>
    </text>
  </frame>
</vbox>
</window>
'
#
# Write bootfloppy image to floppy device.
#
BOOT_DIALOG='
<window title="bootfloppybox" icon-name="gtk-floppy">
  <vbox>
 
    <text use-markup="true">
      <label>
"
<b>SliTaz - Bootfloppybox</b>"
      </label>
    </text>
    <text wrap="false" width-chars="44" use-markup="true">
      <label>
"
Create a floppy or a cdrom to boot a LiveCD in a PXE network or the WEB...
May need a floppy disk in drive. Erase the whole floppy disk.
"
      </label>
    </text>
  
    <frame Floppy disk drive>
      <hbox>
        <text use-markup="true">
          <label>"<b>Device : </b>"</label>
        </text>
	<combobox>
          <variable>DEVICE</variable>'
FLOPPY_DEV=""
for i in $(list_floppy); do
	FLOPPY_DEV="$FLOPPY_DEV
	  <item>/dev/$i</item>"
done
	BOOT_DIALOG="$BOOT_DIALOG$FLOPPY_DEV
	  <item>floppy image (boot.fd)</item>
	  <item>cdrom image (boot.iso)</item>
	</combobox>"
if [ -n "$FLOPPY_DEV" ]; then
	tmp='
        <button>
          <label>Format floppy</label>
          <input file icon="media-floppy"></input>
	  <action>case "$DEVICE" in /dev/*) fdformat -n $DEVICE;; esac</action>
        </button>'
	BOOT_DIALOG="$BOOT_DIALOG$tmp"
fi
tmp='
      </hbox>
    </frame>
    <notebook labels="Set|LiveCD|USB|PXE Network|WEB Network|Memory Test|Windows|Expert">
    <frame Boot floppy set (many floppies)>
      <vbox>
      <hbox>
        <text wrap="true" width-chars="58" use-markup="true">
          <label>
"
Only people without CD-ROM, USB and Network should use a floppy set. 
The images are built from an ISO boot or from a Linux kernel, an initramfs
and a boot command line. Non Slitaz boot floppy set are limited to 15Mb.
"
          </label>
        </text>
      </hbox>
      <hbox>
      <button>
        <label>Create image set</label>
        <input file icon="forward"></input>
	<action type="launch">IMAGE_SET</action>
      </button>
      </hbox>
      </vbox>
    </frame>
'  
BOOT_DIALOG="$BOOT_DIALOG$tmp"
while read name file pkg desc; do
    tmp="<frame $name (single floppy)>
      <hbox>
    <text wrap=\"true\" width-chars=\"58\" use-markup=\"true\">
      <label>
\"
$(echo -e $desc)
\"
      </label>
    </text>
      </hbox>
      <hbox>
"
  if [ -f $file ]; then
    if [ "$pkg" = "grub" -o "$pkg" = "grub4dos" ]; then
      tmp="$tmp
      <button>
        <label>Grub menu</label>
        <input file icon=\"accessories-text-editor\"></input>
	<action>bootfloppybox call mkmenu $pkg</action>
        <action type=\"lauch\">leafpad /tmp/floppybox.grub.menu</action>
      </button>
"
    elif [ "$pkg" = "etherboot" ]; then
      tmp="$tmp
      <button>
        <input file icon=\"browser\"></input>
	<label>Wiki</label>
	<action>firefox http://wiki.slitaz.org/doku.php?id=quickstart:pxe &</action>
      </button>
"
    elif [ "$pkg" = "gpxe" ]; then
      tmp="$tmp
      <text wrap=\"true\" use-markup=\"true\">
        <label> \"<b>Boot URL:</b>\" </label>
      </text>
      <entry>
	<default>$(dd if=$file bs=1 skip=519 count=255 2>/dev/null | strings)</default>
        <variable>URL</variable>
      </entry>
      </hbox>
      <hbox>
      <button>
        <input file icon=\"browser\"></input>
	<label>Wiki</label>
	<action>firefox http://wiki.slitaz.org/doku.php?id=quickstart:pxe &</action>
      </button>
      <button help>
	<action type=\"launch\">HELP</action>
      </button>
      <button>
        <label>Update</label>
        <input file icon=\"reload\"></input>
	<action>echo -n \"\$URL\" | cat - /dev/zero | dd conv=notrunc bs=1 count=255 seek=519 of=$file 2>/dev/null</action>
      </button>
"
    fi
    receipt=/var/lib/tazpkg/installed/$pkg/receipt
    if [ -f $receipt ]; then
      . $receipt
      tmp="$tmp
      <button>
        <input file icon=\"browser\"></input>
	<label>Web</label>
	<action>firefox $WEB_SITE &</action>
      </button>
"
    fi
    tmp="$tmp
      <button>
        <label>Write floppy</label>
        <input file icon=\"forward\"></input>
	<action>bootfloppybox call install \"$pkg\" \"\$DEVICE\" \"$file\"</action>
      </button>
      </hbox>
    </frame>
"
  else
    tmp2="tazpkg get-install $pkg --forced"
    [ "$pkg" = "plop" ] && tmp2="bootfloppybox call get-plop $file"
    tmp="$tmp
      <text wrap=\"true\" width-chars=\"34\" use-markup=\"true\">
        <label>
\"<i>The package <b>$pkg</b> is not yet installed</i>\"
        </label>
      </text>
      <button>
        <input file icon=\"go-jump\"></input>
	<label>Install</label>
	<action>[ -f /var/lib/tazpkg/packages.list ] || tazpkg recharge</action>
	<action>xterm -fa MiscFixed -fs 11 -bg gray93 -fg black -geometry 80x17 -title \"$pkg install\" -e \"$tmp2 ; sleep 2\"</action>
        <action type=\"exit\">restart</action>
      </button>
      </hbox>
    </frame>
"
  fi
  BOOT_DIALOG="$BOOT_DIALOG$tmp"
done <<EOT
SmartBtmgr /usr/share/boot/btmgr btmgr This OS independent Smart Boot Manager can boot \\\\nany partition or ATAPI CD-ROM.
Plop /usr/share/boot/plpbt.bin plop This non free Boot Manager can boot a floppy disk, hardisk, USB or \\\\nCD/DVD. Hit Ctrl-ESC for text mode.
Etherboot /usr/share/boot/etherboot etherboot This network bootloader provides a replacement \\\\nfor proprietary PXE or NBI ROMs.
gPXE /boot/gpxe gpxe PXE / iSCSI / AoE network bootloader.
Memtest86+ /usr/share/boot/memtest.lzma memtest Memory failures detection tool.
Grub4DOS /usr/share/boot/grldr.lzma grub4dos Enhanced grub version supporting NTFS.
Grub /usr/sbin/grub grub General purpose boot loader with command shell.
EOT
tmp='
    </notebook>
    <hbox>
'
BOOT_DIALOG="$BOOT_DIALOG$tmp"
if [ -e /dev/cdrom ]; then
tmp='
      <button>
        <input file icon="media-cdrom"></input>
	<label>Burn cdrom image</label>
	<action>burnbox</action>
      </button>
'
BOOT_DIALOG="$BOOT_DIALOG$tmp"
fi
if list_floppy check; then
tmp='
      <button>
        <input file icon="media-floppy"></input>
	<label>Manage floppy image</label>
	<action type="launch">FLOPPY_IMAGE</action>
      </button>
'
BOOT_DIALOG="$BOOT_DIALOG$tmp"
fi
tmp='
      <button>
        <input file icon="exit"></input>
	<label>Exit</label>
        <action type="exit">Exit</action>
      </button>
    </hbox>
  
  </vbox>
</window>
'
BOOT_DIALOG="$BOOT_DIALOG$tmp"
export BOOT_DIALOG

# Only root can create floppy.
check_root
gtkdialog --program=BOOT_DIALOG | grep -q 'EXIT="restart"' && continue
rm -f /tmp/floppybox.grub.menu
exit 0
done
