#!/bin/bash # # frecover - floppy recover # # A utility to chew through a physically damaged device and recover # data from all of the readable clusters. The recovered data is then # reassembled with binary nulls filling the unrecoverable addresses. # # Copyright (C) 2001 George Bakos # Written by George Bakos (alpinista@bigfoot.com) # # You may not want to run this from a console, as the kernel will scream # bloody murder every time it runs into an unreadable cluster. # # frecover is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. # # frecover is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. A copy of the GPL is available from the Free Software # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. usage() { echo $'\t'"usage: $0 [device]" 1>&2 echo $'\t'"default device is /dev/fd0 " $'\n' } if [ "$1" = "--help" ] then usage exit 0 fi # # Decide if we want to use fd0 or some other device # if [ $# -eq 1 ] then DSK=$1 else DSK="/dev/fd0" fi # # If you are using anything other than a 1.44MB floppy, please be # sure to change the following to the capacity, in bytes, of your media. # DSKSIZE=1474560 # # If INCR is adjusted higher, the recovery will be faster, but you stand # a greater chance of missing something. If you are really nit-picky, you # are welcome to lower it, but be ready to wait a looooong time if there # is alot of damage. In theory, lowering this below your cluster size won't # gain you anything. YMMV. # INCR=128 # # ZDEV is a character generator to pad out the spaces between good data. # If you don't have a /dev/zero, or wish to use something else, edit this # next line. # ZDEV=/dev/zero # # dd should be in /bin, otherwise change this line # DDBIN=/bin/dd # ######### Don't change anything below this line ######### # DOFFSET=0 SHIMVAL=0 SHIMCNT=0 DOFFSET=0 RCRDS=0 BYTES=0 CNT=1 TMPDIR=/tmp/`date +%s` NEWIMG=$TMPDIR/newimage.img test -x $DDBIN ||\ { echo dd not found exit 1 } test -b $DSK ||\ { echo $'\n'$DSK is not a valid block device usage exit 1 } test -c $ZDEV ||\ { echo $'\n'$ZDEV is not a valid character device exit 1 } readgood() { TMPFIL=$TMPDIR/$CNT RCRDS=`$DDBIN if=$DSK of=$TMPFIL bs=1 skip=$DOFFSET 2>&1 | tail -1 | cut -d \+ -f 1` if [ $RCRDS -eq 0 ] then { echo -n $DOFFSET bytes of $DSKSIZE complete$'\r' DOFFSET=$(($DOFFSET + $INCR)) if [ $DOFFSET -ge $DSKSIZE ] then return fi SHIMVAL=$(($SHIMVAL + $INCR)) } else { DOFFSET=$(($DOFFSET + $RCRDS)) SHIMCNT=$(($CNT - 1)) $DDBIN if=$ZDEV of=$TMPDIR/$SHIMCNT bs=1 count=$SHIMVAL 2>/dev/null CNT=$(($CNT + 2)) SHIMVAL=0 } fi } todisk() { echo "Remove original and insert clean diskette." echo "WARNING! All data on target disk will be overwritten!" echo "Enter to continue" read pause && echo $pause Writing image to $DSK $DDBIN if=$NEWIMG of=$DSK 2>/dev/null echo Finished. } reconstr() { ls -1 $TMPDIR |sort -n | while read f do cat $TMPDIR/$f >> $NEWIMG echo -n \# done echo echo "Reconstruction complete" echo "Rebuilt image is $NEWIMG" if [ $(ls -l $NEWIMG |awk '{print $5}') != $DSKSIZE ] then { echo "WARNING! New image file size error. Recovery may be incomplete" exit 1 } fi } echo "Recovering disk in $DSK, $DSKSIZE bytes in $INCR byte increments." mkdir $TMPDIR while [ $DOFFSET -le $DSKSIZE ] do readgood done echo "Finished reading recoverable data. Reconstruction initiated" reconstr echo "Would you like to write the recovered image to disk? " echo -n "Type y to to write, or anything else to exit: " read resp val=x$resp if [ $val = "xy" ] then todisk fi exit 0