#!/bin/sh

if [ $# -ne 1 ]; then
	echo -e "Usage:\n\t$0 <partition to recover>"
	echo -e "\t<partition> takes format of device name excluding /dev/"
	echo -e "Example:\n\t$0 hdb8"
	exit 1
fi

partition="$1"
outFile="/new_disk/recover-$partition.img"
baseCmd="dd if=/dev/$partition of=$outFile bs=1"
recordsIn=0
recordsOut=0
#recordsIn=20140000000
#recordsOut=20140000000
lastUnread=0 # 1 if last dd resulted in failed read
ddReturn=-1 # set bad intial return value

while [ "$ddReturn" -ne 0 ]; do

	if [ "$recordsIn" -gt 0 ]; then
		fullCmd="$baseCmd skip=$recordsIn seek=$recordsIn"
	else
		fullCmd="$baseCmd"
	fi
	if [ "$lastUnread" -ne 0 ]; then
		# this time try to read only one block
		fullCmd="$fullCmd count=100000"
	fi
	echo Running "$fullCmd"
	ddOutput="$($fullCmd 2>&1)"
	ddReturn=$?
	# get around the case where a 100k read is successful, but the last read wasn't...
	# this will oftentimes end the recovery prematurely.  the workaround (below) could,
	# i suppose, get us stuck in the case that we're already at the end of the disk, in
	# which case the script may end up infinitely adding 100k blocks of zeroes to the
	# disk image.  but, for such a limited use script... *shrug* for now.
	if [ "$ddReturn" -eq 0 ]; then
		if [ "$lastUnread" -ne 0 ]; then
			ddReturn=-1
		fi
	fi

	newRecordsIn=$(echo "$ddOutput" | sed -ne 's/^\([0-9][0-9]*\)+.* records in$/\1/p')
	newRecordsOut=$(echo "$ddOutput" | sed -ne 's/^\([0-9][0-9]*\)+.* records out$/\1/p')
	if [ "$newRecordsIn" -ne "$newRecordsOut" ]; then
		echo "WARNING: new records in and out don't match! ($newRecordsIn, $newRecordsOut)"
	fi
	if [ "$newRecordsIn" -eq 0 ]; then
		lastUnread=1 # no data read this time, only try one block next time
		echo "Writing 100k zeros after $recordsIn."
		# advance 100k blocks to avoid this current failing block
		dd if=/dev/zero of=$outFile seek=$recordsIn bs=1 count=100000 &> /dev/null
		recordsIn=$[ $recordsIn + 100000 ]
		recordsOut=$[ $recordsOut + 100000 ]
	else
		lastUnread=0 # some data read successfully this time, continue on to unlimited read next time
		recordsIn=$[ $recordsIn + $newRecordsIn ]
		recordsOut=$[ $recordsOut + $newRecordsOut ]
	fi

	echo "Records in: $recordsIn, Records out: $recordsOut"

done

echo -e "\nRecovery attempt done."

# vim:ts=2:sw=2

