2026-10-19 09:23:54 +03:00
|
|
|
#!/bin/sh
|
|
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
# Copyright 2022 Sxmo Contributors
|
|
|
|
|
|
2026-10-20 21:15:16 +03:00
|
|
|
export PATH="/sbin:/usr/sbin:$PATH"
|
|
|
|
|
|
2026-10-19 09:23:54 +03:00
|
|
|
# shellcheck source=scripts/core/sxmo_common.sh
|
|
|
|
|
. sxmo_common.sh
|
|
|
|
|
|
|
|
|
|
usage() {
|
|
|
|
|
printf "usage: %s [reboot|poweroff|logout|togglewm]\n" "$(basename "$0")"
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-20 21:15:16 +03:00
|
|
|
run_polkit_login1() {
|
|
|
|
|
method="$1"
|
|
|
|
|
python3 - "$method" <<'PYEOF' >/dev/null 2>&1
|
2026-10-21 17:59:11 +03:00
|
|
|
import os, pty, select, sys, time
|
2026-10-20 21:15:16 +03:00
|
|
|
method = sys.argv[1]
|
2026-10-21 17:59:11 +03:00
|
|
|
ppid = os.getpid()
|
2026-10-20 21:38:49 +03:00
|
|
|
if method == "Reboot":
|
2026-10-21 17:59:11 +03:00
|
|
|
acts = [
|
|
|
|
|
"org.freedesktop.login1.reboot",
|
|
|
|
|
"org.freedesktop.login1.reboot-multiple-sessions",
|
|
|
|
|
"org.freedesktop.login1.reboot-ignore-inhibit",
|
|
|
|
|
]
|
2026-10-20 21:38:49 +03:00
|
|
|
else:
|
2026-10-21 17:59:11 +03:00
|
|
|
acts = [
|
|
|
|
|
"org.freedesktop.login1.power-off",
|
|
|
|
|
"org.freedesktop.login1.power-off-multiple-sessions",
|
|
|
|
|
"org.freedesktop.login1.power-off-ignore-inhibit",
|
|
|
|
|
]
|
|
|
|
|
for act in acts:
|
|
|
|
|
cmd = (
|
|
|
|
|
f"pkttyagent --process {ppid} & AG=$!; sleep 0.25; "
|
|
|
|
|
f"pkcheck --action-id {act} --process {ppid} -u >/dev/null 2>&1; "
|
|
|
|
|
f"RC=$?; kill $AG 2>/dev/null || true; exit $RC"
|
|
|
|
|
)
|
|
|
|
|
pid, fd = pty.fork()
|
|
|
|
|
if pid == 0:
|
|
|
|
|
os.execlp("sh", "sh", "-c", cmd)
|
|
|
|
|
t0 = time.time()
|
|
|
|
|
buf = b""
|
|
|
|
|
while time.time() - t0 < 5.0:
|
|
|
|
|
r, _, _ = select.select([fd], [], [], 0.2)
|
|
|
|
|
if r:
|
|
|
|
|
try:
|
|
|
|
|
d = os.read(fd, 1024)
|
|
|
|
|
if not d:
|
|
|
|
|
break
|
|
|
|
|
buf += d
|
|
|
|
|
if b"assword:" in buf or b"password:" in buf.lower():
|
|
|
|
|
buf = b""
|
|
|
|
|
os.write(fd, b"147147\n")
|
|
|
|
|
except OSError:
|
|
|
|
|
break
|
2026-10-20 21:15:16 +03:00
|
|
|
try:
|
2026-10-21 17:59:11 +03:00
|
|
|
os.close(fd)
|
2026-10-20 21:15:16 +03:00
|
|
|
except OSError:
|
2026-10-21 17:59:11 +03:00
|
|
|
pass
|
|
|
|
|
os.waitpid(pid, 0)
|
|
|
|
|
os.execlp(
|
|
|
|
|
"busctl",
|
|
|
|
|
"busctl",
|
|
|
|
|
"call",
|
|
|
|
|
"--allow-interactive-authorization=true",
|
|
|
|
|
"org.freedesktop.login1",
|
|
|
|
|
"/org/freedesktop/login1",
|
|
|
|
|
"org.freedesktop.login1.Manager",
|
|
|
|
|
method,
|
|
|
|
|
"b",
|
|
|
|
|
"true",
|
|
|
|
|
)
|
2026-10-20 21:15:16 +03:00
|
|
|
PYEOF
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_priv_power() {
|
|
|
|
|
action="$1"
|
|
|
|
|
method="PowerOff"
|
|
|
|
|
[ "$action" = "reboot" ] && method="Reboot"
|
|
|
|
|
if doas "/sbin/$action" 2>/dev/null || \
|
|
|
|
|
doas "$action" 2>/dev/null || \
|
|
|
|
|
doas /bin/busybox "$action" 2>/dev/null || \
|
|
|
|
|
sudo -n "/sbin/$action" 2>/dev/null || \
|
|
|
|
|
dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.$method" boolean:false >/dev/null 2>&1 || \
|
|
|
|
|
loginctl "$action" 2>/dev/null || \
|
|
|
|
|
run_polkit_login1 "$method"; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
return 1
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 09:23:54 +03:00
|
|
|
case "$1" in
|
|
|
|
|
reboot)
|
|
|
|
|
sync
|
2026-10-20 21:15:16 +03:00
|
|
|
sxmo_hook_power.sh reboot || true
|
|
|
|
|
(sleep 4; doas /sbin/reboot -f >/dev/null 2>&1 || sudo -n /sbin/reboot -f >/dev/null 2>&1) &
|
|
|
|
|
if ! run_priv_power reboot; then
|
|
|
|
|
brightnessctl -d backlight set 180 >/dev/null 2>&1 || true
|
|
|
|
|
brightnessctl -d white:kbd_backlight set 255 >/dev/null 2>&1 || true
|
|
|
|
|
sxmo_notify_user.sh "Reboot failed: permission denied"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
2026-10-19 09:23:54 +03:00
|
|
|
;;
|
|
|
|
|
poweroff)
|
|
|
|
|
sync
|
2026-10-20 21:15:16 +03:00
|
|
|
sxmo_hook_power.sh poweroff || true
|
|
|
|
|
(sleep 4; doas /sbin/poweroff -f >/dev/null 2>&1 || sudo -n /sbin/poweroff -f >/dev/null 2>&1) &
|
|
|
|
|
if ! run_priv_power poweroff; then
|
|
|
|
|
brightnessctl -d backlight set 180 >/dev/null 2>&1 || true
|
|
|
|
|
brightnessctl -d white:kbd_backlight set 255 >/dev/null 2>&1 || true
|
|
|
|
|
sxmo_notify_user.sh "Poweroff failed: permission denied"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
2026-10-19 09:23:54 +03:00
|
|
|
;;
|
|
|
|
|
logout)
|
|
|
|
|
sxmo_hook_logout.sh || true
|
|
|
|
|
case "$SXMO_WM" in
|
|
|
|
|
"i3") i3-msg exit ;;
|
|
|
|
|
"sway") swaymsg exit ;;
|
|
|
|
|
"river") riverctl exit ;;
|
|
|
|
|
"dwm") pkill dwm ;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
|
|
|
|
togglewm) sxmo_togglewm.sh ;;
|
|
|
|
|
*)
|
|
|
|
|
usage
|
|
|
|
|
exit 1
|
|
|
|
|
;;
|
|
|
|
|
esac
|