Package: fdutils
Version: 5.4-20040228-1
Severity: wishlist
Tags: patch
The following script offers a friendly interface (pv on commandline,
dialog, or zenity for gui) for writing floppy disk images. This
script doesn't just blast out the image and hope it's okay; unless you
specify otherwise, the script will verify (using cmp) that the image
can be read back and, if not, will reformat the floppy and try again
(exactly once). I did this after far too many bad floppies (a
combination of flaky drives and the fact that floppy quality is
absolutely horrible these days).
If called without a disk image to write it will use a file chooser to
let the user browse to the file to write. I hope to do an update-menu
thing that calls 'fburn --gui', which makes for a somewhat friendly
interface from a window manager menu or icon.
If possible I'd like to be forwarded any bugs in the script so that I
can fix them, rather than you having to spend time on them.
It depends on bash, getopt, dd, cmp, superformat, pv, tee,
dialog, and zenity which on debian are provided by bash, util-linux,
coreutils, diff, fdutils, pv, dialog, and zenity, although dialog and
zenity are optional (though the default ui would have to changed to
commandline using pv instead of dialog, if dialog and zenity were to
be suggests or recommends).
#!/bin/bash
# fburn 1.2 is used to write raw data (usually a floppy image) to a
# floppy.
# Copyright (C) 2006 Daniel Dickinson <[EMAIL PROTECTED]>
# This program 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 of the License, or
# (at your option) any later version.
# This program 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.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
display_usage () {
echo ""
echo "fburn 1.1 Copyright (C) 2006 Daniel Dickinson <[EMAIL PROTECTED]>"
echo ""
echo "fburn is used to write raw data (usually a floppy image) to a floppy."
echo " its default action is the write the image to floppy, then compare"
echo " the floppy to the image. If there is an error during the compare"
echo " stage, fburn will make at reformatting the floppy and rewriting."
echo ""
echo "Usage: fburn [options] [image-to-write]"
echo ""
echo " -a|--abort-on-failure Don't try formatting then rewriting the"
echo " image after a fail in compare or copy"
echo ""
echo " -d|--debug Display debugging information"
echo ""
echo " -f device|--device device Floppy device name"
echo ""
echo " -g|--gui Display progress bars, info boxes, and"
echo " error messages as GUI dialogs"
echo " -h|--help This text"
echo ""
echo " -i|--initial-format Format before writing image, instead"
echo " only after failing to write"
echo " -n|--no-dialogs Display and prompt on command-line"
echo " (no popup dialogs)"
echo ""
echo "image-to-write can be any file small enough to fit on a floppy"
echo " though usually it will be a floppy image. If no image is"
echo " specified a file browser is opened."
echo ""
}
#
# Q: Why do the copy and compare functions use fillstr and write fake data to
# the pipe?
#
# A: We pad the output of cat (piped to pv) because dialog and zenity progress
# bars require that only the very last byte result in a progress report of 100%
# but pv rounds up so in many cases dialog and zenity think the job is done and
# terminating, breaking the pipe. Also, because of floppy buffering, pv
# reports 100% when the last byte is written to the disk buffer, not when the
# buffer is emptied. By appending fake data (which never goes to disk) that
# doesn't make it to dialog or zenity until the disk buffer is empty, we see a
# mostly complete write, instead of no more dialog or zenity progress bar until
# the buffer unblocks. This does throw off the math slightly, but I don't
# think that should be an issue since a progress bar really only gives a
# general feel for the progress made so far anyway.
#
##################
# Exit Codes
#################
OK=0
CANCEL=1
ERR_IMAGE=2
ERR_GETOPT=3
ERR_COPYTMP=4
ERR_COPYABORT=5
ERR_CMPTMP=6
ERR_CMPABORT=7
ERR_FORMATTMP=8
ERR_FLOPPYDEVW=9
ERR_FLOPPYDEVR=10
ERR_INITFORMAT=11
ERR_REFORMAT=12
ERR_INITDD=13
#####################
#
# Other constants
#
#####################
BLOCKSIZE=512
###############################
#
# Default settings for options
# false, true
#
###############################
INITIALFORMAT=false
DEBUG=false
GUI=false
FLOPPYDEV=/dev/fd0
ABORT=false
NODIALOG=false
SKIPLICENSE=false
################################
#
# Parse command line options
#
################################
CMDLINE=$(getopt --long
device:,gui,initial-format,abort-on-failure,debug,no-dialogs,skip-license,help
-o f:giadnsh -- "$@")
IMAGE=""
if [ $? != 0 ]; then
echo "Error parsing options; Terminating." >&2 ; exit $ERR_GETOPT
fi
eval set -- "$CMDLINE"
while true; do
case "$1" in
-f|--device)
FLOPPYDEV=$2
shift 2
;;
-g|--gui)
GUI=true
shift
;;
-i|--initial-format)
INITIALFORMAT=true
shift
;;
-a|--abort-on-failure)
ABORT=true
shift
;;
-d|--debug)
DEBUG=true
shift
;;
-n|--no-dialogs)
NODIALOG=true
shift
;;
-s|--skip-license)
SKIPLICENSE=true
shift
;;
-h|--help)
display_usage
exit 0
;;
--)
shift
break
;;
*)
display_usage
exit 2
;;
esac
done
for arg do IMAGE="$arg"; break; done
if [ "$DEBUG" = "true" ]; then
echo "'$IMAGE'"
fi
msgbox () {
local CANCELLED
CANCELLED=false
if [ "$NODIALOG" = "true" ]; then
echo "$1"
elif [ "$GUI" = "true" ]; then
zenity $2 --text="$1"
if [ "$?" = "1" ]; then
CANCELLED=true
fi
else
dialog --clear
dialog --msgbox "$1" 10 70
if [ "$?" = "1" ]; then
CANCELLED=true
fi
fi
if [ "$CANCELLED" = "true" ]; then
exit CANCEL
fi
}
errbox () {
msgbox "$1" "--error"
}
infobox () {
msgbox "$1" "--info"
}
progressbar () {
if [ "$GUI" = "true" ]; then
zenity --progress --text="$1" --auto-close 2>&1
elif [ "$NODIALOG" = "false" ]; then
dialog --clear
dialog --guage "$1" 9 70 2>&1
fi
}
copy_image () {
local EXIT
local TMPFILE
local remainder
local fullblocks
local fillstr
local fakerem
local fakesize
local fakeblkrem
local fakefull
local faketotal
local fakebytes
local fakeblkbytes
local CANCELLED
CANCELLED=false
if [ "$DEBUG" = "true" ]; then
echo "Copying image"
fi
TMPFILE=$(mktemp -t "exit_code.XXXXXX")
if [ "$?" != "0" ]; then
errbox "Error getting temporary filename for copy_image"
exit $ERR_COPYTMP
fi
remainder=$(expr $SIZE % $BLOCKSIZE)
fullblocks=$(expr $SIZE / $BLOCKSIZE)
if [ $remainder -ne 0 ]; then
fullblocks=$(expr $fullblocks + 1)
fi
fakerem=$(expr $SIZE % 100)
fakesize=$(expr $SIZE / 100 )
if [ $fakerem -ne 0 ]; then
fakesize=$(expr $fakesize + 1)
fi
fakeblkrem=$(expr $fakesize % $BLOCKSIZE)
fakefull=$(expr $fakesize / $BLOCKSIZE)
if [ $fakeblkrem -ne 0 ]; then
fakefull=$(expr $fakefull + 1)
fi
faketotal=$(expr $fakefull + $fullblocks)
fakeblkbytes=$(expr $faketotal '*' $BLOCKSIZE)
fakebytes=$(expr $fakeblkbytes - $SIZE)
fillstr=$(yes . | tr -d \\\n | dd bs=1 count=$fakebytes 2>/dev/null)
if [ "$DEBUG" = "true" ]; then
echo "remainder: $remainder"
echo "fullblocks: $fullblocks"
echo "fakerem: $fakerem"
echo "fakesize: $fakesize"
echo "fakeblkrem: $fakeblkrem"
echo "fakefull: $fakefull"
echo "faketotal: $faketotal"
echo "fakeblkbytes: $fakeblkbytes"
echo "fakebytes: $fakebytes"
# echo "fillstr\n$fillstr"
fi
if [ "$NODIALOG" = "true" ]; then
echo "Copying image $1 to $FLOPPYDEV"
( cat $1; echo $fillstr ) | pv -W -s $fakeblkbytes -n 2>$TMPFILE | pv
-W -p -e -b -s $fakeblkbytes | ( dd of=$FLOPPYDEV obs=$BLOCKSIZE ibs=1
count=$SIZE; cat - >/dev/null )
else
( cat $1; echo $fillstr ) | pv -W -s $fakeblkbytes -n 2>$TMPFILE | ( pv
-W -n -s $fakeblkbytes | ( dd of=$FLOPPYDEV obs=$BLOCKSIZE ibs=1 count=$SIZE ;
cat - >/dev/null ) 2>/dev/null ) 2>&1 | progressbar "Copying image $1 to
$FLOPPYDEV"
if [ "$?" = "1" ]; then
CANCELLED=true
exit CANCEL
fi
fi
EXIT=$(cat $TMPFILE | sed -e '/^[0-9][0-9]*$/!d' | tail -n 1 )
if [ "$DEBUG" = "true" ]; then
cat $TMPFILE
echo "\$EXIT = $EXIT"
fi
rm -f $TMPFILE
if [ "$EXIT" != "100" ]; then
if [ "$ABORT" = "true" ]; then
errbox "Error writing image to floppy; aborting"
exit $ERR_COPYABORT
fi
return 1
else
return 0
fi
}
compare_image () {
local EXIT
local TMPFILE
local fillstr
local fakesize
local fakerem
local faketotal
local CANCELLED
CANCELLED=false
if [ "$DEBUG" = "true" ]; then
echo "Comparing image"
fi
TMPFILE=$(mktemp -t "exit_code.XXXXXX")
if [ "$?" != "0" ]; then
errbox "Error getting temporary filename for compare_image"
exit $ERR_CMPTMP
fi
fakerem=$(expr $SIZE % 100)
fakesize=$(expr $SIZE / 100 )
if [ $fakerem -ne 0 ]; then
fakesize=$(expr $fakesize + 1)
fi
faketotal=$(expr $fakesize + $SIZE)
fillstr=$(yes . | tr -d \\\n | dd count=$fakesize bs=1 2>/dev/null)
if [ "$NODIALOG" = "true" ]; then
echo "Comparing file $1 to $FLOPPYDEV"
(cat $1 ; echo $fillstr ) | pv -W -n -s $faketotal 2>$TMPFILE | pv -W
-e -b -p -s $faketotal | ( cmp -n $SIZE $FLOPPYDEV ; cat - >/dev/null)
else
(cat $1; echo $fillstr) | ( pv -W -n -s $faketotal | ( cmp -n $SIZE
$FLOPPYDEV ; cat - >/dev/null ) ) 2>&1 | tee $TMPFILE | progressbar "Comparing
file $1 to $FLOPPYDEV"
if [ "$?" = "1" ]; then
CANCELLED=true
exit CANCEL
fi
fi
EXIT=$(cat $TMPFILE | sed -e '/^[0-9][0-9]*$/!d' | tail -n 1 )
if [ "$DEBUG" = "true" ]; then
cat $TMPFILE
echo "\$EXIT = $EXIT"
fi
rm -f $TMPFILE
if [ "$EXIT" != "100" ]; then
if [ "$ABORT" = "true" ]; then
errbox "Error comparing image to floppy; aborting"
exit $ERR_CMPABORT
fi
return 1
else
return 0
fi
}
copy_compare () {
local DDOK
local CMPOK
CMPOK=false
copy_image $1
if [ "$?" = "0" ]; then
DDOK=true
else
DDOK=false
fi
if [ "$DDOK" = "true" ]; then
compare_image $1
if [ "$?" = "0" ]; then
CMPOK=true
else
CMPOK=false
fi
else
if [ "$DEBUG" = "true" ]; then
echo "Copy failed"
fi
return 1
fi
if [ "$DDOK" = "true" ] && [ "$CMPOK" = "true" ]; then
return 0
else
if [ "$DEBUG" = "true" ]; then
echo "Compare failed"
fi
return 1
fi
}
doformat () {
local TMPFILE
local EXIT
TMPFILE=$(mktemp -t "exit_code.XXXXXX")
if [ "$?" != "0" ]; then
errbox "Error getting temporary filename for format"
exit $ERR_FORMATTMP
fi
if [ "$NODIALOG" = "true" ]; then
echo "Formatting floppy"
( superformat -v 2 --superverify $FLOPPYDEV | cat -A ; echo -n
"........") | pv -n -s 650 2>$TMPFILE | pv -p -e -s 650 >/dev/null
else
( superformat -v 2 --superverify $FLOPPYDEV | cat -A ; echo -n
"........") | ( pv -n -s 650 >/dev/null ) 2>&1 | tee $TMPFILE | progressbar
"Formatting floppy"
fi
EXIT=$(cat $TMPFILE | sed -e '/^[0-9][0-9]*$/!d' | tail -n 1 )
if [ "$DEBUG" = "true" ]; then
cat $TMPFILE
echo "\$EXIT = $EXIT"
fi
rm -f $TMPFILE
if [ "$EXIT" = "100" ]; then
return 0
else
return 1
fi
}
###############################
# SCRIPT BODY
###############################
CANCELLED=false
if [ "$DEBUG" = "true" ]; then
echo "Entering main body of fburn script"
fi
if [ "$NODIALOG" = "false" ] && [ "$GUI" = "false" ]; then
dialog --clear
fi
if [ "$SKIPLICENSE" = "false" ]; then
infobox "fburn 1.2, Copyright (C) 2006 Daniel Dickinson
fburn comes with ABSOLUTELY NO WARRANTY; This is free
software and you are welcome to redistribute it under certain
conditions; see the GNU Public License which you should have
received with this software. If not, see
http://www.gnu.org/licenses/gpl.html, or contact the author
by email at [EMAIL PROTECTED]"
fi
if [ -n $(echo "$IMAGE" | tr -d \ ) ]; then
if [ ! -r "$IMAGE" ]; then
if [ "$GUI" = "true" ]; then
IMAGE=$(zenity --file-selection)
if [ "$?" = "1" ]; then
CANCELLED=true
fi
elif [ "$NODIALOG" = "false" ]; then
IMAGE=$(dialog --clear --stdout --fselect "$(pwd)/*" 15 70 )
if [ "$IMAGE" = "" ]; then
CANCELLED=true
fi
fi
elif [ "$DEBUG" = "true" ]; then
echo "Image to write = $IMAGE"
fi
fi
if [ "$CANCELLED" = "true" ]; then
exit $CANCEL
fi
if [ -n $(echo "$IMAGE" | tr -d \ ) ]; then
if [ ! -r "$IMAGE" ]; then
errbox "Specified file '$IMAGE' is not readable"
exit $ERR_IMAGE
elif [ "$DEBUG" = "true" ]; then
echo "Image to write = $IMAGE"
fi
fi
if [ ! -w "$FLOPPYDEV" ]; then
errbox "Specified device for floppy ($FLOPPYDEV) is not writable"
exit $ERR_FLOPPYDEVW
fi
if [ ! -r "$FLOPPYDEV" ]; then
errbox "Specified device for floppy ($FLOPPYDEV) is not readable"
exit $ERR_FLOPPYDEVR
fi
if [ "$INITIALFORMAT" = "true" ]; then
doformat
if [ "$?" != "0" ]; then
errbox "Initial format failed"
exit $ERR_INITFORMAT
fi
fi
SIZE=$(du -s -b $IMAGE | cut -f1)
if [ "$DEBUG" = "true" ]; then
echo "Image size = $SIZE"
fi
copy_compare $IMAGE
if [ "$?" = "0" ]; then
infobox "Image successfully written to $FLOPPYDEV"
exit 0
elif [ "$INITIALFORMAT" = "false" ]; then
doformat
if [ $? != 0 ]; then
errbox "Format after failed copy or compare also failed"
exit $ERR_REFORMAT
fi
else
errbox "Writing or comparison of image failed after initial format"
exit $ERR_INITDD
fi
copy_compare $IMAGE
if [ "$?" != "0" ]; then
errbox "Compare failed even after reformat"
else
infobox "Compare initially failed, but succeeded after reformat"
fi
-- System Information: Debian Release: 3.1
APT prefers testing
APT policy: (200, 'testing'), (75, 'unstable'), (10, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.16-2-k7
Locale: LANG=en_CA, LC_CTYPE=en_CA (charmap=ISO-8859-1)
Versions of packages fdutils depends on:
ii debianutils 2.8.4 Miscellaneous utilities specific t
ii libc6 2.3.6-15 GNU C Library: Shared libraries
-- no debconf information
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]