#!/bin/bash # rc.book-reader: start/stop the local server for book-reader. # Copyright (C) 2026 Danilo M. # SPDX-License-Identifier: GPL-2.0-only # # Config (shell syntax): ${XDG_CONFIG_HOME:-~/.config}/book-reader.conf # LIBRARY=/path/to/library # required; one folder per series, every folder with images is a book # PORT=8642 # keep it fixed: reading progress is stored per origin # BIND=127.0.0.1 # READER=/path/to/book-reader/reader.html # needed when this script is copied out of the repo # # Boot (Slackware): copy to /etc/rc.d, set RUNAS below, call "start" from # rc.local and "stop" from rc.local_shutdown. Run as root, the script # re-executes itself as RUNAS: the web server never runs as root. RUNAS= # user to run as when started by root if [ "$(id -u)" = 0 ]; then if [ -z "$RUNAS" ] || [ "$RUNAS" = root ]; then echo "set RUNAS in $0 to a non-root user" >&2; exit 1; fi exec su - "$RUNAS" -s /bin/bash -c "$(printf '%q %q' "$(readlink -f "$0")" "$1")" fi LIBRARY= PORT=8642 BIND=127.0.0.1 READER=$(dirname "$(readlink -f "$0")")/reader.html CONF=${BOOK_READER_CONF:-${XDG_CONFIG_HOME:-$HOME/.config}/book-reader.conf} [ -r "$CONF" ] && . "$CONF" # fixed path: boot (no XDG_RUNTIME_DIR) and desktop sessions must share the pidfile RUN=/tmp/book-reader-$UID PIDFILE=$RUN/pid URL="http://$BIND:$PORT/reader.html" running() { [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; } start() { if running; then echo "book-reader already running: $URL"; return 0; fi if [ ! -d "$LIBRARY" ]; then echo "LIBRARY not set or missing (edit $CONF)" >&2; return 1; fi if [ ! -r "$READER" ]; then echo "reader.html not found at $READER (set READER in $CONF)" >&2; return 1; fi # Served root holds only symlinks: the viewer and the library, so neither dir gets touched. mkdir -p -m 700 "$RUN" "$RUN/root" find "$RUN/root" -mindepth 1 -maxdepth 1 -type l -delete ln -s "$(readlink -f "$READER")" "$RUN/root/reader.html" ln -s "$(readlink -f "$LIBRARY")" "$RUN/root/library" setsid python3 -m http.server -b "$BIND" -d "$RUN/root" "$PORT" >"$RUN/log" 2>&1 & echo $! >"$PIDFILE" sleep 0.5 if ! running; then echo "book-reader failed to start:" >&2; tail -n 5 "$RUN/log" >&2; rm -f "$PIDFILE"; return 1; fi echo "book-reader started: $URL" } stop() { if running; then kill "$(cat "$PIDFILE")"; echo "book-reader stopped"; else echo "book-reader not running"; fi rm -f "$PIDFILE" } case "$1" in start) start ;; stop) stop ;; restart) stop; start ;; status) if running; then echo "book-reader running: $URL"; else echo "book-reader stopped"; exit 3; fi ;; *) echo "usage: $0 start|stop|restart|status" >&2; exit 1 ;; esac