#
# optparttn
#
# Allocate any disk free space into user partitions.
#

set -ue
myname=${0}
args="${*:-}"

dir=/usr
seq=2

p_0=0	p_1=1	p_2=2	p_3=3	p_4=4	p_5=5	p_6=6	p_7=7
p_8=8	p_9=9	p_a=10	p_b=11	p_c=12	p_d=13	p_e=14	p_f=15

cylsize=1
drive=
rel=unk
root=/
SAflag=n

fstab=
mountdir=

Again()
{
	Undo $*
	exec ${myname} ${args}
}

Cleanup()
{
	Undo $*
	exit 1
}

Undo()
{
	level=0
	while [ $# -ge 2 ]
	do
		eval dev_${level}=\${1} dir_${level}=\${2}
		level=`ignore expr ${level} + 1`
		shift 2
	done
	while [ ${level} -ne 0 ]
	do
		level=`ignore expr ${level} - 1`
		eval dev=\${dev_${level}} dir=\${dir_${level}}
		unmnt ${dev}
		part=`ignore expr ${dev} : '.*\(.\)$'`
		eval partno=\${p_${part}}
		eval fmthard -d ${partno}:0:1:0:0 ${devraw}${part} > /dev/null
		rrmdir -r ${root} ${dir}
	done
}

while [ $# -ne 0 ]
do
	case "${1}" in
	-c)
		cylsize="${2}" ; shift 2 ;;
	-d)
		drive="${2}" ; shift 2 ;;
	-g)
		rel="${2}" ; shift 2 ;;
	-r)
		root="${2}" ; shift 2 ;;
	-S)
		SAflag=y ; shift 1 ;;
	-*)
		echo "${myname}: \"${2}\": Unknown option" >&2 ; exit 1 ;;
	*)
		break ;;
	esac
done

if [ $# -ne 1 ]
then
	echo "\
Usage:	${myname} [ -c cylsize ] [ -d drivename ] [ -g release ]
	[ -r rootdir ] devprefix" >&2
	exit 1
fi

if expr ${1} : /dev/r > /dev/null
then
	devraw=${1}
	devblk=/dev/`ignore expr ${1} : '/dev/r\(.*\)'`
else
	echo "${myname}: ${1}: Device name must begin with \"/dev/r\"" >&2
	exit 1
fi

if [ ${SAflag} = y ]
then
	mnt()	{ /etc/mount ${1} ${2} && chmod 775 ${2} ; }
	unmnt()	{ /etc/umount ${1} ; }
else
	mnt()	{ fsys -m ${2} -c 775 ${1} ; }
	unmnt()	{ fsys -u ${1} ; }
fi

while true
do
	#
	# "prtvtoc -f" prints several shell variable assignments:
	#	FREE_PART	Concanentaion of free partition names (0-f)
	#	FREE_START	Initial block of first chunk of free space
	#	FREE_SIZE	Size of first chunk of free space
	#	FREE_COUNT	Number of chunks of free space
	#
	eval `prtvtoc -f ${devraw}6`
	if [ ${FREE_COUNT} -eq 0 ]
	then
		break
	fi
	echo "
There are ${FREE_SIZE} blocks remaining${drive:+ on disk ${drive}}." >&2
	FREE_PART=`ignore expr "${FREE_PART}" : '[0-7]*\(.*\)'`
	while [ ${FREE_SIZE} -ne 0 ]
	do
		use_part=`ignore expr "${FREE_PART}" : '\(.\)'`
		eval use_partno=\${p_${use_part}}
		use_have=`ignore expr "${FREE_PART}" : '.*'`
		case ${use_have} in
		0)
			echo "${myname}: ${devraw}?: Out of partitions!" >&2
			exit 1
			;;
		${FREE_COUNT})
			echo "
Allocating ${FREE_SIZE} blocks to${drive:+ disk ${drive}} partition ${use_partno}." >&2
			use_size=${FREE_SIZE}
			;;
		*)
			use_size=`askx -s -q "\
How many blocks for${drive:+ disk ${drive}} partition ${use_partno}?" \
			    -h "\
There are ${FREE_SIZE} blocks remaining${drive:+ on disk ${drive}}. \
They may be distributed amongst
one or more of the ${use_have} remaining partitions. Enter the \
number of blocks to be
allocated to partition ${use_partno}, \"again\" to reallocate the \
optional partitions
${drive:+on disk ${drive} }or \"quit\" to quit." \
			    -c again -c quit -n 0:${FREE_SIZE} -d ${FREE_SIZE}`
			if [ "${use_size}" = again ]
			then
				Again ${fstab}
			elif [ "${use_size}" = quit ]
			then
				if [ -n "${fstab}" ]
				then
					Cleanup ${fstab}
				else
					exit 1
				fi
			fi
			use_size=`ignore expr \( ${use_size} + ${cylsize} - 1 \) / ${cylsize} \* ${cylsize}`
			if [ ${use_size} -gt ${FREE_SIZE} ]
			then
				use_size=${FREE_SIZE}
			fi
			;;
		esac
		FREE_PART=`ignore expr "${FREE_PART}" : '.\(.*\)'`
		if [ ${use_size} -eq 0 ]
		then
			continue
		fi
		while true
		do
			while [ -r ${root}/${dir}${seq} ]
			do
				seq=`ignore expr ${seq} + 1`
			done
			use_dir=`askx -q "\
Upon what directory should the file system within ${drive:+ disk ${drive}} partition ${use_partno} 
be mounted?" \
			    -h "\
Enter the absolute directory name upon which this ${use_size}-block file system
should be mounted. If you just hit <RETURN>, the file system will be mounted
as \"${dir}${seq}\". See the \"3B2 System Owner/Operator Manual\" for more
information about directory and file names.

You may also enter \"again\" to reallocate the optional partitions
${drive:+on disk ${drive} }or \"quit\" to quit." \
			    -c again -c quit -p -d ${dir}${seq}`
			if [ "${use_dir}" = again ]
			then
				Again ${fstab}
			elif [ "${use_dir}" = quit ]
			then
				if [ -n "${fstab}" ]
				then
					Cleanup ${fstab}
				else
					exit 1
				fi
			elif [ ! -r ${root}${use_dir} ]
			then
				if (umask 022 ; exec rmkdir ${root}${use_dir})
				then
					break
				fi
			fi
			echo "
${use_dir} already exists; please choose a new directory name." >&2
		done
		fmthard -d ${use_partno}:0:0:${FREE_START}:${use_size} ${devraw}${use_part} > /dev/null
		FREE_START=`ignore expr ${FREE_START} + ${use_size}`
		FREE_SIZE=`ignore expr ${FREE_SIZE} - ${use_size}`
		vmkfs ${devraw}${use_part} > /dev/null
		labelit ${devraw}${use_part} `ignore expr ${use_dir} : '.*/\(.*\)$' \| ${use_dir}` ${rel} > /dev/null
		mountdir=`ignore expr "${root}${use_dir}" : "/*\(/.*\)"`
		mnt ${devblk}${use_part} ${mountdir}
		mklost+found ${root}/${use_dir} ${devblk}${use_part}
		fstab="${fstab} ${devblk}${use_part} ${use_dir}"
	done
done
if [ -n "${fstab}" ]
then
	set -- ${fstab}
	while [ $# -ne 0 ]
	do
		echo "${1}\t${2}"
		shift 2
	done
fi