#!/bin/sh
: <<END
    floppyinfo: show information about the contents of a floppy image.

    Copyright (C) 2013 Adam Sampson <ats@offog.org>

    Permission to use, copy, modify, and/or distribute this software for
    any purpose with or without fee is hereby granted, provided that the
    above copyright notice and this permission notice appear in all
    copies.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
    WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
    AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
    DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
    PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
    TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
END

tempdir=`mktemp -d`
trap 'rm -fr $tempdir' 0

extractdir=""
imdcatflags=""

show_imd () {
	fn="$1"
	echo
	echo "$fn"
	imdcat -n "$fn" | tail -n +2 | sed 's,^,  | ,'

	imdcat $imdcatflags -c2: -C0: -o $tempdir/whole.img "$fn"
	size=`stat -c '%s' $tempdir/whole.img`

	flags=""
	cpmtype=""
	case $size in
	81920)
		# RM SS 40T 16x128
		flags="-c2: -C0:"
		sides="0"
		cpmtype="rm-sd"
		;;
	163840)
		# RM DS 40T 16x128
		flags="-c2: -C0:"
		sides="0 1"
		cpmtype="rm-sd"
		;;
	184320)
		# RM SS 40T 9x512
		flags="-c2: -C0:"
		sides="0"
		cpmtype="rm-dd"
		;;
	# FIXME: 368640 is also MS-DOS 360k
	368640)
		# RM DS 40T 9x512
		flags="-c2: -C0:"
		sides="0 1"
		cpmtype="rm-dd"
		;;
	# FIXME: RM SS 80T 9x512? Need an example of one!
	737280)
		# RM DS 80T 9x512
		flags="-c2: -C0:"
		sides="0 1"
		cpmtype="rm-qd"
		;;
	327680)
		# Alphatronic PC 40T 16x256
		# FIXME: This doesn't do the right thing for the ZCPR
		# disks I have...
		sides="both"
		cpmtype="alpha"
		;;
	# FIXME: RM disks formatted differently on each side
	*)
		echo >&2 "$fn has unrecognised size: $size"
		return 1
		;;
	esac

	diskname="$(basename "$fn" | sed 's,\.[a-zA-Z]*$,,')"
	for side in $sides; do
		img=$tempdir/side$side.img
		diskdir="$extractdir/$diskname"
		if [ $side = both ]; then
			sideflags=""
			label="Both sides"
		else
			sideflags="-h $side"
			label="Side $side"
			diskdir="$diskdir/side$side"
		fi
		imdcat $imdcatflags $flags $sideflags -o $img "$fn"

		if [ -n "$cpmtype" ]; then
			echo
			echo "  $label (CP/M $cpmtype):"
			echo `cpmls -f $cpmtype $img | egrep -v '^[0-9]+:$'` | sort | fmt -w60 | sed 's,^,    ,'

			if [ -n "$extractdir" ]; then
				for user in `seq 0 15`; do
					dir="$diskdir/user$user"
					mkdir -p "$dir"
					cpmcp -f $cpmtype $img $user:'*' $user:'*.*' "$dir" 2>&1 | grep -v "can not open"
					rmdir "$dir" 2>/dev/null
				done
			fi
		fi
	done
}

while getopts "i:x:" c; do
	case $c in
	i)
		imdcatflags="$OPTARG"
		;;
	x)
		extractdir="$OPTARG"
		;;
	\?)
		cat <<END
usage: floppyinfo [OPTION]... IMAGE-FILE ...
  -i FLAGS   pass extra options FLAGS to imdcat
  -x DIR     extract contents of each disk into DIR
END
		exit 1
		;;
	esac
done
shift `expr $OPTIND - 1`

for fn in "$@"; do
	show_imd "$fn"
done
