#!/bin/sh /etc/rc.common
# banIP init script - ban incoming and outgoing IPs via named nftables Sets
# Copyright (c) 2018-2026 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.

# (s)hellcheck exceptions
# shellcheck disable=all

START=95
USE_PROCD=1

extra_command "report" "[text|json|mail|gen] Print banIP related Set statistics"
extra_command "search" "[<IPv4 address>|<IPv6 address>] Check if an element exists in a banIP Set"
extra_command "content" "[<Set name>] [true|false] Listing of all or only elements with hits of a given banIP Set"
extra_command "actual" "Print nft/monitor actuals"

ban_init="/etc/init.d/banip"
ban_service="/usr/bin/banip-service.sh"
ban_funlib="/usr/lib/banip-functions.sh"
ban_pidfile="/var/run/banIP/banIP.pid"
ban_lock="/var/run/banIP/banIP.lock"

if [ -z "${IPKG_INSTROOT}" ]; then

	# check for running instance and handle boot trigger
	#
	case "${action}" in
	"boot")
		"${ban_init}" running && exit 0
		;;
	"stop" | "report" | "content")
		"${ban_init}" running || exit 0
		;;
	esac

	# reset pidfile if no/stale process is found,
	# otherwise exit with error to prevent multiple instances
	#
	case "${action}" in
	"boot" | "start" | "restart" | "reload" | "search")
		if [ -d "${ban_lock}" ]; then
			pid="$(cat "${ban_pidfile}" 2>/dev/null)"
			if [ -n "${pid}" ] && kill -0 "${pid}" 2>/dev/null; then
				exit 1
			else
				rm -rf "${ban_lock}"
			fi
		fi
		mkdir -p "${ban_lock}"
		;;
	esac
	. "${ban_funlib}"
fi

boot() {
	rc_procd start_service boot
}

start_service() {
	if "${ban_init}" enabled; then
		f_rmpid
		procd_open_instance "banip-service"
		procd_set_param command "${ban_service}" "${@:-"${action}"}"
		procd_set_param pidfile "${ban_pidfile}"
		procd_set_param nice "$(uci_get banip global ban_nicelimit "0")"
		procd_set_param limits nofile="$(uci_get banip global ban_filelimit "1024")"
		procd_set_param stdout 0
		procd_set_param stderr 1
		procd_close_instance
	else
		f_log "err" "banIP service autostart is disabled"
	fi
}

reload_service() {
	f_rmpid
	rc_procd start_service reload
}

stop_service() {
	"${ban_nftcmd}" delete table inet banIP >/dev/null 2>&1
	f_genstatus "stopped"
	f_rmpid
	[ "${action}" = "stop" ] && rm -rf "${ban_lock}"
}

restart() {
	stop_service
	rc_procd start_service restart
}

status() {
	status_service
}

status_service() {
	f_getstatus
}

report() {
	f_report "${1:-"text"}"
}

search() {
	f_search "${1}"
	rm -rf "${ban_lock}"
}

content() {
	f_content "${1}" "${2:-"false"}"
}

actual() {
	f_actual
}

service_triggers() {
	local iface trigger delay

	delay="$(uci_get banip global ban_triggerdelay "20")"
	trigger="$(uci_get banip global ban_trigger)"

	PROCD_RELOAD_DELAY="$((delay * 1000))"
	for iface in ${trigger}; do
		procd_add_interface_trigger "interface.*.up" "${iface}" "${ban_init}" start
	done
}
