#!/bin/sh
# use gainroot to become root and relaunch itself
if [ `id -u` != 0 ] ; then
#if not already root, call itself as root
TTY=`tty`
[ "$TTY" = "not a tty" ] && unset TTY
exec sudo gainroot <<EOF
if [ -z "$TTY" ] ; then exec $0 $* ; else exec <$TTY $0 $* ; fi
EOF
exit $?
fi
# real script follows

OLDDIR=`pwd`
cd `dirname $0`
MYDIR=`pwd`

case $MYDIR in
    /media/mm*)
	echo "Cannot run from FAT formatted card, real UNIX filesystem is needed."
	echo "Please extract archive directly to internal flash and run from there."
	exit 0
	;;
esac

INITFS_IMAGE=initfs.bootmenu.jffs2
INITFS_MAX_SIZE=$((0x0`grep initfs /proc/mtd | cut -d ' ' -f 2`))

ask_no(){
ans=
while [ "$ans" = "" ] ; do
    echo -n "$*"
    read ans
done
case $ans in
    y*|Y*)
	return 1
	;;
    *)
	return 0
	;;
esac
}
ask_yes(){
ask_no "$*" && return 1
return 0
}


initfs_create_backup(){
#echo " *** copying current initfs ..."
##mkdir -p initfs
##rsync -aHx --delete /mnt/initfs/ initfs/
mkdir -p initfs
mount -t jffs2 -o ro /dev/mtdblock3 initfs
echo " *** creating $1 ..."
$MYDIR/mkfs.jffs2 -r initfs -o $1 -e 128 -l -n
umount initfs
rm -rf initfs		
}

initfs_create(){
echo -n " *** copying current initfs ..."
#mkdir -p initfs
#rsync -aHx --delete /mnt/initfs/ initfs/
mkdir -p mnt
mount -t jffs2 -o ro /dev/mtdblock3 mnt
cp -a mnt initfs
umount mnt
rmdir mnt
echo " done."

echo "If you remove extra stuff you may write to initfs and customize bootmenu."
if ask_yes "Remove unneeded extra (and factory testing) stuff? (yes/no) : " ; then
	echo " *** removing extra stuff ..."
	for i in `cat $MYDIR/to_remove.lst` ; do rm -rf initfs/$i ; done
fi

INITFSVERSION=`cut -d ' ' -f 1,2 initfs/etc/initfs_version  | tr ' ' '.'`
if [ -f $MYDIR/initfs.${INITFSVERSION}.tgz ] ; then
    echo " *** extracting boot menu files for initfs version ${INITFSVERSION} ..."
    tar zxvf $MYDIR/initfs.${INITFSVERSION}.tgz -C initfs
    if [ -f $MYDIR/bootmenu.sh ] ; then
    	echo " *** copying bootmenu.sh"
	cp $MYDIR/bootmenu.sh initfs/
	chown root:root initfs/bootmenu.sh
    fi
    #telnetd
    if [ -f $MYDIR/utelnetd.${INITFSVERSION}.tgz ] ; then
	if ask_yes "install telnet server for network recovery? (yes/no) " ; then
		tar zxvf $MYDIR/utelnetd.${INITFSVERSION}.tgz -C  initfs
		echo " *** OK, utelnetd added"
	else
		echo " *** OK, utelnetd skipped"
	fi	   
	
    fi
    #dropbear
    if [ -f $MYDIR/dropbear.${INITFSVERSION}.tgz ] ; then
	if ask_yes "install dropbear ssh server for advanced network recovery? (yes/no) " ; then
		tar zxvf $MYDIR/dropbear.${INITFSVERSION}.tgz -C  initfs
		echo " *** OK, dropbear added"
		if [ -f /etc/dropbear/dropbear_rsa_host_key ] ; then
		echo " *** dropbear found in rootfs, copying server keys to initfs"
		mkdir -p initfs/etc/dropbear
		cp -a /etc/dropbear/dropbear_*_key initfs/etc/dropbear/
		else
		echo " *** no dropbear in rootfs, server keys will be generated on each boot"
		fi
	else
		echo " *** OK, dropbear skipped"
	fi	   
	
    fi
	# check previous bootmenu.conf
	if [ -f initfs/bootmenu.conf ] ; then
		echo " *** previous bootmenu installation with custom bootmenu.conf found, keeping it"
		Q="bootmenu.conf found, do you want to add it to initfs and overwrite previous one? (yes/no) "
	else
		Q="bootmenu.conf found, do you want to add it to initfs? (yes/no) "
	fi
    echo " *** searching for optional bootmenu.conf in current directory ..."
    if [ -f bootmenu.conf ] ; then
	if ask_yes $Q ; then
		cp bootmenu.conf initfs/
		echo " *** OK, bootmenu.conf added"
	else
		echo " *** OK, bootmenu.conf ignored"
	fi	   
    else
    	echo " *** not found, no problem"
    fi
    echo " *** creating $1 ..."
    $MYDIR/mkfs.jffs2 -r initfs -o $1 -e 128 -l -n
else
    echo " !!! unknown initfs version ${INITFSVERSION}, cannot install bootmenu"
fi
rm -rf initfs		
}

initfs_flash(){
sync
echo -n " *** remounting initfs read only ... "
#mount -o remount,ro /dev/mtdblock3 /mnt/initfs || return 1
#workaround buggy bysybox mount in N800, the line above fails
#we can also use mount inside initfs
chroot /mnt/initfs mount -t jffs2 -o remount,ro /dev/mtdblock3 /
#ignore mount return code and check if initfs is now mounted ro
INITFSMODE=`grep '/mnt/initfs jffs2' /proc/mounts | cut -d ' ' -f 4`
if [ ! "$INITFSMODE" = "ro" ] ; then
	echo "failed, flashing skipped"
	return 1
else
	echo "OK"
fi
sync
echo " *** caching old initfs to memory (for crash prevention)"
# block level, probably useless
dd if=/dev/mtdblock3 of=/dev/null bs=65536 2>/dev/null
# file level, read all interesting stuff (should be enough to cache dsme and bme)
tar cf - /mnt/initfs/usr /mnt/initfs/lib /mnt/initfs/bin /mnt/initfs/sbin >/dev/null 2>/dev/null
echo " *** erasing initfs partition (/dev/mtd3) ..."
$MYDIR/flash_eraseall -j /dev/mtd3
echo " *** flashing $1 image ..."
$MYDIR/nandwrite -a -p /dev/mtd3 $1
echo " *** done"
return 0
}

renameprevious(){
FROM=$1
if [ -f $FROM ] ; then
    TO=${FROM}.`ls -l $FROM | awk ' { print $6$7$8 }' | tr -d '.:-'`
    echo "Previous $FROM detected, renamed to $TO"
    mv $FROM $TO
fi
}


wizard(){

echo ""
echo " === Flasher for initfs with onscreen bootmenu ==="
echo ""
echo "For safe flashing please do the following:"
echo ""
echo "- close all aplications (to free available RAM and prevent system crash)"
echo "- disconnect from wi-fi network (to prevent random system crash with N770)"
echo "- make sure you have at least 5MB free disk space in flasher directory"
echo "- make sure you know how to reflash device in usual way if this fails"
echo ""

if ask_no "Are you sure to continue? (yes/no) : " ; then
    echo "OK, see you later :-)"
    exit 0
fi

if ask_yes "Create backup of current initfs (yes/no) : " ; then
    renameprevious initfs.orig.jffs2
    initfs_create_backup initfs.orig.jffs2
    ls -l initfs.orig.jffs2
    echo "Press enter to continue"
    read ans
fi

echo "Part 1 - Preparing ${INITFS_IMAGE} image"
renameprevious $INITFS_IMAGE
initfs_create ${INITFS_IMAGE}
if [ -f ${INITFS_IMAGE} ] ; then

ls -l ${INITFS_IMAGE}
imgsize=`ls -l ${INITFS_IMAGE} | awk '{ print $5 }'`
if [ $imgsize -gt ${INITFS_MAX_SIZE} ] ; then
    echo "Oversized image, max size is $INITFS_MAX_SIZE actual is $imgsize"
    echo "Please select different options next time." 
    exit 0
fi
echo ""
if ask_no "Part 2 - Ready for flashing this image? (yes/no) : " ; then
    echo "OK, see you later :-)"
    exit 0
fi

initfs_flash ${INITFS_IMAGE}
echo "Press enter to reboot device (or ctrl+c to quit, not recommended)"
read ans
echo "Rebooting ..."
shutdown -r now
else
echo "Cannot find ${INITFS_IMAGE}, something failed, nothing flashed."
fi
}

#this flashes initfs image directly, usable for backup or prepared image
flasher(){
if ask_no "Ready to flash initfs jffs2 image $1? (yes/no) : " ; then
    echo "OK, see you later :-)"
    exit 0
fi
initfs_flash $OLDDIR/$1
echo "Press enter to reboot device (or ctrl+c to quit, not recommended)"
read ans
shutdown -r now
}


if [ "$#" = "1" -a -f "$OLDDIR/$1" ] ; then
	if [ "`basename $1 .jffs2`.jffs2" != "`basename $1`" ] ; then
	    echo "$1 has no .jffs2 suffix !"
	    echo "Cowardly refusing to brick your device :-)"
	    exit 0
	fi
	flasher "$1"
else
	wizard
fi
