docs: rewrite readme; add macOS install script
- Clarify that the sprite is the author's face on Nedry's body - Explicit Wayland (gtklock module) vs X11/macOS (PAM module) comparison table with an explanation of how each integration works - Accurate per-distro PAM paths (standard/Fedora multilib/Debian multiarch) - scripts/install-macos.sh: one-shot installer for macOS — checks Homebrew, installs brew deps, builds from source, copies binaries, and patches /etc/pam.d/screensaverui (or screensaver) after the last auth line Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
a35ca838ce
commit
554bb00a69
Executable
+98
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
# install-macos.sh — build and install ahfail on macOS
|
||||
# Run from the repository root: bash scripts/install-macos.sh
|
||||
set -euo pipefail
|
||||
|
||||
INSTALL_DIR="/usr/local/lib/ahfail"
|
||||
BOLD=$(tput bold 2>/dev/null || true)
|
||||
RESET=$(tput sgr0 2>/dev/null || true)
|
||||
|
||||
step() { echo "${BOLD}==> $*${RESET}"; }
|
||||
die() { echo "ERROR: $*" >&2; exit 1; }
|
||||
|
||||
[[ "$(uname)" == "Darwin" ]] || die "This script is for macOS only."
|
||||
|
||||
# ── 1. Homebrew ───────────────────────────────────────────────────────────────
|
||||
if ! command -v brew &>/dev/null; then
|
||||
die "Homebrew is required. Install it from https://brew.sh then re-run this script."
|
||||
fi
|
||||
|
||||
step "Installing Homebrew dependencies..."
|
||||
brew install --quiet gtk+3 gstreamer gst-plugins-base gst-plugins-good meson ninja
|
||||
|
||||
# ── 2. Rust ───────────────────────────────────────────────────────────────────
|
||||
if ! command -v cargo &>/dev/null; then
|
||||
step "Installing Rust via rustup..."
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path
|
||||
# shellcheck source=/dev/null
|
||||
source "$HOME/.cargo/env"
|
||||
fi
|
||||
|
||||
# ── 3. Build ──────────────────────────────────────────────────────────────────
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
step "Building ahfail..."
|
||||
if [[ -d builddir ]]; then
|
||||
meson setup builddir --wipe
|
||||
else
|
||||
meson setup builddir
|
||||
fi
|
||||
meson compile -C builddir
|
||||
|
||||
# ── 4. Install binaries ───────────────────────────────────────────────────────
|
||||
step "Installing binaries to ${INSTALL_DIR}/ (requires sudo)..."
|
||||
sudo mkdir -p "$INSTALL_DIR"
|
||||
sudo cp builddir/libahfail_pam.so "$INSTALL_DIR/"
|
||||
sudo cp builddir/ahfail-display "$INSTALL_DIR/"
|
||||
sudo chmod 755 "$INSTALL_DIR/libahfail_pam.so" "$INSTALL_DIR/ahfail-display"
|
||||
|
||||
# ── 5. Configure PAM ─────────────────────────────────────────────────────────
|
||||
step "Configuring PAM..."
|
||||
|
||||
# macOS 13+ uses screensaverui; 12 and earlier uses screensaver
|
||||
if [[ -f /etc/pam.d/screensaverui ]]; then
|
||||
PAM_FILE="/etc/pam.d/screensaverui"
|
||||
elif [[ -f /etc/pam.d/screensaver ]]; then
|
||||
PAM_FILE="/etc/pam.d/screensaver"
|
||||
else
|
||||
echo ""
|
||||
echo " Could not find a screensaver PAM file. Add this line manually"
|
||||
echo " to the appropriate file in /etc/pam.d/ (after the auth entries):"
|
||||
echo ""
|
||||
echo " auth optional ${INSTALL_DIR}/libahfail_pam.so"
|
||||
echo ""
|
||||
echo "Done (PAM not configured automatically)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PAM_LINE="auth optional ${INSTALL_DIR}/libahfail_pam.so"
|
||||
|
||||
if grep -qF "$PAM_LINE" "$PAM_FILE"; then
|
||||
echo " PAM already configured in ${PAM_FILE}."
|
||||
else
|
||||
# Insert after the last 'auth' line so we stay in the auth block.
|
||||
sudo python3 - "$PAM_FILE" "$PAM_LINE" <<'PYEOF'
|
||||
import sys
|
||||
|
||||
pam_file, new_line = sys.argv[1], sys.argv[2] + "\n"
|
||||
lines = open(pam_file).readlines()
|
||||
|
||||
if new_line in lines:
|
||||
sys.exit(0)
|
||||
|
||||
# Find the last line that starts with 'auth'
|
||||
last_auth = max(
|
||||
(i for i, l in enumerate(lines) if l.strip().startswith("auth")),
|
||||
default=len(lines) - 1,
|
||||
)
|
||||
lines.insert(last_auth + 1, new_line)
|
||||
open(pam_file, "w").writelines(lines)
|
||||
PYEOF
|
||||
echo " Added to ${PAM_FILE}."
|
||||
fi
|
||||
|
||||
# ── Done ──────────────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo "${BOLD}Done.${RESET} Lock your screen and type the wrong password to test."
|
||||
Reference in New Issue
Block a user