#!/bin/bash
# Last-Updated: 2026-07-19 13:49 EDT
# Created: 2026-04 (live EventScript lineage); packaged 2026-07 as NO-policy
# Authors: Paul Aidukas KN2R, Logan Crook K8LRC
# PACKAGE TEMPLATE — DO NOT EDIT for normal installs (installer copies/fills this).
#
# ============================================================================
# SETUP TEMPLATE - NO conference POLICY (simple / tester use)
# Copy this file to your TLB server as tlbevent.sh
# (see SETUP-INSTRUCTIONS.txt Step 6, choice B). Then:
#   chmod +x /path/to/tlbevent.sh
#   EventScript = /path/to/tlbevent.sh   (in tlb.conf)
#
# This is the EventScript WITHOUT rapid-reconnect / multi-conference bans.
# For conference POLICY ops, use tlbevent-conference.template ->
# tlbevent-conference.sh instead (Step 6, choice A).
#
# Verify these paths for YOUR system (edit defaults below if different):
#   TLBCMD       - path to tlbcmd (default /usr/local/bin/tlbcmd)
#   TLB_LOGFILE  - TLB messages log (default /home/tlb/log/messages)
#   STATE_DIR    - shared with tlbevent-conference.sh so leftover --monitor is stopped
#
# Includes: linkit (WD5M-style) + IRLP TCP 15425 on bump/kick/ban for stn####
# Does NOT include: rapid-reconnect bans, multi-conference bans
# ============================================================================
#
# WD5M (original linkit) / K8LRC (IRLP 15425 + no-policy mode)
#

TLBCMD="${TLBCMD:-/usr/local/bin/tlbcmd}"
TLB_LOGFILE="${TLB_LOGFILE:-/home/tlb/log/messages}"
ACTION_LOG="${EVENT_LOGFILE:-${TLB_LOGFILE}}"
# Same state dir as tlbevent-conference.sh so leftover --monitor can be stopped.
STATE_DIR="${TLB_STATE_DIR:-/var/lib/thelinkbox/tlbevent_state}"
PID_FILE="${STATE_DIR}/monitor.pid"

log() {
	local MESSAGE="TLB: $*"
	echo "${0##*/}:${MESSAGE}" >&2
	if [[ -n "${ACTION_LOG}" ]]; then
		echo "$(date '+%b %d %Y %T %z') ${MESSAGE}" >> "${ACTION_LOG}"
	fi
}

# tlbevent-conference.sh leaves a background --monitor that still bans multi-conf.
# Kill it whenever this no-policy script runs, or testing is useless.
stop_full_policy_monitor() {
	local pid=""
	if [[ -f "${PID_FILE}" ]]; then
		pid="$(tr -d ' \r\n' < "${PID_FILE}" 2>/dev/null || true)"
		if [[ -n "${pid}" ]]; then
			kill "${pid}" 2>/dev/null || true
			log "stopped leftover policy monitor pid ${pid}"
		fi
		rm -f "${PID_FILE}"
	fi
	pkill -f '/home/thelinkbox/scripts/tlbevent-conference\.sh --monitor' 2>/dev/null || true
	pkill -f '/home/tlb/scripts/tlbevent-conference\.sh --monitor' 2>/dev/null || true
	# Legacy names (older installs)
	pkill -f '/home/thelinkbox/scripts/tlbevent\.conference\.sh --monitor' 2>/dev/null || true
	pkill -f '/home/tlb/scripts/tlbevent\.conference\.sh --monitor' 2>/dev/null || true
	pkill -f '/home/thelinkbox/scripts/tlbevent\.sh --monitor' 2>/dev/null || true
	pkill -f '/home/tlb/scripts/tlbevent\.sh --monitor' 2>/dev/null || true
}

# Loop through connected users and link the new connection (WD5M original).
linkit() {
	local THISCALL="${1}"
	local USERS ISCONF line

	USERS="$(${TLBCMD} -s "..users" 2>/dev/null)"
	ISCONF="$(${TLBCMD} -s "..set ConfEnable" 2>/dev/null | tail -1 | cut -d' ' -f3)"
	if [[ "${ISCONF}" =~ ^[0-9]+$ ]] && (( ISCONF == 1 )); then
		log "Linking is not supported with ConfEnable enabled."
		log "Setting ConfEnable = 0"
		${TLBCMD} -s "..set ConfEnable = 0" >/dev/null 2>&1 || true
	fi

	IFS=$'\n'
	for line in ${USERS}; do
		unset IFS
		set -- ${line}
		if [[ "${1}" == *[0-9]. ]]; then
			if [[ "${3}" == *K* || "${3}" == *x* ]]; then
				log "${2} is already kicked or inactive, skipping link: ${*}"
				continue
			fi
			if [[ "${2}" == "${THISCALL}" ]]; then
				log "${THISCALL} skip same node: ${*}"
				continue
			fi
			if [[ "${3}" == *R* ]]; then
				if [[ ${MONITOR:-0} -eq 1 ]]; then
					log "unlink ${THISCALL} ${2} in monitor mode: ${*}"
					${TLBCMD} -s "..unlink ${THISCALL} ${2}" >/dev/null 2>&1 || true
				else
					log "link -m ${THISCALL} ${2}: ${*}"
					${TLBCMD} -s "..link -m ${THISCALL} ${2}" >/dev/null 2>&1 || true
				fi
			else
				log "link ${THISCALL} ${2}: ${*}"
				${TLBCMD} -s "..link ${THISCALL} ${2}" >/dev/null 2>&1 || true
			fi
		fi
		IFS=$'\n'
	done
	unset IFS
}

# IRLP stn####: send disconnect on TCP 15425 (same as tlbevent-conference.sh).
handle_command_event() {
	local event="$1"
	local talking="" station="" sf_bind_ip="" nodeip="" statusmsg="" cmdargs=""

	if [[ "${event}" != "command" ]]; then
		return 0
	fi

	if [[ "${3}" == *idisc* || "${3}" == *ikick* || "${3}" == *iban* ]]; then
		if [[ "${4}" == "." ]]; then
			talking="$(${TLBCMD} -s port 2>/dev/null | egrep 'Rx$' | tail -1 | cut -c3- | cut -d' ' -f1)"
		fi

		if [[ ${4:0:3} == stn || ${5:0:3} == stn || ${talking:0:3} == stn ]]; then
			station="${4}"
			[[ -n "${5:-}" ]] && station="${5}"
			[[ -n "${talking}" ]] && station="${talking}"
			sf_bind_ip="$(${TLBCMD} -s "set SFBind2IP" 2>/dev/null | grep '^SFBind2IP' | cut -d' ' -f3 | tr -d '"')"
			[[ -n "${sf_bind_ip}" ]] && sf_bind_ip="-s ${sf_bind_ip}"
			nodeip="$(${TLBCMD} -s "showip" 2>/dev/null | egrep "^${station}[[:space:]]" | tail -1 | cut -f2)"
			[[ -z "${nodeip}" ]] && nodeip="${station}.ip.irlp.net"
			log "sending disconnect to ${station} ${nodeip}"
			statusmsg="$(echo disconnect | nc ${sf_bind_ip} -w2 -q2 "${nodeip}" 15425 2>/dev/null)"
			[[ -n "${statusmsg}" ]] && log "${statusmsg}"
		fi

		cmdargs="${4:-}"
		[[ -n "${5:-}" ]] && cmdargs="${cmdargs} ${5}"
		[[ -n "${6:-}" ]] && cmdargs="${cmdargs} ${6}"
		statusmsg="$(${TLBCMD} -s "${3:1} ${cmdargs}" 2>/dev/null)"
		[[ -n "${statusmsg}" ]] && log "${statusmsg}"
		return 0
	fi

	if [[ "${3}" == "bump" ]]; then
		if [[ ${4:0:3} == stn ]]; then
			sf_bind_ip="$(${TLBCMD} -s "set SFBind2IP" 2>/dev/null | grep '^SFBind2IP' | cut -d' ' -f3 | tr -d '"')"
			[[ -n "${sf_bind_ip}" ]] && sf_bind_ip="-s${sf_bind_ip}"
			nodeip="$(${TLBCMD} -s "showip" 2>/dev/null | egrep "^${4}[[:space:]]" | tail -1 | cut -f2)"
			[[ -z "${nodeip}" ]] && nodeip="${4}.ip.irlp.net"
			log "sending disconnect to ${4} ${nodeip}"
			statusmsg="$(echo disconnect | nc ${sf_bind_ip} -w2 -q2 "${nodeip}" 15425 2>/dev/null)"
			[[ -n "${statusmsg}" ]] && log "${statusmsg}"
		fi
		statusmsg="$(${TLBCMD} -s "disconnect ${4}" 2>/dev/null)"
		[[ -n "${statusmsg}" ]] && log "${statusmsg}"
	fi
}

#
# ${1} = event  ${2} = type  ${3} = user  ${4} = user_count
#
log "${1:-} ${2:-} ${3:-} ${4:-}"

case "${1:-}" in
	starting)
		stop_full_policy_monitor
		log "tlbevent.sh active (linkit + IRLP 15425 only; policy off)"
		;;
	connected)
		stop_full_policy_monitor
		linkit "${3}"
		;;
	shutdown)
		stop_full_policy_monitor
		;;
	command)
		handle_command_event "$@"
		;;
	*)
		:
		;;
esac

exit 0
