#!/bin/sh
# The notice page's server (ADR 0108 §2.6, PLAN WP A-3). A blocked device's plain HTTP is redirected (the kill switch's table, A-2)
# to the router's own address on notice_port; this is what answers there: a second uhttpd, not LuCI's, on the router's LAN addresses
# only (never a wildcard, so the WAN cannot reach it), serving the one page the state hook writes into the run directory (tmpfs: a
# state change never writes flash). Every path answers with that page (-E), whatever the Host: the redirect keeps the original one.
#
#   serve --listen          the LAN addresses this router has, as ip:port, one line (the init passes them back to a start)
#   serve <ip:port>...      run uhttpd in the foreground on exactly those (procd's instance; exec, so procd supervises uhttpd)
#
# The init defines the instance with the --listen answer as its arguments, so an address or port change is a changed command line
# and a `start` swaps the instance. Nothing here is a secret and nothing here reads one.
. "${FV_LIB:-/lib/forestvpn}/adapter.sh"
fv_load
NOTICE_DIR=${NOTICE_DIR:-$FV_RUN/notice}
WRITE=$(dirname "$0")/write

listen() { # the global IPv4 addresses of the LAN zone's devices (fv_landevs), each with the port
	local d
	for d in $FV_LANDEVS; do
		ip -4 -o addr show dev "$d" 2> /dev/null | awk '/scope global/ { for (i = 1; i < NF; i++) if ($i == "inet") { a = $(i + 1); sub("/.*", "", a); print a } }'
	done | while read -r a; do fv_is_ip4 "$a" && echo "$a:$FV_NPORT"; done | awk '!s[$0]++' | tr '\n' ' ' | sed 's/ $//'
}

[ "${1:-}" = --listen ] && { listen; echo; exit 0; }
[ $# -gt 0 ] || { echo "forestvpn notice: no LAN address to listen on" >&2; exit 1; }

n=$#
while [ $n -gt 0 ]; do
	a=${1%:*}; p=${1##*:}
	fv_is_ip4 "$a" && [ "$a" != 0.0.0.0 ] && [ "$(fv_num "$p" 1 65535 0)" = "$p" ] && [ "$1" = "$a:$p" ] \
		|| { echo "forestvpn notice: '$1' is not an IPv4 address and port" >&2; exit 2; }
	set -- "$@" -p "$1"; shift; n=$((n - 1))
done
# the page the last state asked for, or the safe one at a boot: nothing has been said yet and the devices are held
mkdir -p "$NOTICE_DIR"
if [ ! -s "$NOTICE_DIR/index.html" ]; then
	s=$(cut -d' ' -f1 "$FV_RUN/adapter.state" 2> /dev/null); r=$(cut -d' ' -f2 "$FV_RUN/adapter.state" 2> /dev/null)
	"$WRITE" "${s:-reconnecting}" "${r:--}" || "$WRITE" reconnecting -
fi
exec uhttpd -f "$@" -h "$NOTICE_DIR" -E /index.html -I index.html -S -D -N 32 -T 10
