Skip to content

Instantly share code, notes, and snippets.

@msikma
Created October 25, 2018 22:47
Show Gist options
  • Save msikma/e226071b59593727e579a7f8af5cf22a to your computer and use it in GitHub Desktop.
Save msikma/e226071b59593727e579a7f8af5cf22a to your computer and use it in GitHub Desktop.
#!/usr/bin/env fish
# Floppy imaging script for OSX
# Requires gdd, diskutil and python (either 2 or 3).
#
# Waits until a new floppy is inserted, then automatically images it to
# the indicated directory. Set the directory in $FLOPPY_IMAGING_PATH.
#
# We will calculate the CRC32 of the first 500 bytes of the floppy
# as part of the filename, along with the floppy partition name.
set err "backup-floppy.fish: Error:"
if [ (whoami) != "root" ]
echo "$err Must run as root to access floppy device"
exit
end
# Remove trailing slash from the floppy path if it's there.
set dst (echo $FLOPPY_IMAGING_PATH | string replace -r '/$' '')
if test -z "$dst"
echo "$err Set a FLOPPY_IMAGING_PATH envvar first"
exit
end
set missing 0
if not type "gdd" > /dev/null 2>&1
echo "$err Missing command: gdd (GNU Core Utilities version of dd: install with 'brew install coreutils')"
set missing 1
end
if not type "diskutil" > /dev/null 2>&1
echo "$err Missing command: diskutil"
set missing 1
end
if not type "python" > /dev/null 2>&1
echo "$err Missing command: python (either Python 2 or Python 3)"
set missing 1
end
if [ $missing -eq '1' ]
exit
end
echo
echo "Floppy disk imaging script"
echo
echo (set_color yellow)"Target dir: "(set_color normal)$dst
mkdir -p $dst
if not test -d $dst
echo "$err Could not create or access FLOPPY_IMAGING_PATH: $FLOPPY_IMAGING_PATH"
exit
end
function make_crc32
# Prints the CRC32 of the first 500 bytes of the floppy disk.
# No 0x prefix.
set floppy $argv[1]
head -c500 $floppy \
| python -c "import zlib; import sys; print(format(zlib.crc32((sys.stdin.buffer if sys.version_info[0] >= 3 else sys.stdin).read(500)) & 0xFFFFFFFF, '08x'));"
end
function check_floppy
set floppy $argv[1]
# List partitions on the floppy disk device and strip to the volume name.
set list (diskutil list $floppy \
| tail -n +3 \
| grep "1.5 MB" \
| sed 's/^ *[0-9]*: *//g' \
| string sub -s 1 -l 11)
echo $list
end
function find_floppy_drive
set drive (diskutil list \
| awk '/^\// { device=$1 }
$1 == "0:" && $4 == "*1.5" { print device }')
echo $drive
end
function save_floppy
set src $argv[1]
set fn $argv[2]
gdd if=$src status=progress bs=1024 count=1440 > $fn
end
function drive_size
set drive $argv[1]
set out (df -Hl | grep -i "$drive" | awk '{print $2"|"$3"|"$4"|"$5}')
echo $out
end
function main
# Detect the floppy drive and begin listening for new disks.
while true
set drive (find_floppy_drive)
set rawdrive (echo $drive | sed 's/\/disk/\/rdisk/')
if test -n "$drive"
echo (set_color yellow)"Floppy drive: "(set_color normal)"$drive (detected)"
break
end
sleep 1
end
while true
set floppy (check_floppy $drive)
# If no floppy drive found, sleep and try again.
if test -z "$floppy"
sleep 1
continue
end
# Retrieve disk label and CRC32 of the first 500 bytes for uniqueness.
set crc (make_crc32 $rawdrive)
# Convert :\/."' and spaces to underscores for safety.
set label (echo $floppy | sed 's/[ :\/\\\."\']/_/g')
set fn "$dst"/"$label - $crc"".img"
# Check if this disk has been ripped yet.
if test -e $fn
sleep 2
continue
end
set out (drive_size $drive)
set total (echo $out | cut -d'|' -f1)
set used (echo $out | cut -d'|' -f2)
set free (echo $out | cut -d'|' -f3)
set usage (echo $out | cut -d'|' -f4)
# Sometimes we arrive here before the disk has been mounted.
# In that case we've actually taken *1.5 MB, the diskutil size,
# as though it's the partition label.
# If that's so, drive_size will have no output.
if test -z "$total"
sleep 2
continue
end
# Print disk information before ripping.
echo
echo (set_color green)"Found new disk."(set_color white)
echo (set_color blue)"Floppy size: "(set_color normal)"$used ($total total; $usage)"
echo (set_color blue)"Disk label: "(set_color -u white)"$floppy"(set_color normal)
echo (set_color blue)"CRC32 hash: "(set_color white)"$crc"(set_color normal)
echo (set_color purple)"Filename: "(set_color white)"$fn"(set_color normal)
save_floppy $rawdrive $fn
echo (set_color green)"Finished imaging disk. Waiting for next."(set_color normal)
sleep 5
end
check_floppy
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment