#!/usr/local/bin/cbsd
#v11.1.2
MYARG=""
MYOPTARG="jname remote inter src_session user"
MYDESC="Exec login into jail"
CBSDMODULE="jail"
ADDHELP="remote=1 - prevent to searching in remote node base. For the avoid the looping\n\
user= login from the specified user. Default is: root"
EXTHELP="wf_jlogin.html"

# Login by jid not supported yet

. ${subr}
. ${strings}
. ${tools}

init $*
readconf jlogin.conf

try_remote()
{
	[ "${remote}" = "1" ] && err 1 "${MAGENTA}No such jail${NORMAL}"
	RHST=$( jwhereis ${jname}| /usr/bin/head -n1 )
	[ -z "${RHST}" ] && err 1 "No such jail for login"

	# we don't need for interactive when come with remote=2 from select_jail_by_list
	if [ "${remote}" != "2" -a "${always_rlogin}" = "0" ]; then
		getyesno "Found jail on remote node: ${RHST}. Try to login?"
		[ $? -eq 1 -o $? -eq 3 ] && err 1 "No such jail for login"
	fi

	rexe node=${RHST} /usr/local/bin/cbsd jlogin src_session=${nodename} jname=${jname} remote=1
	err 0 ""
}

init_tmux()
{
	if [ "${tmux_login}" != "1" -o -z "${src_session}" ]; then
		tmux_login=0
		return 0
	fi

	tmuxcmd=$( which tmux 2>/dev/null )

	src_session="$( /usr/bin/whoami )-nodename"
	session_name="${src_session}-${jname}"

	if [ -n "${tmuxcmd}" ]; then
		# tmux here and we preferred them
		return 0
	fi

	# no tmux here
	tmux_login=0
	return 0
}


login_internal()
{
	local _res
	local _formfile

	#rctl/limits area
	. ${workdir}/rctl.subr

	_formfile="${jailsysdir}/${jname}/helpers/jrctl.sqlite"
	[ -r "${_formfile}" ] && nice=$( cbsdsql ${_formfile} "SELECT cur FROM forms WHERE param=\"nice\"" )
	[ -z "${nice}" ] && nice="0"

	if [ ${exec_fib} -eq 0 ]; then
		SETFIB=""
	else
		SETFIB="/usr/sbin/setfib ${exec_fib}"
	fi

	if [ "${cpuset}" = "0" ]; then
		CPUSET=""
	else
		CPUSET="/usr/bin/cpuset -c -l ${cpuset}"
	fi

	case "${ver}" in
		"empty")
			# is linux?
			if [ -f "${data}/bin/bash" ]; then
				LOGIN_STR="/bin/bash"
			elif [ -f "${data}/bin/sh" ]; then
				LOGIN_STR="/bin/sh" ];
			else
				err 1 "${MAGENTA}Unknown environment, unable to login${NORMAL}"
			fi
			;;
		*)
			if [ "${user}" != "root" ]; then
				# additional check for user existance
				_res=$( /usr/sbin/pw -R ${path} usershow ${user} 2>&1 )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Unable to find user: ${_res}${NORMAL}"
			fi

			if [ "${emulator}" != "jail" -a -n "${emulator}" ]; then
				. ${workdir}/emulator.subr
				init_usermode_emul
				LOGIN_STR="/bin/${emulator} /usr/bin/login -f ${user}"
			else
				LOGIN_STR="/usr/bin/login -f ${user}"
			fi
			;;
	esac

	jexec="/usr/bin/nice -n ${nice} ${SETFIB} ${CPUSET} /usr/sbin/jexec ${jid} ${LOGIN_STR}"

	init_tmux

	cbsdlogger NOTICE ${CBSD_APP}: executing jexec string for login: ${jexec}

	if [ ${tmux_login} -eq 1 ]; then
		${tmuxcmd} list-sessions | ${GREP_CMD} -qwF "${session_name}:"
		if [ $? -eq 1 ]; then
			${tmuxcmd} new -s "${session_name}" "eval ${jexec}"
		else
			${tmuxcmd} attach-session -t "${session_name}"
		fi
	else
		eval ${jexec}
	fi
}

login_custom()
{
	# reset PATH to default
	local CBSDPATH="${PATH}"
	# reset CBSD PATH
	export PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
	. ${workdir}/jcreate.subr	# for export_jail_data_for_external_hook
	export_jail_data_for_external_hook
	readconf jlogin.conf
	${ECHO} "${MAGENTA}Custom login command: ${GREEN}${login_cmd}${NORMAL}"
	exec /bin/sh -c "${login_cmd}"
	# restore CBSD PATH
	export PATH="${CBSDPATH}"
}

if [ -z "${user}" ]; then
	user="root"
else
	shift
fi

emulator="jail"		# for jname_is_multiple
jname_is_multiple	# import jail_list if jname is mask

if [ -n "${jail_list}" ]; then
	${ECHO} "${MAGENTA}Found jails by mask: ${GREEN}${jail_list}${NORMAL}"
	for jname in ${jail_list}; do
		${ECHO} "${MAGENTA}exec jlogin to: ${GREEN}${jname}${NORMAL}"
		jlogin jname=${jname}
	done
	exit 0
fi


[ -z "${jname}" ] && jname=$1
[ -z "${jname}" ] && select_jail_by_list -s "List of online jail" -a "On" -r ${sqlreplica}
[ -z "${jname}" ] && err 1 "${MAGENTA}Please specify jname as argument${NORMAL}"
[ -z "${remote}" ] && remote=0

validate_jname ${jname}
[ $? -ne 1 ] && err 1 "${MAGENTA}Bad jname${NORMAL}"

. ${jrcconf}
[ $? -eq 1 ] && try_remote
[ "${emulator}" = "bhyve" ] && err 1 "${MAGENTA}For bhyve jail use: ${GREEN}cbsd blogin=${jname} ${MAGENTA}instead${NORMAL}"
[ "${baserw}" = "1" ] && path=${data}
[ ${jid} -eq 0 ] && err 1 "Not running"

readconf jlogin.conf

cbsdlogger NOTICE ${CBSD_APP}: login into ${jname}

case "${login_cmd}" in
	internal)
		login_internal
		;;
	*)
		login_custom
		;;
esac
