#!/bin/bash

# Source common settings
. /etc/owl-setup.conf

dlgresult=''
partbl=''
fstype=''
trap 'rm -f $dlgresult $partbl $fstemp' EXIT HUP INT TERM
dlgresult=`mktemp /var/run/owl-setup.XXXXXX` || exit 1
partbl=`mktemp /var/run/owl-setup.XXXXXX` || exit 1
fstemp=`mktemp $FSTAB.XXXXXX` || exit 1

function type2fs
{
	echo "`grep -Ei "$1[:,]" <<EOF | cut -d : -f2
82:swap
83:ext2
01,04,06:msdos
0b,0c,0e,0f:vfat
EOF`"
}

# def_opt <mount point>
function def_opt
{
	local str i re
	while read str; do
		re="`echo "$str" | cut -d : -f1`"
		if echo "$1" | grep -Eq "$re"; then
			echo "$str" | cut -d : -f2
			break
		fi
	done <<EOF
^/$|^/usr$|^/usr/|^/bin$|^/sbin$:defaults
^none$:sw
^.*$:nosuid
EOF
}

function parse
{
	local STR i dev descr
	cat $partbl | {
		i=1
		while read STR; do
			dev="`echo "$STR" | cut -d ' '  -f1`"
			descr="`echo "$STR" | cut -d ' '  -f3-`"
			echo -n " $dev" \""$descr, ${mntpoint[$i]:-not used}"
			test -n "${mntopt[$i]}" && echo -n " (${mntopt[$i]})"
			echo -n \"
			((i+=1))
		done
	}
	# Print additional menu items
	echo -n " Unlisted 'Add a device not listed above'"
	echo -n " --------- --------------------------------------------"
	echo -n " Save 'Write to fstab'"
	echo -n " Exit 'Exit without saving'"
}

function gen_fstab
{
	local i line dev fsid fstype flags

	test -f $FSTAB &&
		while read line; do
			dev="`echo "$line" | cut -f1 | cut -d ' ' -f1`"
			i="`grep -n "^$dev" $partbl | cut -d : -f1`"
			test -n "${mntpoint[$i]}" 2> /dev/null && continue
			echo "$line" >> $fstemp || exit 1
		done < $FSTAB

	cut -d ' ' -f1,2 < $partbl | {
		i=1
		while read dev fsid; do
			if [ -n "${mntpoint[$i]}" ]; then
				if [ "$fsid" = "82" ]; then
					flags='0 0'
				else
					flags='1 1'
				fi
				fstype=`type2fs $fsid`
				echo -e "$dev\t${mntpoint[$i]}\t\t\t${fstype:-"$fsid"}\t${mntopt[$i]}\t\t$flags" >> $fstemp || exit 1
			fi
			((i+=1))
		done
		mv -f $fstemp $FSTAB
	}
}

# Try to detect Solaris partitions
# param: /dev/<devname>
function detect_solaris
{
	dd if="$1" bs=512 count=1 2>/dev/null | strings -n 32 | grep -iq SOLARIS
}

######################
#  Main
##

if [ ! -x "$FDISK" ]; then
	echo "Error: $FDISK not found, exiting..."
	exit 1
fi

UMOUNT_PROC=
if $FDISK -l 2>&1 | grep -q /proc/partitions; then
	mount /proc && UMOUNT_PROC=yes
fi

$FDISK -l | grep '^/dev' | sed -e 's/  */ /g' |
	while read STR; do

		if echo "$STR" | cut -d ' ' -f2 | grep -Eq '[0-9]+'; then
			o=0
		else
			o=1
		fi

		dev="`echo "$STR" | cut -d ' '  -f1`"
		id="`echo "$STR" | cut -d ' '  -f$[5+$o]`"
		descr="`echo "$STR" | cut -d ' '  -f$[6+$o]-`"

		# Type 82, may mean Solaris
		if [ "$id" = '82' ]; then
			detect_solaris "$dev" && descr="$descr (or Solaris)"
		fi

		echo "$dev $id $descr" >> $partbl
	done

test -n "$UMOUNT_PROC" && umount /proc

while :; do
	eval "$DIALOG --backtitle '$TITLE' --title 'fstab setup' --menu 'device, fs type, mount point, mount options' 0 0 0" \
		"`parse`" 2>$dlgresult || break
	mntdev="`cat $dlgresult`"

	case "$mntdev" in
		Unlisted)
			$DIALOG --backtitle "$TITLE" --clear --inputbox "Device name" 0 0 \
				'/dev/' 2>$dlgresult || continue
			mntdev="`cat $dlgresult`"
			[ -n "$mntdev" ] || continue

			if grep -q "^${mntdev} " "$partbl"; then
				$DIALOG --backtitle "$TITLE"\
					--title 'Error' --msgbox "\n$mntdev is already listed\n" 0 0
				continue
			fi

			$DIALOG --backtitle "$TITLE"\
				--clear --inputbox "Filesystem type (ext2, swap, ...)" 0 0 \
				2>$dlgresult || continue
			fstype="`cat $dlgresult`"
			[ -n "$fstype" ] || continue

			echo "$mntdev $fstype $fstype" >> $partbl
		;;

		Save)
			IFS=$'\n'
			n="`echo "${mntpoint[*]}" | grep -c '^/$'`"
			m="`echo "${mntpoint[*]}" | grep -c '^swap$'`"
			unset IFS
			if [ $n -lt 1 -o $m -lt 1 ]; then
				$DIALOG --backtitle "$TITLE" --title 'Error' \
					--yesno "\nYou haven't specified a root and/or swap device. Continue anyway?\n" 0 0 \
				2>$dlgresult || continue
				[ $? -eq 0 ] || continue
			fi

			gen_fstab

			$DIALOG --backtitle "$TITLE"\
				--title 'Info'\
				--msgbox 'If needed, mkfs and mkswap your devices manually.' 0 0
			exit 0
		;;

		Exit)
			exit 0
		;;
	esac

	n="`sed -n "\,${mntdev}\ ,=" $partbl 2>/dev/null | tail -1`"
	[ -n "$n" ] || continue

	fstype="`sed -n ${n}p <$partbl | cut -d ' '  -f2`"

	if [ "$fstype" = 'swap' -o "`type2fs "$fstype"`" = 'swap' ]; then
		mntpoint[$n]=${mntpoint[$n]:-'swap'}
		mntopt[$n]=${mntopt[$n]:-'defaults'}
	fi

	$DIALOG --backtitle "$TITLE"\
		--clear --inputbox "Mount point for $mntdev" 0 0\
		"${mntpoint[$n]}" 2>$dlgresult || continue
	mntpoint[$n]="`cat $dlgresult`"
	[ -n "${mntpoint[$n]}" ] || continue

	$DIALOG --backtitle "$TITLE"\
		--clear\
		--inputbox "Mount options for $mntdev" 0 0 \
		"${mntopt[$n]:-`def_opt ${mntpoint[$n]}`}" 2>$dlgresult || continue
	mntopt[$n]="`cat $dlgresult`"
done
