#!/bin/bash

make_install=1
make_rescue=
make_live=
make_memtest=
make_mbr=
boot_only=
home_size=
image=
force=
verbose=
quiet=
iso_path=/media/cdrom



exit_handler() {
	        local rc=$?
		trap - EXIT
		rm -rf -- "$workdir"
		if [ "$mpoint" ] ; then 
                        umount $live_point/lib &>/dev/null
			umount $live_point/tmp &>/dev/null
			umount $live_point/proc &>/dev/null
			umount $live_point/sys &>/dev/null
			umount $live_point &> /dev/null
			rmdir -- "$live_point"
			say "syncing..."
			sync
			umount $mpoint &> /dev/null
			rmdir -- "$mpoint"
		fi
		exit 
	}

trap exit_handler HUP PIPE INT QUIT TERM EXIT

die(){
	echo $1
	exit
}

say(){
	if [ "$verbose" ] ; then echo $1; fi
}

show_help() {
    [ -z "$*" ] || Info "$*"
        cat <<EOF
mkbootflash - make FAT fromatted USB storage suitable to initiate 
              network installation or be usable as rescue or live system.

Usage: mkbootflash [options] <path-to-device>
    -i, --install            make install image (default)
    -r, --rescue             make rescue image
    -l, --live               make live image
    -m, --memtest            make memtest image
    -M, --MBR                write mbr
    -s, --size               size of home partition image in 512 bytes blocks
    -f, --force              force home image creation
    -b, --boot-only          don't copy images, do boot stuff only
    -p, --path		     path to a directory with rescue and/or live 
                             squashfs images
    -v, --verbose            print a message from each action
    -V, --version            print program version and exit
    -h, --help               show this text and exit

Report bugs to http://bugzilla.altlinux.org/

EOF
exit
}

TEMP=`getopt -n mkbootflash -o M,i,v,r,q,V,h,l,p:,s:,f,m,b -l install,rescue,live,verbose,version,quiet,help,path:,size:,force,memtest,MBR,boot-only -- "$@"` || show_help


eval set -- "$TEMP"

while :; do
	case "$1" in
		-i|--install) make_install=1
		;;
		-r|--rescue)  make_rescue=1 
		;;
		-l|--live)  make_live=1 
		;;
		-m|--memtest)  make_memtest=1
		;;
		-M|--MBR)  make_mbr=1
		                 ;;
		-p|--path)  shift
		            iso_path=$1
		;;
		-s|--size)  shift
                            home_size=$1
                            ;;
                -f|--force) force=-v
                ;;
		-b|--boot-only) boot_only=1
                ;;
	        -v|--verbose) verbose=-v
		;;
		-q|--quiet) quiet=1
		;;
		-h|--help) show_help
		;;
		--) shift; break
		;;

	esac
	shift
done

if [ "$make_rescue" -o "$make_live" ] ; then
	image=rescue
	if [ "$make_live" ] ; then
		image=live
	fi
fi

# Exactly one argument, please.
[ "$#" -ge 1 ] || show_help 'Insufficient arguments.'
[ "$#" -le 1 ] || show_help 'Too many arguments.'

device=$1
mpoint=`mktemp -d -t mkbootflash-mount.XXXXXXXXXX`
live_point=`mktemp -d -t mkbootflash-image.XXXXXXXXXX`
workdir=`mktemp -d -t mkbootflash-work.XXXXXXXXXX`
cd $workdir || die "can't chdir"


mount $device $mpoint || die "can't mount"
if [ -d "$iso_path/isolinux" ] ; then
     rsync -a --no-o $verbose "$iso_path/isolinux/" $mpoint/syslinux/ || die "can't copy $iso_path/isolinux to $mpoint"
else
     rsync -a --no-o $verbose "$iso_path/syslinux/" $mpoint/syslinux/ || die "can't copy $iso_path/syslinux to $mpoint"
fi




cat > $mpoint/syslinux/syslinux.cfg <<-EOF
TIMEOUT 100
GFXBOOT bootlogo
PROMPT 1
IMPLICIT 1
DEFAULT linux 

LABEL linux
KERNEL alt0/vmlinuz 
APPEND initrd=alt0/full.cz lang=ru_RU ramdisk_size=65536 splash=silent showopts
EOF

UUID=`/sbin/blkid | grep $device | sed -e 's/.*UUID=\"\([^"]*\)*\".*/\1/'`

if [ $make_rescue ] ; then
	    echo "making rescue syslinux.cnf"
	    if [ ! $boot_only ] ; then
	         rsync -a --no-o --inplace $verbose $iso_path/rescue $mpoint
	    fi
	    cat >> $mpoint/syslinux/syslinux.cfg <<-EOF

LABEL rescue
KERNEL alt0/vmlinuz
APPEND initrd=initrd.img rootdelay=10 lang=ru_RU root=UUID=$UUID fastboot stagename=rescue showopts
EOF

subst 's/DEFAULT.*/DEFAULT rescue/'  $mpoint/syslinux/syslinux.cfg 
fi

if [ $make_live ] ; then
		say "copyng live image"
		if [ ! $boot_only ] ; then
		      cp $verbose $iso_path/live $mpoint
	        fi
		say "making live syslinux.cnf"
		cat >> $mpoint/syslinux/syslinux.cfg <<-EOF

LABEL live
KERNEL alt0/vmlinuz 
APPEND initrd=initrd.img rootdelay=10 lang=ru_RU root=UUID=$UUID fastboot stagename=live splash=silent showopts
EOF

subst 's/DEFAULT.*/DEFAULT live/'  $mpoint/syslinux/syslinux.cfg
fi

if [ $make_memtest ] ; then
	say "making memtest syslinux.cnf"
	cat >> $mpoint/syslinux/syslinux.cfg <<-EOF

LABEL memtest
KERNEL memtest 
EOF
fi

if [ "$make_rescue" -o "$make_live" ] ; then

	if [ "$home_size" ] ; then
		if [ ! -r $mpoint/home ] || [ "$force" ] ; then
			say "making fs image for home"
			dd if=/dev/zero of=$mpoint/home count=$home_size
			mkfs.ext3 -F $mpoint/home
			mount -o loop $mpoint/home $live_point || 
			die "Can't mount $mpoint/home to $live_point"
			mkdir $live_point/altlinux
			rsync -r /etc/skel/ $live_point/altlinux/
			chown -R 500:500 $live_point/altlinux
			mkdir $live_point/mnt
			umount $live_point
		fi
	fi

mkdir $workdir/union

say "making initrd"
mount -o loop -t squashfs $mpoint/$image $live_point ||
      die "Can't mount $image to $live_point"
mount -t unionfs -o dirs=$workdir/union=rw:$live_point/lib=ro $workdir/union $live_point/lib
mount -o bind $workdir $live_point/tmp ||
      die "Can't mount  $workdir to $live_point/tmp"
mount -o bind /proc $live_point/proc ||
      die "Can't mount  /proc to $live_point/proc"

kernel_rel=`ls $live_point/lib/modules/ | head -n 1`


cp /sbin/mkinitrd ./
subst 's/usb_storage//' ./mkinitrd
subst 's/fbresolution=.*/fbresolution=800x600/'  ./mkinitrd

cp /lib/mkinitrd/initramfs-base/init ./

cat > ./init.patch <<-EOF
--- init   2007-03-29 20:51:08 +0400
+++ init 2007-08-03 11:11:03 +0400
@@ -45,6 +45,9 @@
        root=*)
                ROOT=\${x#root=}
                ;;
+    stagename=*)
+           STAGE=\${x#stagename=}
+               ;;
        rootflags=*)
                ROOTFLAGS="-o \${x#rootflags=}"
                ;;
EOF
patch -l -p0 <init.patch


cp /lib/mkinitrd/initramfs-base/scripts/local ./
cat > ./local.patch << 'EOF'
--- local  2007-03-29 20:51:08 +0400
+++ local        2007-08-03 11:11:03 +0400
@@ -109,7 +109,7 @@
 	modprobe -qb ${FSTYPE}
 
 	# Mount root
-	mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} || {
+	mount -o rw,iocharset=utf8 -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /loopfs || {
 		[ "${FSTYPE}" = "ext3" ] && {
 			log_warning_msg "Trying to mount $ROOT as ext2 instead of ext3"
 			modprobe -qb ext2
@@ -118,5 +118,16 @@
 	} ||
 		panic "Unable to mount $ROOT as $FSTYPE.  Dropping to a shell!"
 
+	losetup /dev/loop1 /loopfs/$STAGE
+	mount -t squashfs  /dev/loop1 /root
+	echo "root mounted"
+	mount -o bind /loopfs /root/image
+	echo "image mounted"
+	if [ -r /loopfs/home ] ; then
+			losetup /dev/loop2 /loopfs/home
+			mount -t ext3 -o rw /dev/loop2 /root/home
+			echo "home mounted"; 
+	fi
+
 	run_scripts /scripts/local-bottom
 }
EOF
patch -l -p0 <local.patch

cp /etc/udev/initramfs-rules.d/60-persistent-storage.rules $workdir
cat > ./udev.patch <<-EOF
--- 60-persistent-storage.rules     2007-03-29 23:36:53 +0400
+++ 60-persistent-storage.rules 2007-08-06 17:49:56 +0400
@@ -53,7 +53,6 @@
 KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/\$env{ID_PATH}-part%n"
 
 # by-label/by-uuid (filesystem properties)
-KERNEL=="*[!0-9]", ATTR{removable}=="1", GOTO="persistent_storage_end"
 IMPORT{program}="vol_id --export \$tempnode"
 ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/\$env{ID_FS_UUID}"
 ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/\$env{ID_FS_LABEL_SAFE}"
EOF
patch -l -p0 <udev.patch

if [ -r $live_point/lib64 ] ; then
	libdir='/lib64'
	ldso='/lib64/ld-linux-x86-64.so.2'
else
	libdir='/lib'
	ldso='/lib/ld-linux.so.2'
fi

TMPDIR=/tmp chroot $live_point /tmp/mkinitrd $verbose --with usb-storage -v --with nls_koi8-r --with nls_cp866 --with nls_utf8 --with vfat --with ext3 --with ehci-hcd --with hci_usb --with usbhid --with uhci_hcd --with ehci_hcd --with squashfs --with loop --add /sbin/losetup=/sbin/losetup --add $libdir/libc.so.6=$libdir/libc.so.6 --add $ldso=$ldso --add /scripts/local=/tmp/local --add /etc/udev/rules.d/60-persistent-storage.rules=/tmp/60-persistent-storage.rules --add /init=/tmp/init /tmp/initrd.img  $kernel_rel

rsync $verbose --no-o initrd.img $mpoint/syslinux/

fi

if [ "$make_mbr" ] ; then
boot_device=`echo $device | sed 's/[0-9]*$//'` 
part_number=`echo $device | sed 's,[/a-z]*,,'`


dd if=/usr/lib/syslinux/mbr.bin of=$boot_device
sfdisk "$boot_device" -A $part_number
fi 

syslinux $device 
