#!/bin/sh



LogIt() {
    echo "$1" >> /dev/stderr
# >> /tmp/format-and-kludge-vfat.log
}


ExitHere() {
    echo "Exiting here for testing.                            "
    exit 1
}

Die() {
    LogIt "(format-and-kludge-vfat) $1" 1
    exit 1
}

GetNBytesFromFile() {
    dd if=$1 bs=1 skip=$2 count=$3 2> /dev/null
}



GetPartitionFdiskType() {
    local drive device type
    device=$1
    drive=`echo "$device" | sed s/[0-9]// | sed s/[0-9]//`
    type=`fdisk -l $drive | grep "$device " | tr '*' ' ' | tr '+' ' ' | tr -s ' ' ' ' | cut -d' ' -f5`
    echo "$type"
    LogIt "partition $device is type '$type'"
}


# -------------- main ------------

LogIt "format-and-kludge-vfat --- starting"

if [ "$#" -ne "2" ] ; then
    LogIt "format-and-kludge-vfat <device> <embleer path>" 1
    exit 1
fi

device=$1
embleer=$2

[ -d "$embleer" ] || Die "embleer path $embleer not found"

stub=`basename $device`

retval=0
LogIt "Zeroing the first 50MB of partition $device" 2
dd if=/dev/zero of=$device bs=1024k count=50 2> /dev/null
LogIt "Formatting $device" 2
mkfs -t vfat -F 32 $device 2> /tmp/fakv.log > /dev/null
res=$?
if [ "$res" -ne "0" ] ; then
    mkdosfs -F 32 $device 2> /tmp/fakv.log > /dev/null
    res=$?
fi
retval=$(($retval+$res))
if [ "$res" -ne "0" ]; then
    LogIt "Errors occurred while formatting $device!" 1
    cat /tmp/fakv.log
    exit 1
fi
if [ "$device" != "/dev/hda1" ] && [ "$device" != "/dev/sda1" ] ; then
    LogIt "OK, this is not /dev/hda1 or /dev/sda1; so, I shan't kludge it." 1
    exit 0
fi
LogIt "Baking up the 'real' boot sector" 2
freshBS=/tmp/$stub.fresh.512
embleerBS=/tmp/$stub.embleer.512
finalBS=/tmp/$stub.final.512
dd if=$device of=$freshBS bs=512 count=1 2> /dev/null > /dev/null
res=$?
retval=$(($retval+$res))
LogIt "Finding out if it's a B or C type partition" 2
type=`GetPartitionFdiskType $device`
if [ "$type" = "b" ] ; then
# used to be 'embleer.B.bz2' but some users had problems;
# I'll try C, to see if that helps ------ Hugo Rabson, 01/26/2002
    embleer_fname="$embleer/embleer.C.bz2"
    count=4400
elif [ "$type" = "c" ] ; then
    embleer_fname="$embleer/embleer.C.bz2"
    count=4400
else
    Die "type($device)=$type; that's weird!"
fi

# The plan is this:-
# 1. Backup the first 512 bytes of the freshly-formatted device.
# 2. Overwrite the fist N Megabytes of the device with the 'embleer' file,
#    which will kludge the boot sector (_not_ MBR) so that Windows can boot.
# 3. Backup the first 512 bytes of the recently-embleer'd deevice.
# 4. Take the first 66 bytes of the drive's original contents. Copy to it,
#    from embleer'd device backup file, bytes 2-11, 29 and 41.
# 5. Copy the modified 66-byte section to the start of the device.
#
# freshBS = backup of the freshly-formatted device (first 512 bytes)
# embleerBS = backup of the recently-embleer'd device (first 512 bytes)
# finalBS = combination of freshBS and embleerBS (first 66 bytes)

res=0
LogIt "It's a $type type. Embleering it with $embleer_fname" 2
bunzip2 $embleer_fname -c | dd of=$device bs=1024 count=$count 2> /dev/null > /dev/null
dd if=$device of=$embleerBS bs=512 count=1 2> /dev/null > /dev/null
res=$(($res+$?))
> $finalBS
#                   input     pos   length     output
GetNBytesFromFile $embleerBS   0      13     >> $finalBS || res=$(($res+$?))
GetNBytesFromFile $freshBS     13     15     >> $finalBS || res=$(($res+$?))
GetNBytesFromFile $embleerBS   28     1      >> $finalBS || res=$(($res+$?))
GetNBytesFromFile $freshBS     29     34     >> $finalBS || res=$(($res+$?))
GetNBytesFromFile $embleerBS   63     2      >> $finalBS || res=$(($res+$?))
dd if=$finalBS of=$device 2> /dev/null || res=$(($res+$?))
retval=$(($retval+$res))
[ "$res" -ne "0" ] && LogIt "Failed to do the fresh/embleer/final kludging." 1
[ "$res" -eq "0" ] && LogIt "Embleer'd $device OK with $embleer_fname" 2
[ ! -e "/mnt/tmpK" ] && mkdir /mnt/tmpK

#echo "res = $res"
#ExitHere

dd if=/tmp/$stub.bs.512 of=$device skip=32 seek=32 bs=1 count=6 2> /dev/null > /dev/null
mount $device -t vfat /mnt/tmpK || Die "Can't mount $device"
if [ -e "$embleer/io.sys" ] ; then
    cp -f $embleer/*.sys /mnt/tmpK
elif [ -e "/io.sys" ] ; then
    cp -f /*.sys /mnt/tmpK
else
    LogIt "Can't find io.sys and/or msdos.sys; kludge might not work." 1
    retval=$(($retval+1))
fi
size=`df -m /mnt/tmpK | tr -s ' ' ' ' | cut -d' ' -f2 | tail -n 1`
umount /mnt/tmpK || Die "Can't unmount tmpK"
ideal_size=`cat /tmp/mountlist.txt | grep "$device " | tr -s ' ' ' ' | cut -d' ' -f4`
if [ "$ideal_size" = "" ]; then 
    LogIt "format-and-kludge-mkfs --- can't find $device in mountlist" 1
    exit 0
fi
LogIt "ideal_size = $ideal_size" 2
ideal_size=$(($ideal_size/1024))
difference=$(($ideal_size-$size))
[ "$difference" -lt "0" ] && difference=$((0-$difference))
LogIt "ideal_size=$ideal_size; siz=$size; difference=$difference"
if [ "$difference" -gt "64" ] ; then
    retval=$(($retval+1))
    LogIt "(format-and-kludge-vfat) Size mismatch. Did kludge work?" 1
else
    LogIt "Size matches. (Well, nearly.) Good." 2
fi

if [ "$retval" -eq "0" ] ; then
    LogIt "$device was successfully formatted and prepared" 1
else
    LogIt "$device failed to be formatted and prepared" 1
fi
LogIt "(by format-and-kludge-vfat)"

LogIt "format-and-kludge-vfat --- leaving (retval=$retval)"
exit $retval

