BastionGuard/data/scripts/BastionGuard-user-session-watch.sh
specialworld83 f0f913a209 Release 2.0
2026-07-15 10:52:22 +02:00

106 lines
3.1 KiB
Bash

#!/usr/bin/env bash
# BastionGuard user-session watcher
# Monitors suspend/resume and lock/unlock events, then restarts BastionGuard user services.
set -u
RESTART_SCRIPT="${BG_RESTART_SCRIPT:-/usr/share/BastionGuard/data/scripts/BastionGuard-restart-user-services.sh}"
DEBOUNCE_SECONDS="${BG_RESTART_DEBOUNCE_SECONDS:-8}"
STAMP_FILE="${XDG_RUNTIME_DIR:-/tmp}/BastionGuard-user-session-watch.last"
log_msg() {
local msg="$1"
if command -v systemd-cat >/dev/null 2>&1; then
printf '%s\n' "$msg" | systemd-cat -t BastionGuard-user-session-watch -p info
else
printf '%s\n' "BastionGuard-user-session-watch: $msg" >&2
fi
}
restart_user_services() {
local reason="$1"
local now last
now="$(date +%s)"
last="0"
if [ -r "$STAMP_FILE" ]; then
last="$(cat "$STAMP_FILE" 2>/dev/null || printf '0')"
fi
case "$last" in
''|*[!0-9]*) last="0" ;;
esac
if [ $((now - last)) -lt "$DEBOUNCE_SECONDS" ]; then
log_msg "skip restart for '$reason' because debounce is active"
return 0
fi
printf '%s\n' "$now" > "$STAMP_FILE" 2>/dev/null || true
if [ ! -x "$RESTART_SCRIPT" ]; then
log_msg "restart script missing or not executable: $RESTART_SCRIPT"
return 0
fi
log_msg "restarting BastionGuard user services after: $reason"
"$RESTART_SCRIPT" --user "$reason" || log_msg "restart script returned a non-zero status for: $reason"
}
monitor_login1_sleep() {
dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForSleep'" 2>/dev/null |
while IFS= read -r line; do
case "$line" in
*"boolean false"*) restart_user_services "resume" ;;
esac
done
}
monitor_login1_lock() {
dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Session'" 2>/dev/null |
while IFS= read -r line; do
case "$line" in
*"member=Lock"*) restart_user_services "session-lock" ;;
*"member=Unlock"*) restart_user_services "session-unlock" ;;
esac
done
}
monitor_freedesktop_screensaver() {
dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" 2>/dev/null |
while IFS= read -r line; do
case "$line" in
*"member=ActiveChanged"*) restart_user_services "screensaver-active-changed" ;;
esac
done
}
monitor_gnome_screensaver() {
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" 2>/dev/null |
while IFS= read -r line; do
case "$line" in
*"member=ActiveChanged"*) restart_user_services "gnome-screensaver-active-changed" ;;
esac
done
}
cleanup() {
trap - INT TERM EXIT
jobs -p | xargs -r kill 2>/dev/null || true
}
trap cleanup INT TERM EXIT
if ! command -v dbus-monitor >/dev/null 2>&1; then
log_msg "dbus-monitor not found; install package 'dbus' or equivalent"
while :; do sleep 3600; done
fi
log_msg "watcher started"
monitor_login1_sleep &
monitor_login1_lock &
monitor_freedesktop_screensaver &
monitor_gnome_screensaver &
# Keep the service alive. If a monitor exits, systemd restarts this watcher.
wait -n