#!/usr/local/bin/cbsd
#v10.1.2
globalconf="${workdir}/cbsd.conf";
MYARG="jroot fstab"
MYOPTARG="jname"
MYDESC="Mount jail by fstab file"
ADDHELP="jroot - root of jail, fstab - fstab file\n"

set -e
. ${globalconf}
set +e

. ${subr}
. ${system}
init $*

[ ! -f "${fstab}" ] && err 1 "${fstab} does not exist"
[ ! -d "${jroot}" ] && err 1 "${jroot} does not exist"

# local fstab exist ?
have_local=0

# special sign for zfs attach
with_zfs_attach="${jailsysdir}/${jname}/with_zfs_attach"

init_localmpt_fstab()
{
	local _ret=
	[ ! -f "${fstab}.local" ] && return 0

	have_local=1

	local i=0

	# always rewrite CBSDROOT first
	replacewdir file0="${fstab}.local" old="CBSDROOT"

	eval $( /bin/cat ${fstab}.local | while read _device _mountpt _fs _mode _a _b; do

		[ -z "${_mountpt}" ] && continue

		case ":${_device}" in
			:#* | :)
			continue
			;;
			*)
				if [ "${_fs}" = "zfs" ]; then
					# we need special route for jails with zfs attach, make sign for jstart script
					/usr/bin/touch ${with_zfs_attach}
					continue
				else
					echo "local_mpt${i}=\"${_mountpt}\""
					i=$(( i + 1 ))
				fi
			;;
		esac
	done )
}

# return 0 if no such mount point in fstab.local exist
# return 1 if exist
# $1 - test mpt
# example:
# if ! check_for_localmpt_fstab /tmp; then
#		echo "EXIST"
# fi
check_for_localmpt_fstab()
{
	local _res=0 i local_mpt

	[ -z "${1}" ] && return 0

	for i in $( /usr/bin/seq 0 128 ); do
		eval local_mpt="\$local_mpt${i}"
		[ -z "${local_mpt}" ] && break
		[ "${local_mpt}" = "${1}" ] && _res=1 && break
	done

	return ${_res}
}

## MAIN
init_localmpt_fstab

# always rewrite CBSDROOT first
replacewdir file0="${fstab}" old="CBSDROOT"

# first pass: test for fstab is valid
/bin/cat ${fstab} | while read _device _mountpt _fs _mode _a _b; do

	case ":${_device}" in
		:#* | :)
		continue
		;;
	*)
		if [ "${_fs}" = "zfs" ]; then
			[ ${allow_zfs} -ne 1 ] && ${ECHO} "${MAGENTA}Warning: fstab have zfs: ${GREEN}${_device}${MAGENTA}, but ${GREEN}allow_zfs=0${MAGENTA}. Please enable it.${NORMAL}"
			# we need special route for jails with zfs attach, make sign for jstart script
			/usr/bin/touch ${with_zfs_attach}
			continue
		fi

		if [ "${_fs}" = "geli" ]; then
			is_mounted ${gelidir} && continue
			err 1 "Error: ${gelidir} is not initializated. Please use: 'cbsd geli mode=initmaster' first"
		fi
		[ -z "${_device}" ] && continue
		# append workdir if it not full path
		prefix=$( substr --pos=0 --len=1 --str=${_device} )
		[ "${prefix}" != "/" ] && _device="${workdir}/${_device}"
		;;
	esac
done

/bin/cat ${fstab} | while read _device _mountpt _fs _mode _a _b; do
	[ "${_fs}" = "zfs" ] && continue
	case ":${_device}" in
		:#* | :)
		continue
		;;
	esac

	# SKIP mount when mount point also exist in fstab.local. fstab.local is preferred
	if [ ${have_local} -eq 1 ]; then
		if ! check_for_localmpt_fstab ${_mountpt}; then
			continue
		fi
	fi

	mnt=0
	prefix=$( substr --pos=0 --len=1 --str=${_device} )

	if [ "${_fs}" = "geli" ]; then
		# prepare src part
		if [ "${prefix}" != "/" ]; then
			if [ -z "${jname}" ]; then
				_device="${workdir}/${_device}"
			else
				_device="${jailsysdir}/${jname}/${_device}"
			fi
		fi
		attachgeli file="${_device}" dst="${jroot}${_mountpt}" mode="${_mode}"
		continue
	fi

	[ "${prefix}" != "/" ] && _device="${workdir}/${_device}"

	if is_mounted "${jroot}${_mountpt}"; then
		echo "${jroot}${_mountpt} already mounted"
		mnt=1
	fi

	if [ ${mnt} -eq 0 ]; then

		# /usr/compat - work-around for migrate from /usr/compat -> /compat introduced in CBSD 11.0.16
		if [ "${_mountpt}" != "/usr/compat" ]; then
			[ ! -d "${jroot}${_mountpt}" ] && /bin/mkdir -p "${jroot}${_mountpt}"
		fi

		if [ ! -d "${jroot}${_mountpt}" ]; then

			# /usr/compat - work-around for migrate from /usr/compat -> /compat introduced in CBSD 11.0.16
			if [ "${_mountpt}" = "/usr/compat" ]; then
				_mountpt="/compat"
				[ ! -d "${jroot}${_mountpt}" ] && /bin/mkdir -p "${jroot}${_mountpt}"
			else
				echo "Warning: Can't create ${jroot}${_mountpt} - permission problem ?"
			fi
		fi

		/sbin/mount -t ${_fs} -o${_mode} ${_device} ${jroot}${_mountpt}
	fi
done
