#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# Copyright ForestVPN
#
# luci.forestvpn's `status` (the rpcd plugin runs this file for that one method, with rpcd's standard input and nothing else):
# `fv ctl rpcd status`'s reply line, unchanged, plus one ADDITIVE top-level field, `other_router`: the routing apps that are installed AND
# turned on, by read-only checks (passwall2, podkop, pbr), in that order. The Status page warns a protected router about them (round 2 WP-H):
# protection sends what such an app leaves direct into the tunnel. A second ADDITIVE field, `pkg_version`, is the installed package's version,
# read from the file the build wrote (/usr/share/forestvpn/version): the updater's own document is tmpfs and old or empty after a reboot or an
# upgrade it did not do. Only version characters are kept ("" when the file is missing). No request value is read here: the standard input belongs to fv.
# A third ADDITIVE field, `other_vpn`: the other VPN software that is RUNNING (OW-4; a vendor firmware ships its own clients), from a closed list of
# names: strongswan, xl2tpd, pptpd, openvpn, zerotier, and wireguard for any kernel WireGuard interface that is up other than ForestVPN's fvpn0
# (ForestVPN's own tunnel is a TUN device, not a kernel WireGuard one). Read-only: nothing is stopped, disabled or removed; the Status page only warns.
PATH=/usr/sbin:/usr/bin:/sbin:/bin; export PATH
apps=
[ -x /etc/init.d/passwall2 ] && [ "$(uci -q get 'passwall2.@global[0].enabled')" = 1 ] && apps="$apps,\"passwall2\""
[ -x /etc/init.d/podkop ] && /etc/init.d/podkop enabled > /dev/null 2>&1 && apps="$apps,\"podkop\""
[ -x /etc/init.d/pbr ] && /etc/init.d/pbr enabled > /dev/null 2>&1 && [ "$(uci -q get pbr.config.enabled)" = 1 ] && apps="$apps,\"pbr\""
vpn=
for p in charon:strongswan xl2tpd:xl2tpd pptpd:pptpd openvpn:openvpn zerotier-one:zerotier; do
	pidof "${p%%:*}" > /dev/null 2>&1 && vpn="$vpn,\"${p#*:}\""
done
for d in /sys/class/net/*; do
	[ "${d##*/}" != fvpn0 ] && grep -qx DEVTYPE=wireguard "$d/uevent" 2> /dev/null && [ "$(cat "$d/operstate" 2> /dev/null)" != down ] && { vpn="$vpn,\"wireguard\""; break; }
done
ver=$(head -n 1 /usr/share/forestvpn/version 2> /dev/null | tr -cd '0-9A-Za-z.~+-' | cut -c1-64)
out=$(/usr/sbin/fv ctl rpcd status); rc=$?
case $out in
	*\}) out="${out%\}},\"other_router\":[${apps#,}],\"other_vpn\":[${vpn#,}],\"pkg_version\":\"$ver\"}" ;;
esac
[ -z "$out" ] || echo "$out"
exit $rc
