blob: 4f5ed9c1ec32a0780d0afd0c2f8d991d52f96f6c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#!/bin/sh
# airplane-mode — toggle a low-power "airplane" state for a laptop.
#
# Engage: record the current state of each lever, then apply low-power values:
# - wifi off (nmcli; bluetooth is left alone, on purpose — earbuds)
# - CPU energy-performance preference -> power (intel_pstate, via sysfs)
# - display brightness dimmed
# - stop network-only services (VPNs, sync, discovery, inbound SSH)
# Disengage: read the recorded state and restore exactly what was there. A
# lever already in its low-power position before engaging (e.g. wifi already
# off, a service already stopped) is left untouched on disengage.
#
# State lives at $XDG_RUNTIME_DIR/airplane-state as key=value lines. The
# waybar-airplane indicator reads `mode` from it.
#
# Env knobs (defaults are the real system; tests override them):
# AIRPLANE_EPP_GLOB glob of EPP sysfs files
# AIRPLANE_BRIGHTNESS_LOW brightnessctl target while engaged
# AIRPLANE_SYSTEM_SERVICES system units to stop (sudo)
# AIRPLANE_USER_SERVICES --user units to stop
STATE_FILE="${XDG_RUNTIME_DIR:-/tmp}/airplane-state"
SUDO="${AIRPLANE_SUDO:-sudo}"
EPP_GLOB="${AIRPLANE_EPP_GLOB:-/sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference}"
BRIGHTNESS_LOW="${AIRPLANE_BRIGHTNESS_LOW:-35%}"
SYSTEM_SERVICES="${AIRPLANE_SYSTEM_SERVICES:-tailscaled.service proton.VPN.service avahi-daemon.service cups.service wsdd.service geoclue.service sshd.service fail2ban.service}"
USER_SERVICES="${AIRPLANE_USER_SERVICES:-syncthing.service}"
read_key() { sed -n "s/^$1=//p" "$STATE_FILE" 2>/dev/null | head -n1; }
set_epp() {
# Write $1 to every EPP file. Needs root; glob expands inside the subshell.
$SUDO sh -c "for f in $EPP_GLOB; do [ -e \"\$f\" ] && echo $1 > \"\$f\"; done" 2>/dev/null
}
first_epp() {
for f in $EPP_GLOB; do
[ -e "$f" ] && { cat "$f"; return; }
done
}
engage() {
# --- record current state ---
wifi_was=$(nmcli radio wifi 2>/dev/null)
epp_was=$(first_epp)
bright_was=$(brightnessctl get 2>/dev/null)
stopped_system=""
for s in $SYSTEM_SERVICES; do
if systemctl is-active --quiet "$s" 2>/dev/null; then
$SUDO systemctl stop "$s" 2>/dev/null && stopped_system="$stopped_system $s"
fi
done
stopped_user=""
for s in $USER_SERVICES; do
if systemctl --user is-active --quiet "$s" 2>/dev/null; then
systemctl --user stop "$s" 2>/dev/null && stopped_user="$stopped_user $s"
fi
done
# --- apply low-power settings ---
nmcli radio wifi off 2>/dev/null
set_epp power
brightnessctl set "$BRIGHTNESS_LOW" >/dev/null 2>&1
# --- persist what we recorded ---
{
echo "mode=on"
echo "wifi=$wifi_was"
echo "epp=$epp_was"
echo "brightness=$bright_was"
echo "stopped_system=$stopped_system"
echo "stopped_user=$stopped_user"
} > "$STATE_FILE"
notify info "Airplane mode" "ON — wifi off, low power" 2>/dev/null
}
disengage() {
wifi_was=$(read_key wifi)
epp_was=$(read_key epp)
bright_was=$(read_key brightness)
stopped_system=$(read_key stopped_system)
stopped_user=$(read_key stopped_user)
# Only restore a lever that was NOT already in its low-power state.
[ "$wifi_was" = "enabled" ] && nmcli radio wifi on 2>/dev/null
[ -n "$epp_was" ] && set_epp "$epp_was"
[ -n "$bright_was" ] && brightnessctl set "$bright_was" >/dev/null 2>&1
for s in $stopped_system; do
$SUDO systemctl start "$s" 2>/dev/null
done
for s in $stopped_user; do
systemctl --user start "$s" 2>/dev/null
done
echo "mode=off" > "$STATE_FILE"
notify info "Airplane mode" "OFF — settings restored" 2>/dev/null
}
case "$(read_key mode)" in
on) disengage ;;
*) engage ;;
esac
# Refresh the waybar indicator immediately (custom/airplane listens on signal 10).
pkill -RTMIN+10 waybar 2>/dev/null
exit 0
|