pivilion/usr/local/lib/pivilion/common.sh

113 lines
4.9 KiB
Bash

#!/bin/bash
# Shared configuration and small helpers for the Pivilion commands.
PIVILION_CONFIG=""
_pivilion_trim() {
local value=$1
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
printf '%s' "$value"
}
_pivilion_config_value() {
local key=$1 file line name value
for file in /boot/firmware/pivilion.conf /boot/pivilion.conf /etc/pivilion.conf /etc/pivilion.defaults; do
[ -r "$file" ] || continue
while IFS= read -r line || [ -n "$line" ]; do
line=$(_pivilion_trim "$line")
case "$line" in ''|'#'*) continue ;; esac
name=$(_pivilion_trim "${line%%=*}")
[ "$name" = "$key" ] || continue
value=$(_pivilion_trim "${line#*=}")
case "$value" in
\"*\") value=${value#\"}; value=${value%\"} ;;
\'*\') value=${value#\'}; value=${value%\'} ;;
esac
printf '%s' "$value"
return 0
done < "$file"
done
return 1
}
pivilion_load_config() {
local default_user configured ssid_bytes
default_user=${SUDO_USER:-${USER:-}}
[ -n "$default_user" ] && [ "$default_user" != root ] || default_user=$(id -nu 1000 2>/dev/null || true)
configured=$(_pivilion_config_value PIVILION_USER || true)
PIVILION_USER=${configured:-$default_user}
[ -n "$PIVILION_USER" ] || { echo "Cannot determine PIVILION_USER" >&2; return 1; }
getent passwd "$PIVILION_USER" >/dev/null || { echo "Configured user '$PIVILION_USER' does not exist" >&2; return 1; }
PIVILION_GROUP=$(id -gn "$PIVILION_USER")
configured=$(_pivilion_config_value PIVILION_HOME || true)
PIVILION_HOME=${configured:-$(getent passwd "$PIVILION_USER" | cut -d: -f6)}
configured=$(_pivilion_config_value PIVILION_DIR || true)
PIVILION_DIR=${configured:-$PIVILION_HOME/pivilion}
configured=$(_pivilion_config_value PIVILION_WEBROOT || true)
PIVILION_WEBROOT=${configured:-/var/www/html/pivilion}
configured=$(_pivilion_config_value PIVILION_MODE || true)
PIVILION_MODE=${configured:-onion}
configured=$(_pivilion_config_value PIVILION_HOTSPOT_SSID || true)
PIVILION_HOTSPOT_SSID=${configured:-pivilion}
configured=$(_pivilion_config_value PIVILION_WIFI_INTERFACE || true)
PIVILION_WIFI_INTERFACE=${configured:-}
case "$PIVILION_MODE" in onion|hotspot) ;; *) echo "PIVILION_MODE must be onion or hotspot" >&2; return 1 ;; esac
ssid_bytes=$(LC_ALL=C printf '%s' "$PIVILION_HOTSPOT_SSID" | wc -c)
[ "$ssid_bytes" -ge 1 ] && [ "$ssid_bytes" -le 32 ] || {
echo "PIVILION_HOTSPOT_SSID must contain 1-32 bytes" >&2; return 1;
}
case "$PIVILION_HOME$PIVILION_DIR$PIVILION_WEBROOT$PIVILION_WIFI_INTERFACE$PIVILION_HOTSPOT_SSID" in
*$'\n'*|*$'\r'*) echo "Invalid control character in Pivilion configuration" >&2; return 1 ;;
esac
case "$PIVILION_HOME:$PIVILION_DIR:$PIVILION_WEBROOT" in
/*:/*:/*) ;; *) echo "Pivilion paths must be absolute" >&2; return 1 ;;
esac
[[ "$PIVILION_HOME" =~ ^/[A-Za-z0-9._/+:-]+$ && "$PIVILION_DIR" =~ ^/[A-Za-z0-9._/+:-]+$ && "$PIVILION_WEBROOT" =~ ^/[A-Za-z0-9._/+:-]+$ ]] || {
echo "Pivilion paths contain unsupported characters" >&2; return 1;
}
[ -z "$PIVILION_WIFI_INTERFACE" ] || [[ "$PIVILION_WIFI_INTERFACE" =~ ^[A-Za-z0-9._:-]+$ ]] || {
echo "Invalid PIVILION_WIFI_INTERFACE" >&2; return 1;
}
export PIVILION_USER PIVILION_GROUP PIVILION_HOME PIVILION_DIR PIVILION_WEBROOT PIVILION_MODE PIVILION_HOTSPOT_SSID PIVILION_WIFI_INTERFACE
}
pivilion_wifi_interface() {
local iface
if [ -n "${PIVILION_WIFI_INTERFACE:-}" ]; then printf '%s\n' "$PIVILION_WIFI_INTERFACE"; return; fi
if command -v nmcli >/dev/null 2>&1; then
iface=$(nmcli -t -f DEVICE,TYPE device status 2>/dev/null | awk -F: '$2=="wifi" {print $1; exit}')
[ -n "$iface" ] && { printf '%s\n' "$iface"; return; }
fi
if command -v iw >/dev/null 2>&1; then
iface=$(iw dev 2>/dev/null | awk '$1=="Interface" {print $2; exit}')
[ -n "$iface" ] && { printf '%s\n' "$iface"; return; }
fi
iface=$(find /sys/class/net -maxdepth 1 -type l -name 'wl*' -printf '%f\n' 2>/dev/null | head -n1)
[ -n "$iface" ] && printf '%s\n' "$iface"
}
pivilion_uses_networkmanager() {
command -v nmcli >/dev/null 2>&1 && systemctl is-active --quiet NetworkManager
}
pivilion_set_mode() {
local mode=$1
case "$mode" in onion|hotspot) ;; *) return 2 ;; esac
install -d -m 0755 -o "$PIVILION_USER" -g "$PIVILION_GROUP" "$PIVILION_DIR"
printf '%s\n' "$mode" | install -m 0644 -o "$PIVILION_USER" -g "$PIVILION_GROUP" /dev/stdin "$PIVILION_DIR/mode"
}
pivilion_current_mode() {
local mode
mode=$(head -n1 "$PIVILION_DIR/mode" 2>/dev/null || true)
case "$mode" in onion|hotspot) printf '%s\n' "$mode" ;; *) printf '%s\n' "$PIVILION_MODE" ;; esac
}
pivilion_require_root() {
[ "$(id -u)" -eq 0 ] || { echo "This operation must run as root (use sudo)." >&2; return 1; }
}