#!/bin/sh
#v11.1.11
export distdir=${distdir:-"/usr/local/cbsd"}
globalconf="${distdir}/cbsd.conf";
MYLOCK="/tmp/initenv.lock"
MYDESC="Node re-initialization"
MYARG=""
MYOPTARG=""

first_init=1

if [ ! -f "${globalconf}" ]; then
	${ECHO} "${MAGENTA}no such conf file${NORMAL}";
	exit
fi

if [ "$1" = "--help" ]; then
	echo "${MYDESC}"
	exit 0
fi

if [ "$1" = "inter=0" ]; then
	inter=0
	shift
fi

if [ -n "${1}" -a -f "${1}" ]; then
	INITCFG="${1}"
	shift
	. ${INITCFG}
fi

# create and store directory ID for relevant to sharedfs dirs
make_fs_id()
{
	local _id _dir

	for i in jaildatadir jailsysdir jailrcconfdir dbdir; do
		_dir=
		eval _dir="\$${i}"
		if [ ! -r ${_dir}/dir.id ]; then
			[ -z "${_id}" ] && _id=$( /usr/bin/head -c 30 /dev/random | /usr/bin/uuencode -m - | /usr/bin/tail -n 2 | /usr/bin/head -n1 )
			${ECHO} "${MAGENTA} * write directory id: ${i}${NORMAL}"
			echo "${_id}" > ${_dir}/dir.id
		fi
	done
}

desc_question()
{
	local _DEFAULT
	local _DESC

	if [ "${inter}" = "0" ]; then
		eval answ=\$$1
		return 0
	fi

	eval _DEFAULT="\$${1}_default"
	eval _DESC="\$${1}_desc"

	case "$1" in
		"fbsdrepo")
			if getyesno "${1}: ${_DESC} for fetching base/kernel?"; then
				answ=1
			else
				answ=0
			fi
			return 0
		;;
		"hammerfeat")
			if getyesno "${1}: You are running on a HAMMERFS-based system. ${_DESC}"; then
				answ=1
			else
				answ=0
			fi
			return 0
		;;
		"jnameserver")
			${ECHO} "${BOLD}${1}: ${_DESC} (for jails resolv.conf), e.g.: ${GREEN}${_DEFAULT}${NORMAL}"
			read answ
			[ -z "$answ" ] && answ="${_DEFAULT}"
			return 0
		;;
		"mdtmp")
			#will be processed differently. temporary hide this
			#	${ECHO} "${BOLD}${1}: ${_DESC} ?(${_DEFAULT} mb default)${NORMAL}"
			#	${ECHO} "${MAGENTA}This md disk will be used for temporary operation? 0 - for disable or N (in mb) for disk size e.g: ${GREEN}${_DEFAULT}${NORMAL}"
			#	read answ
			#	[ -z "${answ}" ] && answ=0
			answ=0
			return 0
		;;
		"nat_enable")
			if ! getyesno "${1}: ${_DESC}?"; then
				answ=0
				return 0
			fi
			[ -z "$answ" ] && answ="${_DEFAULT}"
			answ=1
			return 0
		;;
		"nodename")
			${ECHO} "${BOLD}${1}: ${_DESC}: ${GREEN}${_DEFAULT}${NORMAL}"
			read answ
			[ -z "$answ" ] && answ="${_DEFAULT}"
			return 0
		;;
		"nodeip")
			${ECHO} "${BOLD}${1}: ${_DESC} (used for node interconnection), e.g: ${GREEN}${_DEFAULT}${NORMAL}"
			read answ
			[ "${answ}" = "default" ] && answ="${CBSD_IP4}"
			[ -z "$answ" ] && answ="${_DEFAULT}"
			return 0
		;;
		"nodeippool")
			${ECHO} "${BOLD}${1}: ${_DESC} (networks for jails)${NORMAL}"
			${ECHO} "${MAGENTA}Hint: use space as delimiter for multiple networks, e.g.: ${GREEN}${_DEFAULT}${NORMAL}"
			read answ
			[ -z "$answ" ] && answ="${_DEFAULT}"
			return 0
		;;
		"parallel")
			${ECHO} "${BOLD}${1}: ${_DESC} ?${NORMAL}"
			${ECHO} "${MAGENTA}(0 - no parallel or positive value (in seconds) as timeout for next parallel sequence) e.g: ${GREEN}${_DEFAULT}${NORMAL}"
			read answ
			[ -z "${answ}" ] && answ="${_DEFAULT}"
			return 0
		;;
		"stable")
			${ECHO} "${BOLD}${1}: ${_DESC} ?${NORMAL}"
			${ECHO} "${MAGENTA}(STABLE_X instead of RELEASE_X_Y branch for base/kernel will be used), e.g.: ${GREEN}${_DEFAULT} ${MAGENTA}(use release)${NORMAL}"
			read answ
			[ -z "${answ}" ] && answ="${_DEFAULT}"
			return 0
		;;
		"statsd_enable")
			${ECHO} "${BOLD}${1}: ${_DESC} ?${NORMAL}"
			${ECHO} "${MAGENTA}(EXPERIMENTAL FEATURE)? e.g: ${GREEN}${_DEFAULT}${NORMAL}"
			read answ
			[ -z "${answ}" ] && answ="${_DEFAULT}"
			return 0
		;;
		"sqlreplica")
			${ECHO} "${BOLD}${1}: ${_DESC} ?${NORMAL}"
			${ECHO} "${MAGENTA}(0 - no replica, 1 - try to replicate all local events to remote nodes) e.g: ${GREEN}${_DEFAULT}${NORMAL}"
			read answ
			[ -z "${answ}" ] && answ="${_DEFAULT}"
			return 0
		;;
		"zfsfeat")
			if getyesno "${1}: You are running on a ZFS-based system. ${_DESC}"; then
				answ=1
			else
				answ=0
			fi
			return 0
		;;
		*)
		return 1
		;;
	esac
}

# check for old install and if exist - execute pre scripts from upgrade directory
# setup pkg if no other cfg
phase0()
{
	local myversion cbsdd_enable cbsd_workdir workdir

	. ${distdir}/${localcbsdconffile}
	newver="${myversion}"

	[ ! -f /etc/rc.conf ] && ${TOUCH_CMD} /etc/rc.conf

	. /etc/rc.conf
	[ -z "${cbsd_workdir}" ] && return 0

	[ ! -f "${cbsd_workdir}/cbsd.conf" ] && return 0

	first_init=0

	workdir="${cbsd_workdir}"
	. "${cbsd_workdir}/cbsd.conf"

	oldver="${myversion}"

	${ECHO} "${MAGENTA}[Stage 0:${GREEN} upgrading and migration data from ${oldver} to ${newver}${MAGENTA}]${NORMAL}"

	[ -d "${distdir}/upgrade" ] && /usr/bin/find ${distdir}/upgrade/ -type f -depth 1 -maxdepth 1 -name pre-patch-\* -exec {} \;
}

# execute post scripts from upgrade directory
phaseX()
{
	local myversion cbsdd_enable cbsd_workdir workdir
	${ECHO} "${MAGENTA}[Stage X:${GREEN} upgrading${MAGENTA}]${NORMAL}"
	[ -d "${distdir}/upgrade" ] && /usr/bin/find ${distdir}/upgrade/ -type f -depth 1 -maxdepth 1 -name post-patch-\* -exec {} \;
}


phase1()
{
	local cbsd_home

	${ECHO} "${MAGENTA}[Stage 1:${GREEN} account & dir hier${MAGENTA}]${NORMAL}"
	/usr/bin/id ${cbsduser} > /dev/null 2>&1

	if [ $? -eq 1 ]; then
		echo "No such user ${cbsduser}. Please follow instruction at https://www.bsdstore.ru/en/installing_cbsd.html"
		echo "if you install not from the ports"
		exit 1
	fi

	# check for correct homedir
	cbsd_home=$( ${GREP_CMD} ^cbsd /etc/master.passwd | /usr/bin/cut -d : -f 9 )

	[ "${cbsd_home}" != "${workdir}" ] && /usr/sbin/pw usermod ${cbsduser} -d ${workdir} >/dev/null 2>&1

	[ ! -d "${workdir}" ] && /bin/mkdir -m 755 ${workdir}
	$ECHO "${MAGENTA} * Check hier and permission..."
	mtree -deU -f ${distdir}/etc/cbsd.mtree -p ${workdir}
	make_fs_id
	printf "${NORMAL}"
}

phase2()
{
	local _dir _ldir _rdir _file _dirhier _d platform

	${ECHO} "${MAGENTA}[Stage 2: ${GREEN}build tools${MAGENTA}]${NORMAL}"

	platform=$( uname -s )

	[ ! -f "${distdir}/bin/cbsdsftp" ] && ${CC_CMD} ${distdir}/bin/cbsdsftp.c -o ${distdir}/bin/cbsdsftp -lssh2 -L/usr/local/lib -I/usr/local/include
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/bin/cbsdsftp ${bindir}/cbsdsftp
	[ -f ${distdir}/bin/cbsdsftp ] && /bin/rm -f ${distdir}/bin/cbsdsftp

	[ ! -f "${distdir}/bin/cbsdsftp6" ] && ${CC_CMD} ${distdir}/bin/cbsdsftp6.c -o ${distdir}/bin/cbsdsftp6 -lssh2 -L/usr/local/lib -I/usr/local/include
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/bin/cbsdsftp6 ${bindir}/cbsdsftp6
	[ -f ${distdir}/bin/cbsdsftp6 ] && /bin/rm -f ${distdir}/bin/cbsdsftp6

	[ ! -f "${distfir}/bin/cbsdssh" ] && ${CC_CMD} ${distdir}/bin/cbsdssh.c -o ${distdir}/bin/cbsdssh -lssh2 -L/usr/local/lib -I/usr/local/include
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/bin/cbsdssh ${bindir}/cbsdssh
	[ -f ${distdir}/bin/cbsdssh ] && /bin/rm -f ${distdir}/bin/cbsdssh

	[ ! -f "${distfir}/bin/cbsdssh6" ] && ${CC_CMD} ${distdir}/bin/cbsdssh6.c -o ${distdir}/bin/cbsdssh6 -lssh2 -L/usr/local/lib -I/usr/local/include
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/bin/cbsdssh6 ${bindir}/cbsdssh6
	[ -f ${distdir}/bin/cbsdssh6 ] && /bin/rm -f ${distdir}/bin/cbsdssh6

	[ ! -f "${distfir}/bin/cfetch" ] && ${CC_CMD} ${distdir}/bin/cfetch.c -o ${distdir}/bin/cfetch -lfetch
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/bin/cfetch ${bindir}/cfetch
	[ -f ${distdir}/bin/cfetch ] && /bin/rm -f ${distdir}/bin/cfetch

	installne "-o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/bin/rexe ${bindir}/rexe

	[ ! -f "${distdir}/sbin/netmask" ] && ${CC_CMD} ${distdir}/sbin/netmask.c -o ${distdir}/sbin/netmask
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/sbin/netmask ${sbindir}/netmask
	[ -f ${distdir}/sbin/netmask ] && /bin/rm -f ${distdir}/sbin/netmask

	if [ ! -f "${distdir}/misc/sqlcli" ]; then
		/usr/bin/which -s pkg-config
		if [ $? -ne 0 ]; then
			echo "pkg-config must be present on the system to build CBSD from the source. Please install it first: pkg install pkgconf";
			exit 1
		fi
		${CC_CMD} ${distdir}/misc/src/sqlcli.c $( pkg-config sqlite3 --cflags --libs ) -lm -lc++ -o ${distdir}/misc/sqlcli
	fi
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 500" ${distdir}/misc/sqlcli ${miscdir}/sqlcli
	[ -f ${distdir}/misc/sqlcli ] && /bin/rm -f ${distdir}/misc/sqlcli

	[ ! -f "${distdir}/misc/pwcrypt" ] && ${CC_CMD} ${distdir}/misc/src/pwcrypt.c -lcrypt -o ${distdir}/misc/pwcrypt
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 500" ${distdir}/misc/pwcrypt ${miscdir}/pwcrypt
	[ -f ${distdir}/misc/pwcrypt ] && /bin/rm -f ${distdir}/misc/pwcrypt

	[ ! -f "${distdir}/misc/cbsdlogtail" ] && ${CC_CMD} ${distdir}/misc/src/cbsdlogtail.c -o ${distdir}/misc/cbsdlogtail
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/cbsdlogtail ${miscdir}/cbsdlogtail
	[ -f ${distdir}/misc/cbsdlogtail ] && /bin/rm -f ${distdir}/misc/cbsdlogtail

	[ ! -f "${distdir}/misc/elf_tables" ] && ${CC_CMD} -I/usr/local/include -I/usr/local/include/libelf -L/usr/local/lib ${distdir}/misc/src/elf_tables.c -lelf -o ${distdir}/misc/elf_tables
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/elf_tables ${miscdir}/elf_tables
	[ -f ${distdir}/misc/elf_tables ] && /bin/rm -f ${distdir}/misc/elf_tables

	[ ! -f "${distdir}/misc/conv2human" ] && ${CC_CMD} -I/usr/local/include -I/usr/local/include/libelf -L/usr/local/lib ${distdir}/misc/src/conv2human.c -lelf -o ${distdir}/misc/conv2human -lutil
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/conv2human ${miscdir}/conv2human
	[ -f ${distdir}/misc/conv2human ] && /bin/rm -f ${distdir}/misc/conv2human

	[ ! -f "${distdir}/misc/cbsd_fwatch" ] && ${CC_CMD} ${distdir}/misc/src/cbsd_fwatch.c -o ${distdir}/misc/cbsd_fwatch
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/cbsd_fwatch ${miscdir}/cbsd_fwatch
	[ -f ${distdir}/misc/cbsd_fwatch ] && /bin/rm -f ${distdir}/misc/cbsd_fwatch

	[ ! -f "${distdir}/misc/cbsd_dot" ] && ${CC_CMD} ${distdir}/misc/src/cbsd_dot.c -o ${distdir}/misc/cbsd_dot
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/cbsd_dot ${miscdir}/cbsd_dot
	[ -f ${distdir}/misc/cbsd_dot ] && /bin/rm -f ${distdir}/misc/cbsd_dot

	[ ! -f "${distdir}/misc/popcnttest" ] && ${CC_CMD} ${distdir}/misc/src/popcnttest.c -o ${distdir}/misc/popcnttest -msse4.2 > /dev/null 2>&1 || /usr/bin/true
	[ -f "${distdir}/misc/popcnttest" ] && installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/popcnttest ${miscdir}/popcnttest
	[ -f ${distdir}/misc/popcnttest ] && /bin/rm -f ${distdir}/misc/popcnttest

	[ ! -f "${distdir}/misc/chk_arp_byip" ] && ${CC_CMD} ${distdir}/misc/src/chk_arp_byip.c -o ${distdir}/misc/chk_arp_byip
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/chk_arp_byip ${miscdir}/chk_arp_byip
	[ -f ${distdir}/misc/chk_arp_byip ] && /bin/rm -f ${distdir}/misc/chk_arp_byip

	[ ! -f "${distdir}/misc/daemon" ] && ${CC_CMD} ${distdir}/misc/src/daemon.c -lutil -o ${distdir}/misc/daemon
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/daemon ${miscdir}/daemon
	[ -f ${distdir}/misc/daemon ] && /bin/rm -f ${distdir}/misc/daemon

	[ ! -f "${distdir}/misc/resolv" ] && ${CC_CMD} ${distdir}/misc/src/resolv.c -o ${distdir}/misc/resolv
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/resolv ${miscdir}/resolv
	[ -f ${distdir}/misc/resolv ] && /bin/rm -f ${distdir}/misc/resolv

	[ ! -f "${distdir}/tools/imghelper" ] && ${CC_CMD} ${distdir}/tools/src/imghelper.c -o ${distdir}/tools/imghelper
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/tools/imghelper ${toolsdir}/imghelper
	[ -f ${distdir}/tools/imghelper ] && /bin/rm -f ${distdir}/tools/imghelper

	[ ! -f "${distdir}/tools/racctd-statsd" ] && ${CC_CMD} ${distdir}/tools/src/racct-statsd.c -lutil -lprocstat -ljail -lsqlite3 -I/usr/local/include -L/usr/local/lib -o ${distdir}/tools/racct-statsd
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/tools/racct-statsd ${toolsdir}/racct-statsd
	[ -f ${distdir}/tools/racct-statsd ] && /bin/rm -f ${distdir}/tools/racct-statsd

	[ ! -f "${distdir}/tools/select_jail.c" ] && ${CC_CMD} ${distdir}/tools/src/select_jail.c -o ${distdir}/tools/select_jail
	installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/tools/select_jail ${toolsdir}/select_jail
	[ -f ${distdir}/tools/select_jail ] && /bin/rm -f ${distdir}/tools/select_jail

	if [ -f ${distdir}/misc/src/dump_cpu_topology.c ]; then
		${CC_CMD} -g -c -Wall -I${distdir}/lib/simplexml ${distdir}/misc/src/dump_cpu_topology.c -o ${distdir}/misc/src/dump_cpu_topology.o
		${CC_CMD} -g -c -Wall -I${distdir}/lib/simplexml ${distdir}/lib/simplexml/simplexml.c -o ${distdir}/lib/simplexml/simplexml.o
		${CC_CMD} -g -o ${distdir}/misc/dump_cpu_topology ${distdir}/misc/src/dump_cpu_topology.o ${distdir}/lib/simplexml/simplexml.o
		installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/dump_cpu_topology ${miscdir}/dump_cpu_topology
		[ -f ${distdir}/misc/dump_cpu_topology ] && /bin/rm -f ${distdir}/misc/dump_cpu_topology ${distdir}/misc/src/dump_cpu_topology.o ${distdir}/lib/simplexml/simplexml.o
	fi
	if [ -f ${distdir}/misc/src/dump_iscsi_discovery.c ]; then
		${CC_CMD} -g -c -Wall -I${distdir}/lib/simplexml ${distdir}/misc/src/dump_iscsi_discovery.c -o ${distdir}/misc/src/dump_iscsi_discovery.o
		${CC_CMD} -g -c -Wall -I${distdir}/lib/simplexml ${distdir}/lib/simplexml/simplexml.c -o ${distdir}/lib/simplexml/simplexml.o
		${CC_CMD} -g -o ${distdir}/misc/dump_iscsi_discovery ${distdir}/misc/src/dump_iscsi_discovery.o ${distdir}/lib/simplexml/simplexml.o
		installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/misc/dump_iscsi_discovery ${miscdir}/dump_iscsi_discovery
		[ -f ${distdir}/misc/dump_iscsi_discovery ] && /bin/rm -f ${distdir}/misc/dump_iscsi_discovery ${distdir}/misc/src/dump_iscsi_discovery.o ${distdir}/lib/simplexml/simplexml.o
	fi

	if [ "${platform}" != "DragonFly" ]; then
		[ ! -f "${distdir}/tools/vale-ctl" ] && ${CC_CMD} ${distdir}/tools/src/vale-ctl.c -o ${distdir}/tools/vale-ctl
		installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/tools/vale-ctl ${toolsdir}/vale-ctl
		[ -f ${toolsdir}/vale-ctl ] && /bin/rm -f ${toolsdir}/vale-ctl

		[ ! -f "${distdir}/tools/nic_info" ] && ${CC_CMD} ${distdir}/tools/src/nic_info.c -o ${distdir}/tools/nic_info
		installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/tools/nic_info ${toolsdir}/nic_info
		[ -f ${toolsdir}/nic_info ] && /bin/rm -f ${toolsdir}/nic_info

		[ ! -f "${distdir}/tools/bridge" ] && ${CC_CMD} ${distdir}/tools/src/bridge.c -o ${distdir}/tools/bridge
		installne "-s -o ${cbsduser} -g ${cbsduser} -m 555" ${distdir}/tools/bridge ${toolsdir}/bridge
		[ -f ${toolsdir}/bridge ] && /bin/rm -f ${toolsdir}/bridge
	fi

	if [ -f "/usr/local/bin/cbsd" ]; then
		CURVERSION=$(/usr/local/bin/cbsd -c version )
		if [ "${CURVERSION}" != "${myversion}" ]; then
			make -C ${distdir}/bin/cbsdsh clean && make -DCBSDVERSION="${ncver}" -C ${distdir}/bin/cbsdsh
			# force rebuild sqlscli too to avoid possible SQLite3 link error
			${CC_CMD} ${distdir}/misc/src/sqlcli.c -lsqlite3 -L/usr/local/lib -I/usr/local/include -o ${distdir}/misc/sqlcli
			installne "-s -o ${cbsduser} -g ${cbsduser} -m 500" ${distdir}/misc/sqlcli ${miscdir}/sqlcli
		fi
	else
		make -C ${distdir}/bin/cbsdsh clean && make -DCBSDVERSION="${ncver}" -C ${distdir}/bin/cbsdsh
	fi

	[ -d "${distdir}/bin/cbsd" ] && /bin/rm -rf "${distfir}/bin/cbsd"
	[ -f "${distdir}/bin/cbsdsh/cbsd" ] && /usr/bin/install -s -o ${cbsduser} -g ${cbsduser} -m 500 ${distdir}/bin/cbsdsh/cbsd /usr/local/bin/cbsd

	[ -f "/usr/local/bin/cbsd" ] && /bin/chmod 0500 /usr/local/bin/cbsd && /usr/sbin/chown ${cbsduser}:${cbsduser} /usr/local/bin/cbsd

	#### /bin/cp SCRIPTS with override and executable
	_dirhier="jailctl \
		nodectl \
		rc.d \
		misc \
		system \
		tools"

	for _d in ${_dirhier}; do
		_ldir="${workdir}/${_d}"
		_rdir="${distdir}/${_d}"
		for _file in $( /usr/bin/find ${_rdir} -depth 1 -maxdepth 1 -type f -exec /usr/bin/basename {} \; ); do
			installne "-o ${cbsduser} -g ${cbsduser} -m 555" ${_rdir}/${_file} ${_ldir}/${_file}
		done
	done

	#### /bin/cp SCRIPTS with override and readonly
	_dirhier="etc/defaults"

	for _d in ${_dirhier}; do
		_ldir="${workdir}/${_d}"
		_rdir="${distdir}/${_d}"
		for _file in $( /usr/bin/find ${_rdir} -depth 1 -maxdepth 1 -type f -exec /usr/bin/basename {} \; ); do
			installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${_rdir}/${_file} ${_ldir}/${_file}
		done
	done

	#### /bin/cp SCRIPTS without override
	_dirhier="share \
		share/helpers \
		etc"

	cat > ${etcdir}/cbsd_sudoers <<EOF
Defaults     env_keep += "workdir DIALOG NOCOLOR CBSD_RNODE"
Cmnd_Alias   CBSD_CMD = ${sudoexecdir}/*,/usr/local/cbsd/sudoexec/*
${cbsduser}   ALL=(ALL) NOPASSWD: CBSD_CMD
EOF

	for _d in ${_dirhier}; do
		_ldir="${workdir}/${_d}"
		_rdir="${distdir}/${_d}"
		for _file in $( /usr/bin/find ${_rdir} -depth 1 -maxdepth 1 -type f -exec /usr/bin/basename {} \; ); do
			[ ! -f "${_ldir}/${_file}" ] && /usr/bin/install -o ${cbsduser} -g ${cbsduser} -m 444 ${_rdir}/${_file} ${_ldir}/${_file}
		done
	done

	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${globalconf} ${workdir}/cbsd.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/bsdconfig.subr ${workdir}/bsdconfig.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/cmd.subr ${workdir}/cmd.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/FreeBSD.subr ${workdir}/FreeBSD.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/HardenedBSD.subr ${workdir}/HardenedBSD.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/TrueOS.subr ${workdir}/TrueOS.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/DragonFly.subr ${workdir}/DragonFly.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/bhyve.subr ${workdir}/bhyve.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/virtual.subr ${workdir}/virtual.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/virtualbox.subr ${workdir}/virtualbox.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/xen.subr ${workdir}/xen.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/zrep.subr ${workdir}/zrep.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/nc.subr ${workdir}/nc.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/zfs.subr ${workdir}/zfs.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/hammer.subr ${workdir}/hammer.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/tools.subr ${workdir}/tools.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/mdtools.subr ${workdir}/mdtools.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/multiple.subr ${workdir}/multiple.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/freebsd_world.subr ${workdir}/freebsd_world.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/initenv.subr ${workdir}/initenv.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/ansiicolor.subr ${workdir}/ansiicolor.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/dialog.subr ${workdir}/dialog.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/nodes.subr ${workdir}/nodes.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/strings.subr ${workdir}/strings.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/rcconf.subr ${workdir}/rcconf.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/rrcconf.subr ${workdir}/rrcconf.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/vnet.subr ${workdir}/vnet.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/vnet-tui.subr ${workdir}/vnet-tui.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/emulator.subr ${workdir}/emulator.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/rctl.subr ${workdir}/rctl.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/imghelper.subr ${workdir}/imghelper.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/jrctl.subr ${workdir}/jrctl.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/securecmd ${workdir}/securecmd
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/system.subr ${workdir}/system.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/jcreate.subr ${workdir}/jcreate.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/jfs.subr ${workdir}/jfs.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/build.subr ${workdir}/build.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/universe.subr ${workdir}/universe.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/settings-tui.subr ${workdir}/settings-tui.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/distccache.subr ${workdir}/distccache.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/mailtools.subr ${workdir}/mailtools.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/env_register.subr ${workdir}/env_register.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/fetch.subr ${workdir}/fetch.subr
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/carp.subr ${workdir}/carp.subr

	#here is file with overwriting
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/jail-arg ${sharedir}/jail-arg
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/rctl.conf ${sharedir}/rctl.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/bhyve.conf ${sharedir}/bhyve.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/bhyverun.sh ${sharedir}/bhyverun.sh
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/virtualbox.conf ${sharedir}/virtualbox.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/bhyve_settings.conf ${sharedir}/bhyve_settings.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/xen_settings.conf ${sharedir}/xen_settings.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/xen.conf ${sharedir}/xen.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/zrep.conf ${sharedir}/zrep.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/bhyvedsk.conf ${sharedir}/bhyvedsk.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/bhyve_dskcontroller.conf ${sharedir}/bhyve_dskcontroller.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/bhyvenic.conf ${sharedir}/bhyvenic.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/virtualboxdsk.conf ${sharedir}/virtualboxdsk.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/virtualboxnic.conf ${sharedir}/virtualboxnic.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/xendsk.conf ${sharedir}/xendsk.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/xennic.conf ${sharedir}/xennic.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/vnetnic.conf ${sharedir}/vnetnic.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/jrctl-arg ${sharedir}/jrctl-arg
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-carp.schema ${sharedir}/local-carp.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bsdbase.schema ${sharedir}/local-bsdbase.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bsdsrc.schema ${sharedir}/local-bsdsrc.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-vale.schema ${sharedir}/local-vale.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/forms.schema ${sharedir}/forms.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/forms_system.schema ${sharedir}/forms_system.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/forms_yesno.schema ${sharedir}/forms_yesno.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-fwcounters.schema ${sharedir}/local-fwcounters.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-gw.schema ${sharedir}/local-gw.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-jails.schema ${sharedir}/local-jails.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-local.schema ${sharedir}/local-local.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-net.schema ${sharedir}/local-net.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-rctl.schema ${sharedir}/local-rctl.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-authkey.schema ${sharedir}/local-authkey.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyve-p9shares.schema ${sharedir}/local-bhyve-p9shares.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyve-cpu_topology.schema ${sharedir}/local-bhyve-cpu_topology.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyve-settings.schema ${sharedir}/local-bhyve-settings.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-storage_media_map.schema ${sharedir}/local-storage_media_map.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyve.schema ${sharedir}/local-bhyve.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyvedsk.schema ${sharedir}/local-bhyvedsk.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyve-dskcontroller.schema ${sharedir}/local-bhyve-dskcontroller.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyvenic.schema ${sharedir}/local-bhyvenic.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-jailnic.schema ${sharedir}/local-jailnic.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-bhyveppt.schema ${sharedir}/local-bhyveppt.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-virtualbox.schema ${sharedir}/local-virtualbox.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-virtualboxdsk.schema ${sharedir}/local-virtualboxdsk.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-virtualboxnic.schema ${sharedir}/local-virtualboxnic.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-xen.schema ${sharedir}/local-xen.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-xendsk.schema ${sharedir}/local-xendsk.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-xennic.schema ${sharedir}/local-xennic.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-vnetnic.schema ${sharedir}/local-vnetnic.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-vmpackages.schema ${sharedir}/local-vmpackages.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-vm_cpu_topology.schema ${sharedir}/local-vm_cpu_topology.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/local-unconfigured.schema ${sharedir}/local-unconfigured.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/cbsdtaskd-taskd.schema ${sharedir}/cbsdtaskd-taskd.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/vpnet-vpnet.schema ${sharedir}/vpnet-vpnet.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/zrepd.schema ${sharedir}/zrepd.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/node-nodelist.schema ${sharedir}/node-nodelist.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/system-expose.schema ${sharedir}/system-expose.schema
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/DragonFly-git_branches.conf ${sharedir}/DragonFly-git_branches.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/FreeBSD-git_branches.conf ${sharedir}/FreeBSD-git_branches.conf
	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/etc/Makefile ${etcdir}/Makefile

	for i in FreeBSD-filebases_10.txt.xz FreeBSD-filebases_11.txt.xz FreeBSD-filebases_12.txt.xz FreeBSD-filebases_13.txt.xz FreeBSD-filemin_10.txt.xz FreeBSD-filemin_11.txt.xz FreeBSD-filemin_12.txt.xz FreeBSD-filemin_13.txt.xz; do
		installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/${i} ${sharedir}/${i}
	done

	installne "-o ${cbsduser} -g ${cbsduser} -m 444" ${distdir}/share/FreeBSD-git_branches.conf ${sharedir}/FreeBSD-git_branches.conf

	# 10_cbsd_sudoers for compatible with puppet sudo module
	if [ ! -f "/usr/local/etc/sudoers.d/cbsd_sudoers" -a ! -f "/usr/local/etc/sudoers.d/10_cbsd_sudoers" ]; then
		if getyesno "Shall i add cbsd user into /usr/local/etc/sudoers.d/cbsd_sudoers sudo file to obtain root privileges for the most cbsd commands?"; then
			[ ! -d /usr/local/etc/sudoers.d ] && /bin/mkdir -p /usr/local/etc/sudoers.d
			installne "-o root -g wheel -m 440" ${etcdir}/cbsd_sudoers /usr/local/etc/sudoers.d/cbsd_sudoers
		fi
	fi

	#    [ -d ${sshdir} ] || /bin/mkdir -m 0700 ${sshdir}
	#    [ -d "${sshdir}/sockets" ] || /bin/mkdir -m 0700 "${sshdir}/sockets"
	[ -f "${sshdir}/config" ] || installne "-o ${cbsduser} -g ${cbsduser} -m 644" ${distdir}/.ssh/config ${sshdir}/config

	# workaround for move jail-skel hier in cbsd 10.0.0
	[ ! -d "${sharedir}/${platform}-jail-skel/etc" -a -d "${distdir}/share/${platform}-jail-skel" ] && /bin/mkdir -p ${sharedir}/${platform}-jail-skel && /bin/cp -a ${distdir}/share/${platform}-jail-skel/* ${sharedir}/${platform}-jail-skel/
	[ -f "${sharedir}/${platform}-jail-skel/etc/master.passwd" ] && chmod 0600 ${sharedir}/${platform}-jail-skel/etc/master.passwd ${sharedir}/${platform}-jail-skel/etc/spwd.db

	# workaround for move jail-skel hier in cbsd 10.0.0
	[ ! -d "${sharedir}/${platform}-jail-vnet-skel/etc" -a -d "${distdir}/share/${platform}-jail-vnet-skel" ] && /bin/mkdir -p ${sharedir}/${platform}-jail-vnet-skel && /bin/cp -a ${distdir}/share/${platform}-jail-vnet-skel/* ${sharedir}/${platform}-jail-vnet-skel/
	[ -f "${sharedir}/${platform}-jail-vnet-skel/etc/master.passwd" ] && chmod 0600 ${sharedir}/${platform}-jail-vnet-skel/etc/master.passwd ${sharedir}/${platform}-jail-vnet-skel/etc/spwd.db

	[ ! -d "${sharedir}/${platform}-jail-puppet-skel/etc" -a -d "${distdir}/share/${platform}-jail-puppet-skel" ] && /bin/mkdir -p ${sharedir}/${platform}-jail-puppet-skel && /bin/cp -a ${distdir}/share/${platform}-jail-puppet-skel/* ${sharedir}/${platform}-jail-puppet-skel/
	[ ! -d "${sharedir}/${platform}-jail-puppet-skel/rc.d" -a -d "${distdir}/share/${platform}-jail-puppet-skel/etc" ] && /bin/mkdir -p ${sharedir}/${platform}-jail-puppet-skel/etc/rc.d && /bin/cp -a ${distdir}/share/${platform}-jail-puppet-skel/etc/rc.d/* ${sharedir}/${platform}-jail-puppet-skel/etc/rc.d/
	[ -f "${sharedir}/${platform}-jail-puppet-skel/etc/master.passwd" ] && chmod 0600 ${sharedir}/${platform}-jail-puppet-skel/etc/master.passwd ${sharedir}/${platform}-jail-puppet-skel/etc/spwd.db

	if [ ! -f "${sharedir}/${platform}-jail-kfreebsd-wheezy-system-skel/tests/00.check_distribution.sh" -a -d "${distdir}/share/${platform}-jail-kfreebsd-wheezy-system-skel" ]; then
		/bin/mkdir -p ${sharedir}/${platform}-jail-kfreebsd-wheezy-system-skel > /dev/null 2>&1
		/bin/cp -a ${distdir}/share/${platform}-jail-kfreebsd-wheezy-system-skel/* ${sharedir}/${platform}-jail-kfreebsd-wheezy-system-skel/
	fi

	[ ! -d "${sharedir}/${platform}-jail-kfreebsd-wheezy-skel" -a -d "${platform}/share/${platform}-jail-kfreebsd-wheezy-system-skel" ] && /bin/cp -a ${distdir}/share/${platform}-jail-kfreebsd-wheezy-skel ${sharedir}/
	[ ! -d "${sharedir}/jail-system-default" -a -d "${distdir}/share/jail-system-default" ] && /bin/cp -a ${distdir}/share/jail-system-default ${sharedir}/

	[ ! -d "${sharedir}/emulators" -a -d "${distdir}/share/emulators" ] && /bin/mkdir -p ${sharedir}/emulators
	/bin/cp -a ${distdir}/share/emulators/* ${sharedir}/emulators/

	/bin/cp -Rp ${distdir}/modules ${workdir}
}

phase3()
{
	local _hname _sname _namenotset

	${ECHO} "${MAGENTA}[Stage 3: ${GREEN}local settings${MAGENTA}]${NORMAL}"
	_namenotset=1

	while [ ${_namenotset} ]; do
		_hname=$( /bin/hostname )
		_sname=$( /bin/hostname -s )

		if [ -z "${_hname}" ]; then
			${ECHO} "${MAGENTA}Hostname is empty. Please set this:${NORMAL}"
			read p
			if getyesno "I will use hostname: $p"; then
				hostname $p
				_hname=$( /bin/hostname )
				_sname=$( /bin/hostname -s )
			fi
		fi

		if [ "${_hname}" = "${_sname}" ]; then
			${ECHO} "${GREEN}${_hname}${MAGENTA} - Wrong hostname. Full hostname must be not equal short hostname. Please set FQDN (${GREEN}${_hname}.my.domain${MAGENTA} for example):${NORMAL}"
			read p
			if getyesno "Shall i modify the /etc/rc.conf to sets new hostname value?: $p"; then
				hostname $p
				${SYSRC_CMD} -vf /etc/rc.conf hostname="${p}"
			fi
			else break;
		fi
	done
}

phase4()
{
	${ECHO} "${MAGENTA}[Stage 4: ${GREEN}update default skel resolv.conf${MAGENTA}]${NORMAL}"

	for i in $(${ECHO} ${jnameserver} | /usr/bin/tr "," " "); do
		if [ -f "${sharedir}/${platform}-jail-skel/etc/resolv.conf" ]; then
			if [ $( ${GREP_CMD} -c ${i} ${sharedir}/${platform}-jail-skel/etc/resolv.conf ) = 0 ]; then
				TMPR="${ftmpdir}/resolv.$$"
				# system nserver must be always last
				${ECHO} "nameserver ${i}" > ${TMPR}
				/bin/cat ${sharedir}/${platform}-jail-skel/etc/resolv.conf >> ${TMPR}
				/bin/mv ${TMPR} ${sharedir}/${platform}-jail-skel/etc/resolv.conf
			fi
		fi
	done
}

phase5()
{
	local _uncfg _uninit _checkme _myfs _ret _val

	${ECHO} "${MAGENTA}[Stage 5: ${GREEN}refreshing inventory${MAGENTA}]${NORMAL}"

	[ -f "${inventory}" ] && . ${inventory}

	#system information
	. ${toolsdir}/sysinv
	update_netinfo

	init_items_desc
	init_items_default

	if [ -z "${nodename}" ]; then
		desc_question nodename
		nodename=${answ}
	fi

	[ -z "${nodename}" ] && err 1 "nodename must be not empty"

	[ "${nodeip}" = "default" ] && nodeip="${CBSD_IP4}"
	[ "${natip}" = "default" ] && natip="${CBSD_IP4}"

	[ ! -f "${nodenamefile}" ] && echo "${nodename}" > "${nodenamefile}"
	[ ! -f "${dbdir}/nodes.sqlite" ] && /usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/nodes.sqlite ${distdir}/share/node-nodelist.schema nodelist

	if [ ! -f "${dbdir}/inv.${nodename}.sqlite" ]; then
		/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-unconfigured.schema unconfigured
		/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-local.schema local
		/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-jails.schema jails
		$ECHO "${MAGENTA}Empty inventory database created: ${GREEN}${dbdir}/inv.${nodename}.sqlite${NORMAL}"
		${miscdir}/sqlcli ${dbdir}/inv.${nodename}.sqlite "insert into local ( nodename ) VALUES ( \"${nodename}\" )"
	fi

	/bin/chmod 0660 ${dbdir}/inv.${nodename}.sqlite && /usr/sbin/chown ${cbsduser}:${cbsduser} ${dbdir}/inv.${nodename}.sqlite

	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-local.schema local

	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-carp.schema carp
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-bsdbase.schema bsdbase
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-bsdsrc.schema bsdsrc
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-vale.schema vale
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/forms.schema forms
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/forms_system.schema system
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-jails.schema jails
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-rctl.schema rctl
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-bhyve.schema bhyve
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-bhyveppt.schema bhyveppt
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-virtualbox.schema virtualbox
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-xen.schema xen
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-vnetnic.schema vnetnic
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-vmpackages.schema vmpackages
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/inv.${nodename}.sqlite ${distdir}/share/local-vm_cpu_topology.schema vm_cpu_topology
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/cbsdtaskd.sqlite ${distdir}/share/cbsdtaskd-taskd.schema taskd
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/vpnet.sqlite ${distdir}/share/vpnet-vpnet.schema vpnet
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/authkey.sqlite ${distdir}/share/local-authkey.schema authkey
	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/storage_media.sqlite ${distdir}/share/local-storage_media_map.schema media

	/usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/zrepd.sqlite ${distdir}/share/zrepd.schema map

	[ -f "${dbdir}/nodes.sqlite" ] && /usr/local/bin/cbsd ${miscdir}/updatesql ${dbdir}/nodes.sqlite ${distdir}/share/node-nodelist.schema nodelist

	/bin/ln -sfh ${dbdir}/inv.${nodename}.sqlite ${dbdir}/local.sqlite

	_myfs="ufs"
	zfsfeat=0

	if kldstat -qm zfs >/dev/null 2>&1; then
		/sbin/zfs list ${jaildatadir} > /dev/null 2>&1
		if [ $? -eq 0 ]; then
			_myfs="zfs"
			zfsfeat=1
		else
			zfsfeat=0
			${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET zfsfeat=\"0\"
		fi
	fi

	if [ -x /sbin/hammer ]; then
		/sbin/hammer info ${workdir} > /dev/null 2>&1
		[ $? -eq 0 ] && _myfs="hammer"
	fi

	_uncfg=$( ${miscdir}/sqlcli ${dbdir}/local.sqlite SELECT items FROM unconfigured )

	[ $? -ne 0 ] && err 1 "Error for unconfigured query"

	if [ -n "${INITCFG}" ]; then
		. ${INITCFG}
		_uncfg=$( ${GREP_CMD} -v '^#' ${INITCFG} | /usr/bin/cut -d '=' -f1 | /usr/bin/xargs )
	fi

	for _checkme in ${_uncfg}; do
		for _uninit in ${USERINI}; do
			# skip for nodename which is already set
			[ "${_uninit}" = "nodename" ] && continue
			# temporary skip for mdtmp
			[ "${_uninit}" = "mdtmp" ] && continue
			if [ "${_uninit}" = "${_checkme}" ]; then
				if [ "${_checkme}" = "zfsfeat" -a ${_myfs} != "zfs" ]; then
					${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET zfsfeat=\"0\"
					continue
				fi
				if [ "${_checkme}" = "hammerfeat" -a ${_myfs} != "hammer" ]; then
					${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET hammer=\"0\"
					continue
				fi

				# check for pre-defined variables
				T=
				eval T="\$$_checkme"
				[ -n "${T}" ] && export ${_checkme}_default="${T}"

				desc_question ${_checkme}
				[ $? -ne 0 ] && continue
				# todo: input validation here
				[ "${_checkme}" = "mdtmp" -a "$answ" = "1" ] && answ="8"
				[ "${_checkme}" = "mdtmp" -a "$answ" = "2" ] && answ="0"
				if [ -n "${answ}" ]; then
					${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET ${_uninit}=\"${answ}\"
					eval "${_uninit}=\"${answ}\"" 2>/dev/null
				fi
				if [ "${_checkme}" = "nat_enable" -a  "${nat_enable}" != "0" ]; then
					# store in nat_enable default NAT framework, e.g: pf
					nat_enable="pf"
					configure_nat
				fi
			fi
		done
	done
	# flush unconfigured marker
	${miscdir}/sqlcli ${dbdir}/local.sqlite DELETE FROM unconfigured
	# constants and static param. FIX ME
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET repo=\"https://bsdstore.ru\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET workdir=\"${workdir}\"
	_ret=$( sysctl -n net.inet.ip.fw.enable 2>/dev/null )
	if [ "${_ret}" = "1" ]; then
		_ret=1
	else
		_ret=0
	fi

	# Overwrite $platform to HardenedBSD if we have /usr/sbin/hbsd-update:
	[ -e "/usr/sbin/hbsd-update" ] && platform="HardenedBSD"
	# Overwrite $platform to TrueOS if we have TrueOS-specific dirs
	[ -d "/usr/local/etc/trueos" -a -d "/usr/local/share/trueos" ] && platform="TrueOS"

	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET ipfw_enable=\"${_ret}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET fs=\"${_myfs}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET jail_interface=\"${nics}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET nodedescr=\"${nodedescr}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET nodename=\"${nodename}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET hostname=\"${hostname}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET vnet=\"${vnet}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET racct=\"${racct}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET platform=\"${platform}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET node_ip4_active=\"${node_ip4_active}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET node_ip6_active=\"${node_ip6_active}\"

	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET nodeip=\"${nodeip}\"
	${miscdir}/sqlcli ${dbdir}/local.sqlite UPDATE local SET natip=\"${natip}\"

	local FILES="descr role domain notes location"
	for i in $FILES; do
		[ ! -f "${workdir}/${i}" ] && /usr/bin/touch ${workdir}/node.${i} && /usr/sbin/chown cbsd:cbsd ${workdir}/node.${i}
	done

	/usr/local/bin/cbsd netinv
	# temporary update ascii inventory
	env sqlcolnames="1" ${miscdir}/sqlcli ${dbdir}/local.sqlite "SELECT * FROM local" > ${inventory}
	local _formfile="${jailsysdir}/CBSDSYS/helpers/cbsd.sqlite"

	[ ! -r  ${_formfile} ] && return 0

	for i in cbsdd_enable nodename nodeip jnameserver nodeippool ipfw_enable parallel stable sqlreplica; do
		myval=
		eval myval=\$${i}
		tmpval=$( /usr/local/bin/sqlite3 ${_formfile} "SELECT cur FROM forms WHERE param=\"${i}\" LIMIT 1" )
		if [ -z "${tmpval}" ]; then
			/usr/local/bin/sqlite3 ${_formfile} "UPDATE forms SET cur=\"${myval}\" WHERE param=\"${i}\""
		fi
	done
}

phase6()
{
	. ${workdir}/${localcbsdconffile}
	${ECHO} "${MAGENTA}[Stage 6: ${GREEN}authentication keys${MAGENTA}]${NORMAL}"

	install_sshkey
}

phase7()
{
	local SECCMD _i _cmd _lnk _dst _modulename _moduledir
	${ECHO} "${MAGENTA}[Stage 7: ${GREEN}modules${MAGENTA}]${NORMAL}"

	[ ! -f "${etcdir}/modules.conf" ] && return 0

	# Install module
	for _i in $( /bin/cat ${etcdir}/modules.conf ); do
		[ ! -f "${moduledir}/${_i}/securecmd" ] && continue
		. ${moduledir}/${_i}/securecmd
		for _cmd in ${SECCMD}; do
			if [ ! -h "${moduledir}/${_cmd}" ]; then
				/bin/ln -sfh ${moduledir}/${_i}/${_cmd} ${moduledir}/${_cmd}
				${ECHO} "${MAGENTA}Installing module ${_i} cmd: ${GREEN}${_cmd}${NORMAL}"
			fi
		done
	done

	# Deinstall module
	for _lnk in $( /usr/bin/find ${moduledir} -type l -depth 1 -maxdepth 1 ); do
		_dst=$( /usr/bin/readlink ${_lnk} )
		_dst=$( /usr/bin/dirname ${_dst} )
		#append slash for next excluding in _modulename
		_moduledir="${moduledir}/"
		_modulename="${_dst#$_moduledir}"

		${GREP_CMD} "^${_modulename}" ${etcdir}/modules.conf >/dev/null 2>&1
		if [ $? -eq 1 ]; then
			${ECHO} "${MAGENTA}Removing module ${_modulename} cmd: ${GREEN}${_dst}${NORMAL}"
			/bin/rm -f ${_lnk}
		fi
	done
}

phase8()
{
	local OLD_FILES OLD_DIRS
	. ${distdir}/ObsoleteFiles

	# append for modules Obsolete cmd part
	if [ -f "${etcdir}/modules.conf" ]; then
		for i in $( /bin/cat ${etcdir}/modules.conf ); do
			[ ! -f "${moduledir}/${i}/ObsoleteFiles" ] && continue
			. ${moduledir}/${i}/ObsoleteFiles
		done
	fi

	${ECHO} "${MAGENTA}[Stage 9: ${GREEN}cleanup${MAGENTA}]${NORMAL}"
	$ECHO "${MAGENTA} * Remove obsolete files..."

	for i in $OLD_FILES; do
		[ -f "${workdir}/${i}" -o -h "${workdir}/${i}" ] && ${ECHO} "\t${MAGENTA}Removing obsolete file: ${GREEN}${workdir}/${i}${NORMAL}" && /bin/rm -f ${workdir}/${i}
	done

	for i in $OLD_DIRS; do
		[ -d "${workdir}/${i}" -o -h "${workdir}/${i}" ] && ${ECHO} "\t${MAGENTA}Removing obsolete dir: ${GREEN}${workdir}/${i}${NORMAL}" && /bin/rmdir ${workdir}/${i}
	done
	printf "${NORMAL}"
}

post_message()
{
	[ ${first_init} -eq 0 ] && return 0
	${ECHO} "  ${GREEN}First CBSD initialization complete."
	${ECHO}
	${ECHO} "  Now your can run:"
	${ECHO} "  ${NORMAL}${BOLD}service cbsdd start${NORMAL}${GREEN}"
	${ECHO} "  to run CBSD services."
	${ECHO}
	${ECHO} "  For change initenv settings in next time, use:"
	${ECHO} "  ${NORMAL}${BOLD}cbsd initenv-tui${NORMAL}${GREEN}"
	${ECHO}
	${ECHO} "  Also don't forget to execute:"
	${ECHO} "  ${NORMAL}${BOLD}cbsd initenv${NORMAL}${GREEN}"
	${ECHO} "  every time when you upgrade CBSD version.${NORMAL}"
	${ECHO}
}

############ start locking section #############
start()
{
	if [ -n "${INITCFG}" ]; then
		inter=0
		ALWAYS_YES=1
		. "${INITCFG}" 2>/dev/null
	fi

	[ -z "${ECHO}" ] && ECHO="echo -e"

	if [ -z "${workdir}" ]; then
		. /etc/rc.conf
		if [ -n "${cbsd_workdir}" ]; then
			workdir="${cbsd_workdir}"
		else
			workdir="/usr/jails"
		fi
	fi

	. ${globalconf}
	. ${distdir}/nc.subr
	. ${distdir}/tools.subr
	. ${distdir}/initenv.subr
	. ${distdir}/ansiicolor.subr

	if [ "${globalconf}" = "${localcbsdconf}" ]; then
		${ECHO} "${MAGENTA}Please use difference path for workdir. Not ${GREEN}${distdir}${NORMAL}"
		exit 1
	fi

	/bin/cat << EOF_HEADER
-------[${product} v.${myversion}]-------
 This is install/upgrade scripts for ${product}.
 Don't forget to backup.
-----------------------------
EOF_HEADER

	if [ "${inter}" != "0" ]; then
		getyesno "Do you want prepare or upgrade hier environment for ${product} now?" || exit 0
	fi
	${ECHO} "${MAGENTA}>>> Installing or upgrading${NORMAL}"
	phase0
	phase1
	phase2
	phase3

	. /etc/rc.conf

	if [ "${cbsd_workdir}" != "${workdir}" ]; then
		if getyesno "Shall i modify the /etc/rc.conf to sets cbsd_workdir=\"${workdir}\"?: $p"; then
			${SYSRC_CMD} -vf /etc/rc.conf cbsd_workdir="${workdir}"
		else
			${SYSRC_CMD} -qf ${workdir}/rc.conf cbsd_workdir=""
		fi
	fi

	[ -d ${workdir} -a ! -f ${workdir}/rc.conf ] && ${TOUCH_CMD} ${workdir}/rc.conf

	if [ $( ${GREP_CMD} ^cbsd_workdir= /etc/rc.conf ${workdir}/rc.conf | /usr/bin/wc -l ) = 0 ]; then
		if getyesno "Shall i modify the /etc/rc.conf to sets cbsd_workdir=\"${workdir}\"?: $p"; then
			${SYSRC_CMD} -vf /etc/rc.conf cbsd_workdir="${workdir}"
		else
			${SYSRC_CMD} -qf ${workdir}/rc.conf cbsd_workdir=""
		fi
	fi

	phase4
	phase5
	# Inventory area
	phase6
	#Finnaly export new inventory from SQLite data for ASCii
	collect_info
	update_hwinfo
	env sqlcolnames="1" ${miscdir}/sqlcli ${dbdir}/local.sqlite "SELECT * FROM local" > ${inventory}
	# end of Inventory
	phase7
	phase8

	[ ! -f "${workdir}/rc.conf" ] && /usr/bin/touch ${workdir}/rc.conf
	configure_rsync
	configure_racct

	if [ $( ${GREP_CMD} ^cbsdd_enable= /etc/rc.conf ${workdir}/rc.conf | /usr/bin/wc -l ) = 0 ]; then
		if getyesno "Shall i modify the /etc/rc.conf to sets cbsdd_enable=YES ?"; then
			${SYSRC_CMD} -vf /etc/rc.conf cbsdd_enable=YES
		else
			${SYSRC_CMD} -qf ${workdir}/rc.conf cbsdd_enable="NO"
		fi
	fi

	freebsdhostversion=$( ${miscdir}/elf_tables --ver /bin/sh 2>/dev/null )

	if [ ${freebsdhostversion} -lt 1000510 ]; then
		# only for FreeBSD 10.0, not for 10.0+
		if [ $( ${GREP_CMD} ^devfs_load_rulesets= /etc/rc.conf ${workdir}/rc.conf | /usr/bin/wc -l ) = 0 ]; then
			#we need initialization of ruleset for proper view on dev in jail
			if getyesno "Shall i modify the /etc/rc.conf to sets devfs_load_rulesets=YES?"; then
				${SYSRC_CMD} -vf /etc/rc.conf devfs_load_rulesets=YES
				/usr/sbin/service devfs restart
			else
				${SYSRC_CMD} -qf ${workdir}/rc.conf devfs_load_rulesets=YES
			fi
		fi
	fi

	if [ $( ${GREP_CMD} ^rcshutdown_timeout= /etc/rc.conf ${workdir}/rc.conf | /usr/bin/wc -l ) = 0 ]; then
		if getyesno "Shall i modify the /etc/rc.conf to sets rcshutdown_timeout=\"900\"?"; then
			${SYSRC_CMD} -vf /etc/rc.conf rcshutdown_timeout="900"
		else
			${SYSRC_CMD} -qf ${workdir}/rc.conf rcshutdown_timeout="900"
		fi
	fi

	if [ $( ${GREP_CMD} ^sshd_flags= /etc/rc.conf ${workdir}/rc.conf | /usr/bin/wc -l ) = 0 ]; then
		if getyesno "Shall i modify default SSH daemon port from 22 to 22222 on this host via /etc/rc.conf and sshd_flags=\"-oPort=22222\" which is default for cbsd?"; then
			${SYSRC_CMD} -vf /etc/rc.conf sshd_flags="-oPort=22222"
		else
			${SYSRC_CMD} -qf ${workdir}/rc.conf sshd_flags="-oPort=22222"
		fi
	fi

	phaseX

	hash -r
	${ECHO} "${MAGENTA}>>> Done${NORMAL}"
	post_message
	exit 0
}

# export LOCK_CMD
init_lock()
{
	if [ -x /usr/bin/lockf ]; then
		LOCK_CMD="/usr/bin/lockf -t0 -s "
	elif [ -x /usr/bin/flock ]; then
		LOCK_CMD="/usr/bin/flock -w0 -x "
	fi

	if [ -z "${LOCK_CMD}" ]; then
		echo "No such lock management stuff (lockf, flock)"
		exit 0
	fi
}



### MAIN ###
init_lock

if [ -z "${workdir}" ]; then
	. /etc/rc.conf
	if [ -n "${cbsd_workdir}" ]; then
		workdir="${cbsd_workdir}"
	else
		workdir="/usr/jails"
	fi
fi


if [ $# -ne 1 ]; then
	if [ "${inter}" = "0" ]; then
		${LOCK_CMD} ${MYLOCK} env INITCFG="${INITCFG}" $0 inter=0 start
	else
		${LOCK_CMD} ${MYLOCK} env INITCFG="${INITCFG}" $0 start
	fi
fi

[ -n "${INITCFG}" -a -r "${INITCFG}" ] && . ${INITCFG}

set -e
. ${distdir}/cbsd.conf
set +e

platform=$( uname -s )

# Overwrite $platform to HardenedBSD if we have /usr/sbin/hbsd-update:
[ -e "/usr/sbin/hbsd-update" ] && platform="HardenedBSD"
# Overwrite $platform to TrueOS if we have TrueOS-specific dirs
[ -d "/usr/local/etc/trueos" -a -d "/usr/local/share/trueos" ] && platform="TrueOS"

[ -f "${distdir}/cmd.subr" ] && . ${distdir}/cmd.subr
[ -f "${distdir}/${platform}.subr" ] && . ${distdir}/${platform}.subr

case "$1" in
	start)
		start
	;;
esac
