#!/bin/sh
#
# Make USB key to save/restore HW configuration on a ProLiant DL 380 G7
#
#set -x
#
# Usage: ./mkusbkey.sh <device>
#
# <device> usually points to a USB pendrive (i.e. /dev/sdb) but it can also
# be a /dev/loop* device attached to a standard file
# $ dd if=/dev/zero of=/tmp/usbdev.img bs=1M count=400
# $ losetup -vf /tmp/usbdev.img
#
# Will associate usbdev.img to /dev/loop0 in most cases
# $ ./mkusbkey.sh /dev/loop0
#
# will create the bootable USB in usbdev.img file which can be dd'ed on a 
# USB pendrive

# Partition size in MB that will be created on the device
[ -f '/etc/setupkey.conf' ] && . '/etc/setupkey.conf'

[ -z "$PARTITION_SIZE" ] && PARTITION_SIZE=400

if [ ! -f "$DATA/ext3fs.img" ]; then
	echo "Cannot find the ext3fs.img file system image"
	echo "Please run 'rpmbootstrap.sh' script before running $0"
	exit 1
fi

if [ ! -f "$DATA/initramfs.img" ]; then
	echo "Cannot find the initramfs.img initial RAM disk image."
	echo "Please run 'rpmbootstrap.sh' script before running $0"
	exit 1
fi

if [ ! -f "$DATA/vmlinuz" ]; then
	echo "Cannot find the boot kernel."
	echo "Please run 'rpmbootstrap.sh' script before running $0"
	exit 1
fi

MBR=/usr/share/syslinux/mbr.bin

if [ ! -f "$MBR" ]; then
	echo "Outch! Cannot find $MBR. That should not happen!"
	echo "Check 'syslinux' is installed, find where the 'mbr.bin' file is located and update the \$MBR variable in $0 accordingly." 
	exit 2
fi

sync
DRIVE=$1
[ -z $DRIVE ] && echo "Usage: $0 device." && exit -1
[ ! -b $DRIVE ] && echo "$1 is not a block device. Exiting." && exit -1
KPARTX=`which kpartx`
[ $? -ne 0 ] && echo "kpartx is missing. exiting" && exit -1
SYSLINUX=`which syslinux`
[ $? -ne 0 ] && echo "syslinux is missing. exiting" && exit -1


[[ $DRIVE == /dev/sda* ]] && echo "For security, the script does not work on /dev/sda* devices" && exit -1

[[ `cat /proc/mounts | grep $DRIVE` != "" ]] && echo "$DRIVE is mounted. Exit now." && exit -1

# Wipe the partition table.
dd if=/dev/zero of=$DRIVE bs=4096 count=1 > /dev/null 2>&1
[ $? -ne 0 ] && echo "WARNING: Unable to erase MBR on $DRIVE."
sync

# Create partition
echo "Creating the partition on $DRIVE"
sfdisk -uM -q $DRIVE 2>/dev/null << EOF
0,$PARTITION_SIZE,b,*
EOF
sync
[ $? -ne 0 ] && echo "Unable to partition the key $DRIVE. Exiting" && exit -1
sfdisk -q -R $DRIVE 2>/dev/null

sync
if [ ! "${DRIVE##/dev/loop*}" = "$DRIVE" ]; then
	echo "Loopback device detected. Special handling required"
	$KPARTX -d $DRIVE
	$KPARTX -a $DRIVE
	PART="/dev/mapper/${DRIVE#/dev/}p1"
else
	PART=${DRIVE}1
fi

echo "Creating the master boot record on $DRIVE"
dd if=$MBR of=$DRIVE > /dev/null 2>&1
[ $? -ne 0 ] && echo "Unable to copy MBR on $DRIVE. Please check the key. Exiting" && exit -1

# FAT32 filesystem labeled 'LiveUSB'
sync
echo "Creating FAT filesystem on $PART"
mkfs.vfat -n LiveUSB $PART > /dev/null
[ $? -ne 0 ] && echo "Unable to format the partition $PART as VFAT. Exiting" && exit -1
sync

TMPDIR=`mktemp -d /tmp/mkusb.XXXX`
if [ ! -d "$TMPDIR" ]; then
	echo "$TMPDIR is not a directory. Exiting"
	exit -1
else
	if [[ "$TMPDIR" == "/" ]]; then
		echo "$TMPDIR is /. Exiting"
		exit -1
	fi
fi

ret=0
mount $PART $TMPDIR
if [ $? -ne 0 ] ; then
	echo "Unable to mount $PART under $TMPDIR. Exiting" 
	ret=1
else
	# The SQUASHFS containing the EXT3 filesystem with the
	# minimum OS and the SSTK tools
	SQUASHFS=$(mktemp -d /tmp/squashfs.XXXX)
	mkdir $SQUASHFS/LiveOS
	dd if=$DATA/ext3fs.img of=$SQUASHFS/LiveOS/ext3fs.img > /dev/null 2>&1
	[ $? -ne 0 ] && echo "Unable to copy the squashfs FS. Exiting" && exit -1
	mkdir $TMPDIR/syslinux $TMPDIR/LiveOS $TMPDIR/data_files $TMPDIR/config $TMPDIR/fw_files $TMPDIR/log

	echo "Copying system files..."
	$SYSLINUX -i -d syslinux $PART
	if [ $? -ne 0 ]; then
		echo "Unable to syslinux $PART. Exiting"
		ret=1
	else
		echo "0.9.7" > $TMPDIR/.version
		cp $DATA/vmlinuz $DATA/initramfs.img $DATA/syslinux.cfg $TMPDIR/syslinux
		cp $DATA/fw_files/* $TMPDIR/fw_files
		cp $DATA/data_files/* $TMPDIR/data_files
		cp $DATA/config/* $TMPDIR/config
		mksquashfs $SQUASHFS $TMPDIR/LiveOS/squashfs.img
		if [ $? -ne 0 ]; then
			echo "Unable to recreate the squash FS $SQUASHFS. Exiting"
			ret=1
		fi
	fi
	rm -rf $SQUASHFS
fi
if [ $ret -eq 1 ]; then
	umount $TMPDIR
	exit $ret
fi

echo "Done"

echo "Unmounting file system. It may take some time to flush the buffers..."
umount $TMPDIR

sync

if [ ! "${PART##/dev/mapper/*}" = "$PART" ]; then
	echo "Releasing loopback device"
	$KPARTX -d $DRIVE
fi

rm -rf $TMPDIR

exit 0
