#!/bin/sh

cat << EOF
#
# Automated upgrade process for mindstor storage unit.
# Author: Steve Dempsey <steve_t_dempsey@hotmail.com>
# Version 0.2
#
# Thanks to Kent Robotti robotti@godmail.com for the RIP boot image.
# http://www.tux.org/pub/people/kent-robotti/looplinux/rip/
#
EOF

logf=/tmp/msupg.log
test -r $logf || {
echo xxxxxxxxxxxxxxxxx >> $logf
}

# show name/size of all drives...
showdrives() {
  for hd in hda hdb hdc hdd ; do
    test -r /proc/ide/$hd/model -a -r /proc/ide/$hd/capacity && {
      model=`cat /proc/ide/$hd/model`
      cap=`cat /proc/ide/$hd/capacity`
      capkb=`expr $cap / 2048`
      echo "Drive:  $hd     Model: $model    Size: ${capkb}KBytes, $cap sectors"
      echo "Drive:  $hd     Model: $model    Size: ${capkb}KBytes, $cap sectors" >> $logf
      echo " "
      nhd=`expr $nhd + 1`
    }
  done
}

writefd() {
    echo ' '
    echo 'Please insert a 1.44MB floppy disk.  Its contents will be erased.'
    echo 'The firmware and serial number file will be saved on the floppy'
    echo 'for later use with your new drive.'
    echo -n 'Press enter when your floppy is ready.  '
    read dummy

    # do some simple i/o on the disk to reset the contoller
    # in case junk left in the driver from untimely media swap
    dd if=/dev/zero of=/dev/fd0 bs=512 count=1 >/dev/null 2>&1
    dd of=/dev/null if=/dev/fd0 bs=512 count=1 >/dev/null 2>&1

    echo "Formatting the floppy..."
    fdformat /dev/fd0

    echo "Installing DOS filesystem on the floppy..."
    gunzip < /etc/blankfd.gz > /dev/fd0

    echo "Mounting the floppy..."
    mkdir -p /mnt/floppy
    mount -orw /dev/fd0 /mnt/floppy || {
	echo "Something seems to have failed mounting the floppy."
	sleep 5
	exit 0
    }

    echo "Copying the files..."
    cp  /tmp/FW-IMG.GZ /tmp/SN.BIN /mnt/floppy || {
	echo "Something seems to have failed, check the floppy."
	sleep 5
        umount /mnt/floppy
	exit 0
    }

    sync
    echo "Unmounting the floppy..."
    umount /mnt/floppy
    sync

    echo ' '
    echo 'Image saved.  Files on the msdos floppy disk are:'
    echo '    FW-IMG.GZ   = compressed firmware image'
    echo '    SN.BIN      = same as m$a$w$.s$n'
    echo 'This disk may be used to restore firmware to the'
    echo 'drive at a later time, or transfer to a replacement'
    echo 'drive including upgrade to a larger drive.'
    echo 'Eject the image floppy and shut down.'
    exit 0
}

olddrive() {
    echo "Retrieving serial number data ..."
    echo dd if=/dev/$hdspec bs=512 count=1 skip=$snloc of=/tmp/snfile >> $logf
    dd if=/dev/$hdspec bs=512 count=1 skip=$snloc of=/tmp/snfile >/dev/null

    test -r /bin/mssn && {
    # let user change the sn file if desired
    mssn /tmp/snfile /tmp/SN.BIN
    }

    # if mssn wasn't there or failed, just keep the old file
    test -s /tmp/SN.BIN || cp /tmp/snfile /tmp/SN.BIN

    echo "Retrieving firmware image data, expect 32768 records ..."
    # put the (possible changed) sn file back inline with the image

    echo dd if=/dev/$hdspec bs=512 skip=$fwloc count=12288 >> $logf
    echo + dd if=/tmp/SN.BIN bs=512 count=1 >> $logf
    echo +  dd if=/dev/$hdspec bs=512 skip=$snloc1 >> $logf

    #test size
    (dd if=/dev/$hdspec bs=512 skip=$fwloc) 2>>/tmp/msupg.log | gzip | dd bs=512 of=/dev/null 2>/tmp/zipsize

    testsiz=`grep records.out /tmp/zipsize | sed 's/\+.*//'`

    test 0$testsiz -gt 2700 -o 0$testsiz -eq 0 && {
        echo "Oops, your firmware image did not compress enough"
        echo "or was empty; got $testsiz and expected less than"
        echo "2700.  This is not a MS/DW drive or something is"
	echo "unusual about your firmware.  Unable to continue,"
	echo "sorry."
        exit 1
    }

    (dd if=/dev/$hdspec bs=512 skip=$fwloc count=12288; dd if=/tmp/SN.BIN bs=512 count=1; dd if=/dev/$hdspec bs=512 skip=$snloc1) 2>>/tmp/msupg.log | dd bs=512 | gzip > /tmp/FW-IMG.GZ

    echo ' '
    echo 'If your new drive is also connected now, you may finish'
    echo 'the upgrade process without rebooting or saving data to'
    echo 'a floppy disk.'
    ans=foo
    while test "1$ans" != "1yes" -a "1$ans" != "1no"; do
      echo -n 'Is your new drive on line (yes/no)?  '
      read ans
      test "1$ans" = "1yes" && mainprog
      test "1$ans" = "1no" && writefd
      echo 'Please answer yes or no.'
    done
}

newdrive() {
    # if files still exist just use them, else retrieve...
    test -s /tmp/FW-IMG.GZ || {
      echo 'Insert the floppy disk holding image from your old drive.'
      echo -n 'Press enter when ready.  '
      read dummy
      
      # do some simple i/o on the disk to reset the contoller
      # in case junk left in the driver from untimely swap
      dd of=/dev/null if=/dev/fd0 bs=512 count=1 skip=1339 >/dev/null 2>&1
      dd of=/dev/null if=/dev/fd0 bs=512 count=1 >/dev/null 2>&1

      echo 'Mounting the floppy...'
      mkdir -p /mnt/floppy
      mount -r /dev/fd0 /mnt/floppy || {
	echo "Something seems to have failed mounting the floppy."
	sleep 5
	exit 0
      }

      echo 'Retrieving files...'
      cp /mnt/floppy/FW-IMG.GZ /tmp || {
	echo "Something seems to have failed, check your floppy"
	sleep 5
        umount /mnt/floppy
	exit 0
    }

    echo 'Unmounting the floppy ...'
    umount /mnt/floppy
    }

    echo 'Checking files...'
    test -s /tmp/FW-IMG.GZ || {
	   echo 'Did not find or failed to copy FW-IMG.GZ'
	   echo 'from your floppy disk, check its contents.'
	   exit 1
    }

    echo 'Some version strings in this image:'
    gunzip < /tmp/FW-IMG.GZ | strings | grep VERSION | dd bs=80 count=1 2>/dev/null

    eightmax=`expr 16383 * 63 * 16`
    test "1$cap" -gt "1$eightmax" && {
      echo 'Your new drive is larger than 8GB.  If you have an older'
      echo 'DW unit, it may be able to use only 8GB maximum.  Do you'
      echo -n 'want to limit the size to 8GB only? (yes/no)  '
      read ans
      test "1$ans" = "1yes" && {
	# max 8GB capacity for older DW
        echo -n "cap old: $cap"
	cap=`expr 16383 '*' 63 '*' 16`
	echo "   new: $cap"
	echo -n "fw old: $fwloc"
	fwloc=`expr $cap - 32768`
	echo "   new: $fwloc"
	echo -n "sn old: $snloc"
	snloc=`expr $fwloc + 12288`
	echo "   new: $snloc"
	snloc1=`expr $snloc + 12289`
	pwloc=`expr $fwloc + 12290`
	echo -n "fssize old: $fssize"
	fssize=`expr $fwloc / 2`
	echo "   new: $fssize"
      }
    }

    echo ' '
    echo 'Restoring image to new drive...'
    gunzip < /tmp/FW-IMG.GZ | dd of=/dev/$hdspec bs=512 seek=$fwloc
    echo "You should see 32768 records in/out."
    echo " "

    dd if=/dev/$hdspec bs=512 count=1 skip=12288 of=/tmp/SN.BIN 2>&1 >/dev/null

    echo 'Apparent serial number in this image:'
    dd if=/tmp/SN.BIN bs=1 count=1 skip=2 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=4 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=6 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=8 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=10 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=12 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=14 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=16 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=18 2>/dev/null
    dd if=/tmp/SN.BIN bs=1 count=1 skip=20 2>/dev/null
    echo ' '

    test -r /sbin/mkdosfs && {

        echo "The fat32 filesystm may be installed now, or you"
        echo "can do it from your system via USB/Firewire interface."
        echo -n "Do you want to create the fat32 filesystem now (yes/no)?"  

        ans="foo"
        read ans
        test "1$ans" = "1yes" && {
	    echo "Creating the fat32 filesystem..."
	    echo "mkdosfs -I -F 32 -v /dev/$hdspec $fssize ..."
	    /sbin/mkdosfs -I -F 32 -v /dev/$hdspec $fssize
        }

        test $fssize -gt 33554432 && {
            echo "NOTE: this fat32 filesystem is larger than 32GB."
            echo "Windows 2000/XP will not be able to (re)format it."
	    echo "see http://support.microsoft.com/default.aspx?scid=kb;EN-US;q184006"
        }
    }
    test -r /sbin/mkdosfs || {
        dd if=/dev/zero of=/dev/$hdspec bs=512 count=4
        echo 'No filesystem was placed on your new disk.  You must'
	echo 'reformat using USB/Firewire interface to use it.'
    }
    echo ' '
    echo 'ALL DONE!  Shutdown and power off before disconnecting the'
    echo 'drive to install back in your mindstor unit.'
    echo ' '
    exit 0
}

mainprog() {

echo 'The following IDE/ATA drives were detected on your system.'
echo '    hda = primary master'
echo '    hdb = primary slave'
echo '    hdc = secondary master'
echo '    hdd = secondary slave'
echo 'If you choose the wrong drive, this process may destroy data.'
echo ' '

nhd=0
showdrives
test $nhd -lt 1 && {
    echo 'Sorry, there seem to be no IDE drives detected'
    echo 'Please change your hardware and try again.'
    exit 1
}

ans=none
while test "1$ans" != "1hda" -a "1$ans" != "1hdb" -a "1$ans" != "1hdc" -a "1$ans" != "1hdd"; do
  echo -n 'Choose a drive (hda/hdb/hdc/hdd)?  '
  read ans
done

hdspec=$ans
model=`cat /proc/ide/$hdspec/model`
cap=`cat /proc/ide/$hdspec/capacity`
capkb=`expr $cap / 2048`
fwloc=`expr $cap - 32768`
snloc=`expr $fwloc + 12288`
snloc1=`expr $fwloc + 12289`
pwloc=`expr $fwloc + 12290`
fssize=`expr $fwloc / 2`

#save to log
echo "drive:   $hdspec" >> $logf
echo "sectors: $cap" >> $logf
echo "kbytes:  $capkb" >> $logf
echo "fwloc:   $fwloc" >> $logf
echo "snloc:   $snloc" >> $logf
echo "snloc1:  $snloc1" >> $logf
echo "pwloc:   $pwloc" >> $logf
echo "fssize:  $fssize" >> $logf

while test true; do
  echo ' '
  echo -n 'Is this drive your original/old or upgrade/new  drive? (old/new) '
  read ans
  
  test "1$ans" = "1old" && olddrive
  test "1$ans" = "1new" && newdrive
  
  echo 'Sorry, please enter "old" or "new"'
done
}

mainprog
