#!/usr/local/bin/cbsd
#v12.0.4
MYARG=""
MYOPTARG="ver arch target_arch destdir"
MYDESC="Update base jail"
CBSDMODULE="sys"
ADDHELP="by default - update all available bases\n\
 you can specify via additional args individual bases for\n\
 update via: ver=,arch=,target_arch=\n"

. ${subrdir}/nc.subr
. ${system}

ver=
arch=
target_arch=
destdir=

keyprint=
servername=
components=

. ${cbsdinit}

readconf ${platform}-baseupdate.conf

generate_freebsd_config()
{
	local _res

	# validate mandatory variables
	for i in keyprint servername components; do
		_res=
		eval _res="\$$i"
		[ -z "${_res}" ] && err 1 "${N1_COLOR}baseupdate generate_freebsd_config error: empty variable ${N2_COLOR}${i}${N1_COLOR}. please use ${platform}-baseupdate.conf to setup${N0_COLOR}"
	done

	${CAT_CMD} << EOF > "${1}"
KeyPrint ${keyprint}
ServerName ${servername}
Components ${components}
IgnorePaths
IDSIgnorePaths /usr/share/man/cat
IDSIgnorePaths /usr/share/man/whatis
IDSIgnorePaths /var/db/locate.database
IDSIgnorePaths /var/log
UpdateIfUnmodified /etc/ /var/ /root/ /.cshrc /.profile
MergeChanges /etc/ /boot/device.hints
EOF
}

update_base()
{
	local _i _res
	sqlfile="local"
	local _mod_count=0

	_sql="SELECT platform,name,arch,targetarch,ver FROM bsdbase"

	# when user specified several parameters,
	# add this as modifiers to narrow down the conditions for an exact result.
	# for example when ver= specidied, we got: "WHERE ver=X"

	for i in ver arch target_arch; do
		_res=
		eval _res="\$$i"
		[ -z "${_res}" ] && continue
		case ${_mod_count} in
			0)
				# first modificator
				_sql="${_sql} WHERE ${i}=\"${_res}\""
				;;
			*)
				# append modificator, concat with AND
				_sql="${_sql} AND ${i}=\"${_res}\""
				;;
		esac
		_mod_count=$(( _mod_count + 1 ))
	done

	#echo "[debug]: ${_sql}"
	local sqldelimer=" "

	cbsdsqlro ${sqlfile} ${_sql} | while read _platform _name _arch _targetarch _ver; do
		base="${_name}_${_arch}_${_targetarch}_${_ver}"
		basepath=${workdir}/basejail/${base}
		if [ ! -r ${basepath}/bin/sh ]; then
			${ECHO} "${N1_COLOR}No such /bin/sh in: ${N2_COLOR}${basepath}${N1_COLOR}. Bad dir/hier? Skipped${N0_COLOR}"
			continue
		fi
		printf "${N1_COLOR}Updating ${basepath}: ${N0_COLOR}"

		# set fake env
		set_bsdenv_by_path -p ${basepath} -v ${_ver}
		${UNAME_CMD} -v
		case "${platform}" in
			HardenedBSD)
				${ECHO} "${N1_COLOR}/usr/sbin/hbsd-update -n -r \"${N2_COLOR}${basepath}${N1_COLOR}\"${N0_COLOR}"
				/usr/sbin/hbsd-update -n -r "${basepath}"
				;;
			FreeBSD)
				updateconf=$( ${MKTEMP_CMD} )
				trap "${RM_CMD} -f ${update_conf}" HUP INT ABRT BUS TERM EXIT
				generate_freebsd_config "${updateconf}"
				FBSD_UPDATE="/usr/sbin/freebsd-update -f ${updateconf} -b ${basepath} --not-running-from-cron"
				${ECHO} "${N1_COLOR}${FBSD_UPDATE}${N0_COLOR}"
				${ENV_CMD} PAGER=${CAT_CMD} ${FBSD_UPDATE} fetch install
				;;
		esac

		unset_bsdenv
	done
}

. ${subrdir}/time.subr
st_time=$( ${DATE_CMD} +%s )

update_base

end_time=$( ${DATE_CMD} +%s )
diff_time=$(( end_time - st_time ))
diff_time=$( displaytime ${diff_time} )
${ECHO} "${N1_COLOR}${CBSD_APP} done ${N2_COLOR}in ${diff_time}${N0_COLOR}"

exit 0
