#! /bin/bash

## Made September, 2002 by Francesco Potort́ <pot@gnu.org>
## current version is 1.12
## This program is released under the GNU GPL, whichever version
## which is available at http://www.gnu.org/licenses/gpl.txt
##
## Presentation and pointer to the latest release available at 
## <URL:http://fly.cnuce.cnr.it/software/software.html#floppyimg>.
## Please write to me if you want announcement of new releases.
##
## This script requires bash and the mtools
##
## TODO:
## - nothing
##
################################################################
progname=$(basename "$0")		# this program's name
nrep=9				       # number of tries for bad sectors
verbose=yes				# unset to make it quiet
disk=${1:-"a:"}				# diskette DOS name

if [[ "$disk" != [a-dA-D]: ]]; then
    echo Usage: $progname [disk] [image]
    echo "	disk is the diskette name in DOS style, default is A:."
    echo "	Creates a file named image.img, asks for the name if missing."
    echo "	The image of the diskette contains null characters where a sector"
    echo "	cannot be read.  Does multiple retries to read bad sectors."
    exit 2
fi

title="$2"
if [ -z "$title" ]; then
    read -p "Disk name: " -e title
fi

minfo $disk >/dev/null || exit 1
dev=$(minfo $disk | fgrep -i filename= | cut -d\" -f2)
nsect=$(($(minfo $disk |
 sed -n '/mformat/s/.*-t \([0-9]\+\).*-h \([0-9]\+\).*-s \([0-9]\+\).*/\1*\2*\3/p')))


out="$title".img
if [ -f "$out" ]; then
    rm -i "$out" || exit 2
fi

sectors=$(
    s=0
    while ((s < nsect)); do
        echo $((s+=1))
    done
)

function readsect ()
{ s=$1; dd if=$dev skip=$((s-1)) count=1 2>/dev/null; }

function writesect ()
{ s=$1; dd of="$out" seek=$((s-1)) conv=notrunc count=1 2>/dev/null; }


r=1
while [ "$sectors" ] && ((r <= nrep)); do
    badsectors=
    for s in $sectors; do
	test "$verbose" && printf "\rSectors read %4d/%d (repetition #%d)" $s $nsect $r >&2
	if readsect $s >/dev/null; then
	    readsect $s | writesect $s
	else
	    badsectors="$badsectors $s"
	fi
    done
    test "$verbose" && printf "\r%40s\r" ' ' >&2
    if [ "$badsectors" ]; then
	echo "Bad #$r: $badsectors" >&2
    else
	echo "No bad sectors" >&2
    fi

    sectors="$badsectors"
    ((r += 1))
done
