#!/bin/sh
# Re-generate external executable cmd macros:
# different platforms may have different full/realpaths
: ${distdir="/usr/local/cbsd"}
# MAIN
if [ -z "${workdir}" ]; then
	[ -z "${cbsd_workdir}" ] && . /etc/rc.conf
	[ -z "${cbsd_workdir}" ] && exit 0
	workdir="${cbsd_workdir}"
fi

[ ! -f "${distdir}/cbsd.conf" ] && exit 0

. ${distdir}/cbsd.conf

CMD_FILE=${workdir}/cmd.subr
export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

# Hardened/FreeBSD/TrueOS-specific CMD
add_freebsd_cmd()
{
	MAIN_CMD="${MAIN_CMD} \
acpidump \
chflags \
devfs \
dpv \
etcupdate \
fetch \
getent \
zfs \
zpool \
ipfw \
cpuset \
geli \
growfs \
gpart \
idprio \
jexec \
jot \
kenv \
kldload \
kldstat \
lockf \
login \
makefs \
md5 \
mdconfig \
mkimg \
mkuzip \
mtree \
newfs \
newfs_msdos \
ndp \
pciconf \
pw \
sha256 \
sockstat \
rctl \
setfib \
sysrc \
ulimit \
uuencode \
"
}

# DragonflyBSD-specific CMD
add_dragonfly_cmd()
{
	MAIN_CMD="${MAIN_CMD} \
chflags \
fetch \
hammer2 \
idprio \
jexec \
jot \
kenv \
kldload \
kldstat \
lockf \
login \
mount_hammer2 \
mtree \
newfs \
pciconf \
pw \
sha256 \
sysrc \
uuencode \
"
}

# Linux-specific CMD
add_linux_cmd()
{
	MAIN_CMD="${MAIN_CMD} \
chattr \
wget \
flock \
md5sum \
sha256sum \
uuencode \
"
}

#  optional/feature command
OPTIONAL_CMD="\
bhyvectl \
bhyve \
bsdlabel \
git \
jail \
xl"

# main cmd: generic command for all platform
MAIN_CMD="\
arp \
awk \
basename \
cat \
cc \
chown \
chmod \
chroot \
column \
cp \
cpio \
cut \
daemon \
date \
dd \
df \
du \
dirname \
egrep \
env \
find \
file \
grep \
gzip \
gunzip \
head \
hexdump \
hostname \
id \
ifconfig \
install \
kill \
killall \
ldd \
ln \
ls \
make \
mkdir \
mktemp \
mount \
mv \
nc \
nice \
pkgconf \
pax \
ps \
ping \
pwd \
readlink \
realpath \
rm \
rmdir \
route \
rsync \
scp \
sed \
seq \
service \
sort \
ssh \
ssh-keygen \
stat \
strings \
su \
sync \
sysctl \
stty \
sqlite3 \
tail \
tar \
tee \
timeout \
touch \
uname \
tr \
truncate \
umount \
uuidgen \
whoami \
xargs \
xz \
xzcat \
wc \
"

# check by FreeBSD version, since the misc/elf_tables may be absent on first init
case "${platform}" in
	Linux)
		_version=$( sysctl -n kernel.osrelease 2>/dev/null | cut -d "-" -f 1  | tr '.' '0' )
		;;
	NetBSD)
		_version=$( sysctl -n kern.osrevision 2>/dev/null )
		;;
	*)
		_version=$( sysctl -n kern.osreldate 2>/dev/null )
		if [ -z "${_version}" ]; then
			echo "unable to get sysctl kern.osreldate"
			exit 1
		fi
		;;
esac

case "${platform}" in
	FreeBSD|HardenedBSD|TrueOS)
		if [ ${_version} -lt 1300131 ]; then
			# https://svnweb.freebsd.org/base?view=revision&revision=r368045
			MAIN_CMD="${MAIN_CMD} ping6"
		fi
		add_freebsd_cmd
		;;
	DragonFly)
		add_dragonfly_cmd
		;;
	Linux)
		add_linux_cmd
		;;
esac

truncate -s0 ${CMD_FILE}

cat > ${CMD_FILE} <<EOF
if [ ! "\$_CBSD_CMD_SUBR" ]; then
_CBSD_CMD_SUBR=1
###
EOF
	if [ $? -ne 0 ]; then
		echo "cmdboot: append error: ${CMD_FILE}"
		cat >> ${CMD_FILE} <<EOF
###
fi
EOF
		exit 1
	fi

MAIN_CMD=$( echo ${MAIN_CMD} | sort )
OPTIONAL_CMD=$( echo ${OPTIONAL_CMD} | sort )

for i in ${MAIN_CMD}; do
	mycmd=
	mycmd=$( which ${i} 2>/dev/null )

	if [ -z "${mycmd}" -a ! -x "${mycmd}" ]; then
		echo "cmdboot: no such executable, CBSD dependency/requirement: ${i}"
		cat >> ${CMD_FILE} <<EOF
###
fi
EOF
		exit 1
	fi
	MY_CMD=$( echo ${i} | tr '\-[:lower:]' '_[:upper:]' )
	MY_CMD="${MY_CMD}_CMD"

	echo "${MY_CMD}=\"${mycmd}\"" >> ${CMD_FILE}
done

for i in ${OPTIONAL_CMD}; do
	mycmd=
	mycmd=$( which ${i} 2>/dev/null )

	if [ -z "${mycmd}" -a ! -x "${mycmd}" ]; then
		feature=
		case "${i}" in
			bhyve*)
				feature="bhyve_feat"
				;;
			jail)
				feature="jail_feat"
				;;
			xl)
				feature="xen_feat"
				;;
		esac

		if [ -n "${feature}" ]; then
			if [ -h ${dbdir}/local.sqlite ]; then
				echo "    cmdboot: no such optional executable: ${i}, ${feature} disabled"
				sqlite3 ${dbdir}/local.sqlite "UPDATE local SET ${feature}=\"0\""
			fi
		fi
	fi

	MY_CMD=$( echo ${i} | tr '\-[:lower:]' '_[:upper:]' )
	MY_CMD="${MY_CMD}_CMD"

	echo "${MY_CMD}=\"${mycmd}\"" >> ${CMD_FILE}

done

cat >> ${CMD_FILE} <<EOF
###
fi
EOF
