Introduce terminal-based workflows for BackTunnel via TUI scripts and service menus

Add `backtunnel-open-term`, `backtunnel-share-tui`, and `backtunnel-access-tui` scripts for terminal-based interaction. Update Dolphin service menus to enable TUI workflows, with improved terminal detection logic. Enhance installation and uninstallation scripts to handle new files. Update README with terminal workflow details and logging information.
This commit is contained in:
2025-09-19 15:30:41 +02:00
parent f42344ebe8
commit 608a6a371f
9 changed files with 276 additions and 71 deletions

View File

@@ -1,5 +1,4 @@
# BackTunnel convenience Makefile (for first-time users and simple installs)
# BackTunnel convenience Makefile (terminal/TUI service menus)
PREFIX ?= /usr
BINDIR := $(PREFIX)/bin
MANDIR := $(PREFIX)/share/man
@@ -7,6 +6,7 @@ KIO_SM := $(PREFIX)/share/kio/servicemenus
KSVC5 := $(PREFIX)/share/kservices5/ServiceMenus
APPDIR := $(PREFIX)/share/applications
BCOMP := $(PREFIX)/share/bash-completion/completions
SHAREDIR := $(PREFIX)/share/backtunnel
# Config paths for user init
XDG_CONFIG_HOME ?= $(HOME)/.config
@@ -38,7 +38,7 @@ init:
cp "$(BT_CFG_EXAMPLE)" "$(BT_CFG_FILE)"; \
echo "Created $(BT_CFG_FILE) from $(BT_CFG_EXAMPLE)."; \
else \
echo "Example file $(BT_CFG_EXAMPLE)" not found.; exit 1; \
echo "Example file $(BT_CFG_EXAMPLE) not found."; exit 1; \
fi \
fi
@@ -48,25 +48,40 @@ install:
@install -Dm755 scripts/backtunnel-access "$(DESTDIR)$(BINDIR)/backtunnel-access"
@install -Dm755 scripts/backtunnel-share-gui "$(DESTDIR)$(BINDIR)/backtunnel-share-gui"
@install -Dm755 scripts/backtunnel-access-gui "$(DESTDIR)$(BINDIR)/backtunnel-access-gui"
@install -Dm755 scripts/backtunnel-open-term "$(DESTDIR)$(BINDIR)/backtunnel-open-term"
@install -Dm755 scripts/backtunnel-share-tui "$(DESTDIR)$(BINDIR)/backtunnel-share-tui"
@install -Dm755 scripts/backtunnel-access-tui "$(DESTDIR)$(BINDIR)/backtunnel-access-tui"
@install -Dm644 man/backtunnel.1 "$(DESTDIR)$(MANDIR)/man1/backtunnel.1"
@install -Dm644 completions/backtunnel.bash "$(DESTDIR)$(BCOMP)/backtunnel-share"
@install -Dm644 completions/backtunnel.bash "$(DESTDIR)$(BCOMP)/backtunnel-access"
@install -Dm644 servicemenus/backtunnel_share.desktop "$(DESTDIR)$(KIO_SM)/backtunnel_share.desktop"
@install -Dm644 servicemenus/backtunnel_access.desktop "$(DESTDIR)$(KIO_SM)/backtunnel_access.desktop"
# Plasma 5 legacy path (harmless if unused)
@install -Dm644 servicemenus/backtunnel_share.desktop "$(DESTDIR)$(KSVC5)/backtunnel_share.desktop"
@install -Dm644 servicemenus/backtunnel_access.desktop "$(DESTDIR)$(KSVC5)/backtunnel_access.desktop"
# Optional desktop launcher if present
@if [ -f desktop/backtunnel.desktop ]; then \
install -Dm644 desktop/backtunnel.desktop "$(DESTDIR)$(APPDIR)/backtunnel.desktop"; \
fi
# Example profiles (system default + packaged fallback)
@install -Dm644 docs/profiles.ini.example "$(DESTDIR)/etc/backtunnel/profiles.ini"
@install -Dm644 docs/profiles.ini.example "$(DESTDIR)$(SHAREDIR)/profiles.ini"
@$(MAKE) refresh
uninstall:
@rm -f "$(DESTDIR)$(BINDIR)/backtunnel-share" \
"$(DESTDIR)$(BINDIR)/backtunnel-access" \
"$(DESTDIR)$(BINDIR)/backtunnel-share-gui" \
"$(DESTDIR)$(BINDIR)/backtunnel-access-gui"
"$(DESTDIR)$(BINDIR)/backtunnel-access-gui" \
"$(DESTDIR)$(BINDIR)/backtunnel-open-term" \
"$(DESTDIR)$(BINDIR)/backtunnel-share-tui" \
"$(DESTDIR)$(BINDIR)/backtunnel-access-tui"
@rm -f "$(DESTDIR)$(MANDIR)/man1/backtunnel.1"
@rm -f "$(DESTDIR)$(BCOMP)/backtunnel-share" \
"$(DESTDIR)$(BCOMP)/backtunnel-access"
@@ -75,6 +90,10 @@ uninstall:
@rm -f "$(DESTDIR)$(KSVC5)/backtunnel_share.desktop" \
"$(DESTDIR)$(KSVC5)/backtunnel_access.desktop"
@rm -f "$(DESTDIR)$(APPDIR)/backtunnel.desktop" || true
# Do not remove /etc/backtunnel or /usr/share/backtunnel by default
# If you want to purge, run scripts/uninstall.sh with PURGE=1
@$(MAKE) refresh
# --- Cache refreshers (no-op if tools missing) ---
@@ -95,6 +114,9 @@ check:
@bash -n scripts/backtunnel-access
@bash -n scripts/backtunnel-share-gui
@bash -n scripts/backtunnel-access-gui
@bash -n scripts/backtunnel-open-term
@bash -n scripts/backtunnel-share-tui
@bash -n scripts/backtunnel-access-tui
@echo "bash -n OK."
shellcheck:
@@ -103,3 +125,6 @@ shellcheck:
@shellcheck scripts/backtunnel-access
@shellcheck scripts/backtunnel-share-gui
@shellcheck scripts/backtunnel-access-gui
@shellcheck scripts/backtunnel-open-term
@shellcheck scripts/backtunnel-share-tui
@shellcheck scripts/backtunnel-access-tui

View File

@@ -167,6 +167,15 @@ Two context actions for Dolphin are installed:
Both wrappers run inside Konsole (or xterm) so you can see live logs, and they honor profile defaults from `~/.config/backtunnel/profiles.ini` (or `/etc`, `/usr/share`).
### Terminal launch from Dolphin (no dialogs)
If you prefer a terminal workflow, Dolphins service menus can launch BackTunnel in your **preferred terminal**. We ship a small opener `backtunnel-open-term` that picks Konsole, Kitty, Alacritty, GNOME Console, Tilix, Xfce Terminal, or xterm (whichever is available).
- **Share via BackTunnel…** → `backtunnel-open-term backtunnel-share-tui %f`
- **Access via BackTunnel…** → `backtunnel-open-term backtunnel-access-tui %f`
Each run produces a log under `${XDG_STATE_HOME:-$HOME/.local/state}/backtunnel/servicemenu.*.log` (latest 10 kept). Set `BACKTUNNEL_DEBUG=1` for extra shell tracing in the launched scripts.
### 🖱️ Dolphin (GUI) Flow — Share with Invite
1. **Right-click a folder → “Share via BackTunnel…”**

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
SEL_DIR="${1:-}"
[[ -n "$SEL_DIR" ]] || { echo "Usage: backtunnel-access-tui <selected-dir>"; exit 1; }
# Defaults: mount INTO the selected folder
DEFAULT_MP="$SEL_DIR"
# If selected folder is not empty, propose subdir
if [[ -d "$SEL_DIR" ]] && [[ -n "$(ls -A -- "$SEL_DIR" 2>/dev/null || true)" ]]; then
DEFAULT_MP="$SEL_DIR/backtunnel"
fi
read -r -p "Remote (user@host or user:host) [user@vps.example.com]: " REMOTE
REMOTE="${REMOTE:-user@vps.example.com}"
read -r -p "Tunnel port on remote [2222]: " PORT
PORT="${PORT:-2222}"
read -r -p "Mount point [${DEFAULT_MP}]: " MP
MP="${MP:-$DEFAULT_MP}"
# Expand leading ~ if user typed it
if [[ "$MP" == "~"* ]]; then
MP="${MP/#\~/$HOME}"
fi
# Ensure mountpoint exists & is writable
mkdir -p -- "$MP"
if [[ ! -w "$MP" ]]; then
echo "Mount point '$MP' is not writable"; exit 1
fi
echo
echo "Running: backtunnel-access '<remote-folder>' from '$REMOTE' -p '$PORT' -m '$MP'"
echo "Note: you'll be prompted on the remote for the exact folder (as per your workflow)."
exec backtunnel-access "$MP" from "$REMOTE" -p "$PORT" -m "$MP"

View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Open a command in the user's available terminal emulator, with logging.
# Usage: backtunnel-open-term <cmd> [args...]
set -euo pipefail
LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/backtunnel"
[[ -d "$LOG_DIR" ]] || mkdir -p "$LOG_DIR"
LOG_FILE="${LOG_DIR}/servicemenu.$(date +%Y%m%d-%H%M%S).log"
# Simple rotation: keep the last 10 files
ls -1t "$LOG_DIR"/servicemenu.*.log 2>/dev/null | awk 'NR>10{print}' | xargs -r rm -f
cmd=( "$@" )
{
echo "=== BackTunnel servicemenu ==="
echo "Time: $(date -Is)"
echo "PWD: $(pwd)"
echo "User: $(id -un) (uid=$(id -u))"
echo "Cmd: ${cmd[*]}"
echo "Env: BACKTUNNEL_DEBUG=${BACKTUNNEL_DEBUG:-} SHELL=${SHELL:-} DISPLAY=${DISPLAY:-}"
echo
# Prefer Konsole on KDE sessions; otherwise probe common terminals
detect_term() {
if [[ -n "${KDE_FULL_SESSION:-}" ]] && command -v konsole >/dev/null 2>&1; then
echo "konsole"; return
fi
for t in kitty alacritty kgx gnome-terminal tilix xfce4-terminal konsole xterm; do
if command -v "$t" >/dev/null 2>&1; then echo "$t"; return; fi
done
echo "" # none
}
term="$(detect_term)"
echo "Chosen terminal: ${term:-<none>}"; echo
# Run command in terminal (use hold/noclose if supported)
case "$term" in
konsole) exec konsole --noclose -e "${cmd[@]}" ;;
kitty) exec kitty -e "${cmd[@]}" ;;
alacritty) exec alacritty -e "${cmd[@]}" ;;
gnome-terminal) exec gnome-terminal -- bash -lc "exec \"${cmd[0]}\" ${cmd[@]:1}" ;;
kgx) exec kgx -- bash -lc "exec \"${cmd[0]}\" ${cmd[@]:1}" ;; # GNOME Console
tilix) exec tilix -e "${cmd[@]}" ;;
xfce4-terminal) exec xfce4-terminal -e "${cmd[@]}" ;;
xterm) exec xterm -hold -e "${cmd[@]}" ;;
*)
echo "No terminal emulator found. Running in background (nohup)."
nohup "${cmd[@]}" >/dev/null 2>&1 &
echo "Started in background (pid=$!)."
echo "Log: $LOG_FILE"
exit 0
;;
esac
} | tee -a "$LOG_FILE"

View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
FOLDER="${1:-}"
[[ -n "$FOLDER" ]] || { echo "Usage: backtunnel-share-tui <folder>"; exit 1; }
read -r -p "Remote (user@host or user:host) [user@vps.example.com]: " REMOTE
REMOTE="${REMOTE:-user@vps.example.com}"
read -r -p "Share duration (30m/2h/1d) [2h]: " DUR
DUR="${DUR:-2h}"
read -r -p "Tunnel port on remote [2222]: " TPORT
TPORT="${TPORT:-2222}"
read -r -p "Local sshd port to expose [22]: " LPORT
LPORT="${LPORT:-22}"
read -r -p "Print invite line for chat? (y/N): " yn
INV=; [[ "${yn,,}" == "y" ]] && INV="-i"
QR=
if [[ -n "$INV" ]]; then
read -r -p "Show QR code for the invite? (y/N): " yq
[[ "${yq,,}" == "y" ]] && QR="--qr"
fi
read -r -p "Invite: suggested mount point [/mnt/remote-rssh]: " MP
MP="${MP:-/mnt/remote-rssh}"
echo
echo "Running: backtunnel-share '$FOLDER' with '$REMOTE' for '$DUR' -p '$TPORT' -l '$LPORT' ${INV:+-i} ${QR:+--qr} --invite-mount '$MP'"
exec backtunnel-share "$FOLDER" with "$REMOTE" for "$DUR" -p "$TPORT" -l "$LPORT" ${INV:+-i} ${QR:+--qr} --invite-mount "$MP"

View File

@@ -1,44 +1,70 @@
#!/usr/bin/env bash
# Copyright (c) 2025. LUXIM d.o.o., Slovenia - Matjaž Mozetič.
# BackTunnel installer (terminal/TUI service menus)
set -euo pipefail
PREFIX=${PREFIX:-/usr}
BINDIR="$PREFIX/bin"
MANDIR="$PREFIX/share/man/man1"
KIO_SM="$PREFIX/share/kio/servicemenus"
KSVC5="$PREFIX/share/kservices5/ServiceMenus"
APPDIR="$PREFIX/share/applications"
BCOMP="$PREFIX/share/bash-completion/completions"
DESTDIR=${DESTDIR:-}
echo "Removing BackTunnel from $PREFIX ..."
BINDIR="$DESTDIR$PREFIX/bin"
MANDIR="$DESTDIR$PREFIX/share/man/man1"
KIO_SM="$DESTDIR$PREFIX/share/kio/servicemenus"
KSVC5="$DESTDIR$PREFIX/share/kservices5/ServiceMenus"
APPDIR="$DESTDIR$PREFIX/share/applications"
BCOMP="$DESTDIR$PREFIX/share/bash-completion/completions"
SHARE_DIR="$DESTDIR$PREFIX/share/backtunnel"
rm -f "$BINDIR/backtunnel-share" \
"$BINDIR/backtunnel-access" \
"$BINDIR/backtunnel-share-gui" \
"$BINDIR/backtunnel-access-gui"
say() { printf '[BackTunnel] %s\n' "$*"; }
rm -f "$MANDIR/backtunnel.1"
say "Installing to PREFIX=${PREFIX} DESTDIR=${DESTDIR}"
rm -f "$BCOMP/backtunnel-share" \
"$BCOMP/backtunnel-access"
# --- Binaries (CLI) ---
install -Dm755 "scripts/backtunnel-share" "$BINDIR/backtunnel-share"
install -Dm755 "scripts/backtunnel-access" "$BINDIR/backtunnel-access"
rm -f "$KIO_SM/backtunnel_share.desktop" \
"$KIO_SM/backtunnel_access.desktop" \
"$KSVC5/backtunnel_share.desktop" \
"$KSVC5/backtunnel_access.desktop"
# --- GUI wrappers (optional) ---
install -Dm755 "scripts/backtunnel-share-gui" "$BINDIR/backtunnel-share-gui"
install -Dm755 "scripts/backtunnel-access-gui" "$BINDIR/backtunnel-access-gui"
rm -f "$APPDIR/backtunnel.desktop" || true
# --- Terminal opener + TUIs (used by service menus) ---
install -Dm755 "scripts/backtunnel-open-term" "$BINDIR/backtunnel-open-term"
install -Dm755 "scripts/backtunnel-share-tui" "$BINDIR/backtunnel-share-tui"
install -Dm755 "scripts/backtunnel-access-tui" "$BINDIR/backtunnel-access-tui"
# Do not remove /usr/share/backtunnel/profiles.ini (packaged example) — leave it.
# --- Man page ---
install -Dm644 "man/backtunnel.1" "$MANDIR/backtunnel.1"
# Refresh caches
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database -q || true
# --- Bash completions (install for both command names) ---
install -Dm644 "completions/backtunnel.bash" "$BCOMP/backtunnel-share"
install -Dm644 "completions/backtunnel.bash" "$BCOMP/backtunnel-access"
# --- Dolphin service menus (Plasma 6) ---
install -Dm644 "servicemenus/backtunnel_share.desktop" "$KIO_SM/backtunnel_share.desktop"
install -Dm644 "servicemenus/backtunnel_access.desktop" "$KIO_SM/backtunnel_access.desktop"
# --- Plasma 5 legacy path (harmless if unused) ---
install -Dm644 "servicemenus/backtunnel_share.desktop" "$KSVC5/backtunnel_share.desktop"
install -Dm644 "servicemenus/backtunnel_access.desktop" "$KSVC5/backtunnel_access.desktop"
# --- Optional desktop launcher ---
if [[ -f "desktop/backtunnel.desktop" ]]; then
install -Dm644 "desktop/backtunnel.desktop" "$APPDIR/backtunnel.desktop"
fi
# --- Example profiles (system default + packaged fallback) ---
install -Dm644 "docs/profiles.ini.example" "$DESTDIR/etc/backtunnel/profiles.ini"
install -Dm644 "docs/profiles.ini.example" "$SHARE_DIR/profiles.ini"
# --- Refresh desktop/KDE cache (best-effort) ---
if command -v update-desktop-database >/dev/null 2>&1; then
say "Refreshing desktop database..."
update-desktop-database -q || true
fi
if command -v kbuildsycoca6 >/dev/null 2>&1; then
say "Rebuilding KDE sycoca (Plasma 6)..."
kbuildsycoca6 --noincremental >/dev/null 2>&1 || true
elif command -v kbuildsycoca5 >/dev/null 2>&1; then
say "Rebuilding KDE sycoca (Plasma 5)..."
kbuildsycoca5 --noincremental >/dev/null 2>&1 || true
fi
echo "BackTunnel removed."
say "Install complete."

View File

@@ -1,50 +1,69 @@
#!/usr/bin/env bash
# Copyright (c) 2025. LUXIM d.o.o., Slovenia - Matjaž Mozetič.
# BackTunnel uninstaller (with optional PURGE=1 to remove shared defaults)
set -euo pipefail
CONFIRM=1
while [[ $# -gt 0 ]]; do
case "$1" in
-y|--yes) CONFIRM=0; shift;;
-h|--help) echo "Usage: $(basename "$0") [--yes]"; exit 0;;
*) echo "Unknown option: $1" >&2; exit 1;;
esac
done
PREFIX=${PREFIX:-/usr}
DESTDIR=${DESTDIR:-}
PURGE=${PURGE:-0} # set PURGE=1 to remove /usr/share/backtunnel and /etc/backtunnel
if [[ $CONFIRM -ne 0 ]]; then
read -r -p "Remove BackTunnel binaries, manpage, completions, service menus, and desktop file? [y/N] " ans
case "${ans:-N}" in y|Y|yes|YES) ;; *) echo "Aborted."; exit 1;; esac
BINDIR="$DESTDIR$PREFIX/bin"
MANDIR="$DESTDIR$PREFIX/share/man/man1"
KIO_SM="$DESTDIR$PREFIX/share/kio/servicemenus"
KSVC5="$DESTDIR$PREFIX/share/kservices5/ServiceMenus"
APPDIR="$DESTDIR$PREFIX/share/applications"
BCOMP="$DESTDIR$PREFIX/share/bash-completion/completions"
SHARE_DIR="$DESTDIR$PREFIX/share/backtunnel"
ETC_DIR="$DESTDIR/etc/backtunnel"
say() { printf '[BackTunnel] %s\n' "$*"; }
say "Uninstalling from PREFIX=${PREFIX} DESTDIR=${DESTDIR} (PURGE=${PURGE})"
# --- Remove binaries ---
rm -f "$BINDIR/backtunnel-share" \
"$BINDIR/backtunnel-access" \
"$BINDIR/backtunnel-share-gui" \
"$BINDIR/backtunnel-access-gui" \
"$BINDIR/backtunnel-open-term" \
"$BINDIR/backtunnel-share-tui" \
"$BINDIR/backtunnel-access-tui"
# --- Man page ---
rm -f "$MANDIR/backtunnel.1"
# --- Bash completions ---
rm -f "$BCOMP/backtunnel-share" \
"$BCOMP/backtunnel-access"
# --- Dolphin service menus (Plasma 6 + legacy) ---
rm -f "$KIO_SM/backtunnel_share.desktop" \
"$KIO_SM/backtunnel_access.desktop" \
"$KSVC5/backtunnel_share.desktop" \
"$KSVC5/backtunnel_access.desktop"
# --- Optional desktop launcher ---
rm -f "$APPDIR/backtunnel.desktop" || true
# --- Shared defaults (only if PURGE=1) ---
if [[ "$PURGE" = "1" ]]; then
say "Purging shared defaults under $SHARE_DIR and $ETC_DIR"
rm -f "$SHARE_DIR/profiles.ini" 2>/dev/null || true
rm -f "$ETC_DIR/profiles.ini" 2>/dev/null || true
# Remove directories if empty (and prune empty parents)
rmdir -p --ignore-fail-on-non-empty "$SHARE_DIR" 2>/dev/null || true
rmdir -p --ignore-fail-on-non-empty "$ETC_DIR" 2>/dev/null || true
else
# Optionally clean up empty share dir if package manager removed files already
rmdir -p --ignore-fail-on-non-empty "$SHARE_DIR" 2>/dev/null || true
say "Keeping shared defaults: $SHARE_DIR/ and $ETC_DIR/ (set PURGE=1 to remove)"
fi
echo "🧹 Removing binaries ..."
sudo rm -f /usr/local/bin/backtunnel-share /usr/local/bin/backtunnel-access || true
echo "🧹 Removing man page ..."
sudo rm -f /usr/local/share/man/man1/backtunnel.1 || true
sudo mandb || true
echo "🧹 Removing bash completion ..."
sudo rm -f /usr/share/bash-completion/completions/backtunnel-share || true
sudo rm -f /usr/share/bash-completion/completions/backtunnel-access || true
sudo rm -f /etc/bash_completion.d/backtunnel || true
echo "🧹 Removing Dolphin service menus ..."
sudo rm -f /usr/share/kio/servicemenus/backtunnel_share.desktop || true
sudo rm -f /usr/share/kio/servicemenus/backtunnel_access.desktop || true
sudo rm -f /usr/share/kservices5/ServiceMenus/backtunnel_share.desktop || true
sudo rm -f /usr/share/kservices5/ServiceMenus/backtunnel_access.desktop || true
echo "🧹 Removing desktop launcher ..."
sudo rm -f /usr/share/applications/backtunnel.desktop || true
# Refresh desktop DB and KDE service cache (best-effort)
command -v update-desktop-database >/dev/null 2>&1 && sudo update-desktop-database -q || true
# --- Refresh desktop/KDE cache (best-effort) ---
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database -q || true
if command -v kbuildsycoca6 >/dev/null 2>&1; then
kbuildsycoca6 --noincremental >/dev/null 2>&1 || true
elif command -v kbuildsycoca5 >/dev/null 2>&1; then
kbuildsycoca5 --noincremental >/dev/null 2>&1 || true
fi
echo "Uninstall complete."
say "Uninstall complete."

View File

@@ -6,8 +6,9 @@ Icon=folder-remote
Actions=BackTunnelAccess;
X-KDE-StartupNotify=false
X-KDE-Priority=TopLevel
TryExec=backtunnel-open-term
[Desktop Action BackTunnelAccess]
Name=Access via BackTunnel…
Name=Access via BackTunnel (mount here)
Icon=folder-remote
Exec=backtunnel-access-gui %f
Exec=backtunnel-open-term backtunnel-access-tui %f

View File

@@ -6,8 +6,9 @@ Icon=network-server
Actions=BackTunnelShare;
X-KDE-StartupNotify=false
X-KDE-Priority=TopLevel
TryExec=backtunnel-open-term
[Desktop Action BackTunnelShare]
Name=Share via BackTunnel…
Icon=network-server
Exec=backtunnel-share-gui %f
Exec=backtunnel-open-term backtunnel-share-tui %f