#!/bin/sh

# fixme: work with msdos directory too, and non-free and contrib

set -e
vardir="$1"
method=$2
option=$3

cd "$vardir/methods/disk"
tp=/tmp/ddm$$

xit=1
trap '
	rm -f $tp.?
	if [ -n "$umount" ]
	then
		umount "$umount"
	fi
	exit $xit
' 0

if ls -d "$tp.?" >/dev/null 2>&1
then
	rm $tp.?
fi

yesno () {
	while true
	do
		echo -n "$2 [$1]  "
		read response
		if [ -z "$response" ]
		then
			response="$1"
		fi
		case "$response" in
		[Nn]*)	yesno=no ; return ;;
		[Yy]*)	yesno=yes ; return ;;
		esac
	done
}

getblockdev () {
	mountpoint="$vardir/methods/mnt"
	if [ -z "$defaultdevice" ]
	then
		defaultdevice="$newdefaultdevice"
	elif [ "$defaultdevice" != "$newdefaultdevice" ]
	then
		echo \
	"Last time you specified installation from $defaultdevice."
	fi
	promptstring="$1"
	while [ -z "$blockdevice" ]
	do
		echo -n "$promptstring [$defaultdevice]:  "
		read response
		if [ -z "$response" ]
		then
			response="$defaultdevice"
		fi
		if ! [ -b "$response" ]
		then
			echo "$response is not a block device."; continue
		fi
		tryblockdevice="$response"
		if [ $option = cdrom ]
		then
			fstype=iso9660
		elif [ $option = harddisk ]
		then
			blockbase="`echo \"$tryblockdevice\" | sed -e 's/[0-9]\{1,\}$//'`"
			set +e
			echo -e "p\nq\n" | fdisk "$blockbase" 2>/dev/null >$tp.f
			set -e
			proposeddevice="$tryblockdevice" perl -ne '
next unless /^ *Device +Boot +Begin +Start +End +Blocks +Id +System *$/i .. !/\S/;
next unless s:^/\S+:: && $& eq $ENV{"proposeddevice"};
next unless s/^ +(\* +)?\d+ +\d+ +\d+ +\d+\+? +//;
next unless m/^([0-9a-f]{1,2}) /i;
%types= ( "1","msdos", "4","msdos", "6","msdos", "7","hpfs", "80","minix",
          "81","minix", "83","ext2" );
print $types{$1}; exit(0);	' <$tp.f >$tp.m
			defaultfstype="`cat $tp.m`"
			if [ -n "$defaultfstype" ]
			then
				cat <<END
The partition table for $blockbase claims that $tryblockdevice
contains filesystem type $defaultfstype.
END
				if ! grep "	$defaultfstype$" /proc/filesystems >/dev/null
				then
					echo \
	"Your kernel does not appear to support that filesystem type."
					defaultfstype=""
				fi
			fi
			echo -n "Supported filesystems: "
			sed -e 's/^.*	/ /' /proc/filesystems | tr '\n' ' '
			echo -n "
Enter filesystem type (for $tryblockdevice) [$defaultfstype]:  "
			read fstype
			if [ -z "$fstype" ]
			then
				fstype="$defaultfstype"
			fi
		fi
		umount="$tryblockdevice"
		if mount -rt "$fstype" "$tryblockdevice" "$mountpoint"
		then
			echo
			blockdevice="$tryblockdevice"
		else
			umount=""
			echo \
	"Unable to mount $tryblockdevice on $mountpoint, type $fstype."
		fi
	done
}

checkdefaultpackages () {
	if [ -z "$defaultpackages" -a -f "$mountpoint$1" ]
	then
		echo "There is a file $1."
		defaultpackages="$1"
	fi
}

outputparam () {
	echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3
}

intrkey="`stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p'`"
echo "
If you make a mistake, use the interrupt key ($intrkey) to abort.
"

# State variables, `best first'
#  directory
#   The directory to attempt to use to find the binary, Packages, non-free, &c.
#   empty or unset if we don't know yet
#  mountpoint
#   The mountpoint for the filesystem containing the stuff
#   empty or unset if we don't know yet, or if we haven't mounted anything;
#   may also be empty if `directory' was set.
#  blockdevice
#   The actual block device to mount.
#  fstype
#   The filesystem type to use.
#  defaultdevice
#   The default block device to mount.

if [ -f shvar.$option ]
then
	. ./shvar.$option
	defaultdevice="$p_blockdev"
	lastbinary="$p_binary"
fi

if [ $option = cdrom ]
then
	mount >$tp.m
	sed -n 's/ ([^)]*)$//; s/^[^ ]* on //; s/ type iso9660$//p' <$tp.m >$tp.l
	ncdroms=`wc -l <$tp.l`
	if [ $ncdroms -gt 1 ]
	then
		response=""
		while [ -z "$response" ]
		do
			echo \
	'Several CD-ROMs (or other ISO9660 filesystems) are mounted:'
			egrep 'type iso9660 \([^)]*\)$' <$tp.m | nl
			echo -n \
	'Is it any of these ?  Type a number, or `n'\'' for none.  '
			read response
			response="`echo \"$response\" | sed -e 's/[ 	]*$//'`"
			if expr "$response" : '[0-9][0-9]*$' >/dev/null && \
			   [ $response -ge 1 -a $response -le $ncdroms ]
			then
				mountpoint="`sed -n $response'p' <$tp.l`"
				echo
			elif expr "$response" : '[Nn]' >/dev/null
			then
				mountpoint=""
			else
				response=""
			fi
		done
	elif [ $ncdroms = 1 ]
	then
		mountpoint="`cat $tp.l`"
		perl -ne 'print if s/ type iso9660 \([^)]*\)$// && s/ on .*$//;' \
			<$tp.m >$tp.d
		blockdevice="`cat $tp.d`"
		yesno yes \
	"I see a CD-ROM: $blockdevice, mounted on $mountpoint.  "'Is it the right one ?'
		if [ $yesno = no ]
		then
			echo 'Unmounting it ...'
			umount="$mountpoint"
			while true
			do
				echo -n \
	'Please insert the right disc, and hit return:  '
				read response
				if mount -rt iso9660 "$blockdevice" "$mountpoint"
				then
					echo
					break
				fi
			done
		fi
	fi
	if [ -z "$mountpoint" ]
	then
		if [ -b /dev/cdrom ]
		then
			echo \
	'I see that /dev/cdrom exists and is a block device.'
			newdefaultdevice=/dev/cdrom
		fi
		getblockdev 'Insert the CD-ROM and enter the block device name'
	fi
fi

if [ $option = harddisk ]
then
	yesno '' 'Is the partition or filesystem already mounted ?'
	if [ $yesno = yes ]
	then
		echo
	else
		set +e
		echo -e 'p\nq\n' | fdisk /dev/hda 2>/dev/null >$tp.f
		if [ $? != 0 ]
		then
			echo -e 'p\nq\n' | fdisk /dev/sda 2>/dev/null >$tp.f
		fi
		set -e
		perl -ne '
next unless /^ *Device +Boot +Begin +Start +End +Blocks +Id +System *$/i .. !/\S/;
next unless / [146] +DOS \d+-bit \S+$/;
next unless m:^/\S+:;
print $&;		' <$tp.f >$tp.d
		newdefaultdevice="`cat $tp.d`"
		if [ -n "$newdefaultdevice" ]
		then
			echo \
	"Your partition table claims that $newdefaultdevice is a DOS partition."
		fi
		getblockdev 'Enter the block device for the partition'
	fi
fi

if [ -n "$mountpoint" ]
then
	# We must have $mountpoint
	if [ $option = cdrom ]
	then
		echo \
	'All directory names should be entered relative to the root of the CD-ROM.)
'
	else
		echo \
"All directory names should be entered relative to the root of the
$fstype filesystem on $blockdevice.)
"
	fi
fi

if [ -n "$lastbinary" -a -d "$mountpoint$lastbinary" ]
then
	echo \
"Last time you specified $lastbinary as the \`binary'
directory, and that directory exists."
	defaultbinary="$lastbinary"
elif [ -z "$mountpoint" ]
then
	: # Who knows ?
elif [ -d "$mountpoint/binary" ]
then
	echo \
"I see a \`binary' directory at the top level."
	defaultbinary=/binary
elif [ -d "$mountpoint/debian/binary" ]
then
	echo \
"I see a \`debian' directory at top level, with a \`binary' subdirectory."
	defaultbinary=/debian/binary
else
	echo \
"I don't see an obvious \`binary' directory anywhere.  You'll have to tell me."
fi

while [ -z "$binary" ]
do
	echo -n \
'Which directory contains the *.deb packages (this directory is usually
named `binary'\'') ['"$defaultbinary"'] ?  '
	read response
	case "$response" in
	'')	response="$defaultbinary"	;;
	/*)					;;
	*)	response="/$response"		;;
	esac
	if [ -z "$response" ]
	then
		continue
	elif find "$mountpoint$response" -name '*.deb' 2>/dev/null | grep . >/dev/null
	then
		echo
		binary="$response"
	else
		echo 'There do not appear to be any packages there.'
	fi
done

checkdefaultpackages "$binary/Packages"
checkdefaultpackages "$binary/packages"
checkdefaultpackages "`echo \"$binary\" | sed -e 's:/binary$:/Packages:'`"
checkdefaultpackages "`echo \"$binary\" | sed -e 's:/binary$:/packages:'`"

if [ -z "$defaultpackages" ]
then
	cat <<'END'

Warning: I can't find the `Packages' file.  The information in the
`Packages' file is important for package selection during new
installations, and is very useful for upgrades.  If you overlooked it when
downloading you should do get it now and return to this installation
procedure when you have done so.  You should find it with the *.deb files,
in the `binary' directory on FTP sites or CD-ROMs.

END
fi

while [ -z "$packages" ]
do
	echo -n \
'Where is the `Packages'\'' file (if there is really none available,
say `none'\'')  ['"$defaultpackages"'] ?  '
	read response
	case "$response" in
	'') 		response="$defaultpackages"	;;
	none)		break				;;
	/*)						;;
	*)		response="/$response"		;;
	esac
	if [ -z "$response" ]
	then
		continue
	elif [ "$response" = none -o -f "$mountpoint$response" ]
	then
		echo
		packages="$response"
	else
		echo "There is no such file."
	fi
done

# fixme: support for non-free

exec 3>shvar.$option.new

outputparam p_blockdev "$blockdevice"
outputparam p_fstype "$fstype"
outputparam p_mountpoint "$mountpoint"
outputparam p_packages "$packages"
outputparam p_binary "$binary"

mv shvar.$option.new shvar.$option

xit=0
