#!/bin/bash

# Copyright (C) 2006-2008 EMAC, Inc.

# Version 3.2

# 20070711 - GMB - Fixed USB target device.
# 20080620 - GMB - 
# 20080926 - GMB - Added fix for boot flash missing target device which will
# happen in cases of large numbers of sd nodes on the host computer.
# 20081210 - GMB - Replaced "exit" with "return". Added option to change fstab
# on the target flash.
# 20081210 - GMB - Fixed fstab file on target flash to match the boot device.
# Decided this change was worth a minor increment as it eliminates a possible
# test step.
# 20090615 - GMB - Added check for root.

# TARBALL   - Name of the initial IMAGEPATH.
# TARGET    - Name of the target device.
# IMAGEPATH - Full path name of the tarball.
# MOUNT     - Mount point for flash.

MOUNT=/mnt

# Change this 
#USBDEV=/dev/sdc
#BOOTDEV=/dev/hdc

#TIMESTART=`date2stamp -now`

fail() {
	if [ "${TARBALL}" = "" ]
	then
		echo "Flash failed."
	else
		echo "Flashing of ${TARBALL} failed."
	fi

    failure
    return
}

usage() {
SCRIPTNAME=`basename $0`
cat << !USAGE!

Usage: $SCRIPTNAME [OPTION] image_archive

Copies and activates partition of an EMAC Linux ext3 file system tarball
archive to a USB CompactFlash adapter. This script assumes the tarball
contains a single partition to go on the first parition of the device.

NOTE: THIS SCRIPT MUST BE RUN AS ROOT AND CAN BE DANGEROUS TO USE! It will
      destroy the master boot record of the device specified. Make sure you
      have a backup of your hard drive before proceeding!

    --help - Shows this help context (or if no arguments specified).
    --boot=<device_node>   - Selects device_node as the boot device.
                             If not specified the default is $BOOTDEV
    --target=<device_node> - Chooses the specified flash device node as the
                             target to copy to.
                             If not specified the default is $USBDEV

    image_archive - must be in the local directory or a full qualified paths
                    name.

Example:

	${SCRIPTNAME} --target=/dev/sdd --boot=/dev/hdc emac_image.tar.gz

!USAGE!
    exit 1
}

pause()
{
    echo Press Enter to Continue
    read TOSS
}

function success()
{
    beep -f 1200 -l 150
    beep -f 1300 -l 200
    beep -f 1400 -l 150
    beep -f 1300 -l 200
    beep -f 1200 -l 150
    #beep -f 1500 -l 1250
}

function failure()
{
	beep -f 196.00 -l 175 -d 1000
	beep -f 174.61 -l 150 -d 1000
	beep -f 164.81 -l 125 -d 1000
	beep -f 196.00 -l 175 -d 1000
	beep -f 174.61 -l 150 -d 1000
	beep -f 164.81 -l 125 -d 1000
	beep -f 196.00 -l 175 -d 1000
	beep -f 174.61 -l 150 -d 1000
	beep -f 164.81 -l 125 -d 1000
}

if [ "$1" == "" ] || [ "$1" = "--help" ]
then
    usage
fi

if [[ $UID != 0 ]]
then
    echo "------------------------"
    echo "!!! You are not root !!!"
    echo "------------------------"
    usage
    exit 0
fi


while [ "$1" ]
do
	# Clean up the flags.
	FLAG=`echo $1 | sed 's/=.*//'`
	ARG=`echo $1 | sed 's/.*=//'`
	#echo FLAG = $FLAG
	#echo ARG = $ARG

    case "$FLAG" in
		'--target')
			[[ "${TARGET}" != "" ]] && echo "Multiple targets not allowed." && fail
			[[ `grep '${TARGET}' /proc/mounts` ]] && echo "Target must not be mounted." && fail
			TARGET=$ARG
			;;
		'--boot')
			[ "${BOOT}" != "" ] && echo "Multiple boot devices not allowed." && fail
			BOOT=$ARG
			;;
		*)
			TARBALL=$ARG
			;;
    esac
	
    shift

done

#if [ $BOOT = "" ] && $BOOT = $BOOTDEV 
#if [ $TARGET = "" ] && echo $TARGET = $USBDEV

#echo BOOT = $BOOT
#echo TARGET = $TARGET
#echo TARBALL = $TARBALL

#pause

if [ "${BOOT}" == "" ]
then
    echo "Boot device not specified."
	fail
    #exit 1
fi

if [ "${TARGET}" == "" ]
then
    echo "Target device not specified."
	fail
    #exit 1
fi

if [ ! -f $TARBALL ] || [ "$TARBALL" == "" ]
then
	echo "Must supply a valid, complete file/pathname!"
	fail
fi

if [ "x`basename $TARBALL`" == "x$TARBALL" ]
then
	IMAGEPATH="`pwd`/$TARBALL"
else
	IMAGEPATH="$TARBALL"
fi

# Make sure the device has settled. Need a loop to check this.
sleep 2

umount ${TARGET}1
# Too dangerous!!! 
#dd if=/dev/zero of=/dev/sda bs=1k count=2 || fail
# ONLY zero the MBR!
dd if=/dev/zero of=$TARGET count=1 || fail

/sbin/sfdisk -uM -D $TARGET <<EOF 
0,,83,*
,,,
,,,
,,,
w
EOF

/sbin/mkfs.ext3 ${TARGET}1 || fail

# Generate a TARGET directory in /mnt.
if [ ! -d ${TARGET}1 ]
then
    mkdir -p $MOUNT/`basename ${TARGET}1`
fi

mount -t ext3 ${TARGET}1 $MOUNT/`basename ${TARGET}1` || fail

#pause

#cp -f lilo.conf.usb /tmp

cd $MOUNT/`basename ${TARGET}1` || fail
#echo `pwd`

#echo $IMAGEPATH
#pause

tar zxvf $IMAGEPATH || fail

# Custom lilo setup.

#LILOCONF="lilo.conf.usb"
NODE=`basename ${TARGET}`

for liloconf in "lilo.conf" "lilo.conf.hdc" "lilo.conf.hda" "lilo.conf.cf" "lilo.conf.usb"
do
    foundconf=false
    lilotest="${MOUNT}/`basename ${TARGET}`1/etc/$liloconf"
    if [ -f "$lilotest" ]
    then
        LILOCONF=$lilotest
        foundconf=true
        break
    fi
done

if [ "$foundconf" = "true" ]
then
    echo Using LILO configuration: $LILOCONF
else
    echo No suitable LILO configuration file found to use.
    echo This should NOT happen. Fix the archive then try again.
    fail
fi

#LILOCONF="${MOUNT}/`basename ${TARGET}`1/etc/lilo.conf.usb"
#LILOCONF=/tmp/lilo.conf.usb
#cp -f /tmp/lilo.conf.usb ${LILOCONF}
cp -f ${LILOCONF} /tmp/lilo.conf
cp -f ${LILOCONF} /tmp/lilo.conf.boot
#sed -i -e "s|disk=.*$|&${TARGET}|" -e "s|boot=.*$|&${TARGET}|" -e "s|root=.*$|&${BOOT}1|" /tmp/lilo.conf
sed -i -e "s|\(disk=\).*$|\1${TARGET}|" -e "s|\(boot=\).*$|\1${TARGET}|" -e "s|\(root=\).*$|\1${BOOT}1|" /tmp/lilo.conf
sed -i -e "s|\(disk=\).*$|\1${BOOT}|" -e "s|\(boot=\).*$|\1${BOOT}|" -e "s|\(root=\).*$|\1${BOOT}1|" /tmp/lilo.conf.boot
echo "Custom ${LILOCONF} created."

cp -f /tmp/lilo.conf ${MOUNT}/`basename ${TARGET}`1/etc/lilo.conf
echo "$MOUNT/`basename ${TARGET}`1/sbin/lilo -v -r $MOUNT/`basename ${TARGET}`1"

# Some crazy stuff here that I do not remember why I did it, but required to
# work correctly.
mv $MOUNT/`basename ${TARGET}`1/tmp $MOUNT/`basename ${TARGET}`1/tmp.tmp
mkdir -p $MOUNT/`basename ${TARGET}`1/tmp

# Make sure there are target device nodes for LILO on the boot flash.
if [ ! -e "$MOUNT/`basename ${TARGET}`1${TARGET}" ]
then
    CREATENODES="true"
    cp -a ${TARGET} $MOUNT/`basename ${TARGET}`1/dev
    cp -a ${TARGET}1 $MOUNT/`basename ${TARGET}`1/dev
fi

# Old LILO command.
###$MOUNT/`basename ${TARGET}`1/sbin/lilo -v -r $MOUNT/`basename ${TARGET}`1 || fail

chroot $MOUNT/`basename ${TARGET}`1 /sbin/lilo

rmdir $MOUNT/`basename ${TARGET}`1/tmp
mv $MOUNT/`basename ${TARGET}`1/tmp.tmp $MOUNT/`basename ${TARGET}`1/tmp

# Make sure the are target device nodes for LILO on the boot flash are removed.
if [ "$CREATENODES" == "true" ]
then
    rm -f $MOUNT/`basename ${TARGET}`1${TARGET}
    rm -f $MOUNT/`basename ${TARGET}`1${TARGET}1
fi

# Set lilo for correct operation on the boot device.
cp -f /tmp/lilo.conf.boot ${MOUNT}/`basename ${TARGET}`1/etc/lilo.conf


target="$MOUNT/`basename ${TARGET}`1"
# Fix for the target fstab entry (probably changed).
#baddevice=`grep " / " fstab | grep -v "^#" | awk '{ print $1 }'`; grep " / " fstab | grep -v "^#" | sed "s|${baddevice}|test|"
#newroot=/dev/newroot1; oldroot=`grep " / " /tmp/sib/etc/fstab | grep -v "^#" | awk '{ print $1 }'`; echo $oldroot; sed "s|^${oldroot}|${newroot}|" /tmp/sib/etc/fstab
oldroot=`grep " / " $target/etc/fstab | grep -v "^#" | awk '{ print $1 }'`
if [ "${oldroot}" == "" ]
then
    echo "Unable to write out $target/etc/fstab root entry."
    echo
    echo "Make sure that $target/etc/fstab is set up correctly before sending"
    echo "to the customer!"
else
    sed -i "s|^${oldroot}|${BOOT}1|" $target/etc/fstab
    echo "Root /etc/fstab has been configured."
fi


sleep 2
cd ..
umount ${TARGET}1 || fail
echo -e "Restore of '`basename $TARBALL`' completed.\a"

success

# Get the finishing time.
#TIMEEND=`date2stamp -now`

#STARTDATE=`stamp2date $TIMESTART`
#ENDDATE=`stamp2date $TIMEEND`

#TIME_SEC=`datediff -s $STARTDATE $ENDDATE`
#TIME_MIN=$(($TIME_SEC/60))

# Dialog menu goes here:

###	echo -n "Flashing completed in "
###	#if [ $TIME_MIN -gt 60 ]
###	#then
###	    #TIME_HR=$(($TIME_MIN/60))
###	    #echo -n "$TIME_HR hour"
###	    #[ $TIME_HR -gt 1 ] && echo -n "s"
###	#fi
###	if [ $TIME_MIN -gt 0 ]
###	then
###	    #[ $TIME_HR -gt 0 ] && echo " "
###	    TIME_SEC=$(($TIME_SEC%60))
###	    echo -n "$TIME_MIN minute"
###	    [ $TIME_MIN -gt 1 ] && echo -n "s"
###	fi
###	[ $TIME_SEC -gt 0 ] && echo -n " $TIME_SEC second"
###	[ $TIME_SEC -gt 1 ] && echo -n "s"
###	echo "."

#msgtxt="Process completed in "
#if [ $TIME_MIN -gt 60 ]
#then
    #TIME_HR=$(($TIME_MIN/60))
    #echo -n "$TIME_HR hour"
    #[ $TIME_HR -gt 1 ] && echo -n "s"
#fi
#if [ $TIME_MIN -gt 0 ]
#then
    #[ $TIME_HR -gt 0 ] && echo " "
#    TIME_SEC=$(($TIME_SEC%60))
#    msgtxt="${msgtxt}$TIME_MIN minute"
#    [ $TIME_MIN -gt 1 ] && msgtxt="${msgtxt}s"
#fi
#[ $TIME_SEC -gt 0 ] && msgtxt="${msgtxt} $TIME_SEC second"
#[ $TIME_SEC -gt 1 ] && msgtxt="${msgtxt}s"
#msgtxt="${msgtxt}."

#echo ${msgtxt}
pause

#return

