Add Joplin, old Mac, and Fedora WiFi runbooks; simplify JA3 Whisky scripts and hotspot recovery.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ahauimix
2026-06-19 22:26:33 +03:00
parent 1938b7c743
commit 4bc9629a09
381 changed files with 3442 additions and 773 deletions

View File

@@ -0,0 +1,31 @@
#!/bin/sh
# Полная настройка Joplin для Android-хотспота (Mac = клиент WiFi).
# .local с телефона не работает → alias *.100 + LaunchAgent.
#
# ./joplin-android-hotspot-setup.sh install
set -e
ROOT="$(CDPATH= cd -- "$(dirname "$0")" && pwd)"
echo "=== Joplin: Android-хотспот (Mac клиент) ==="
echo ""
echo "Почему не eternals.local:"
echo " Android, раздающий хотспот, не резолвит .local имён подключённых устройств."
echo " rclone.log — только 127.0.0.1, запросов с телефона нет."
echo ""
"$ROOT/joplin-hotspot-alias-install.sh"
echo ""
echo "Поднимаем alias (sudo)..."
"$ROOT/joplin-hotspot-alias.sh" ensure
echo ""
"$ROOT/joplin-hotspot-alias.sh" status
echo ""
echo "=== На телефоне в Joplin WebDAV ==="
grep '^JOPLIN_PHONE_URL=' "${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}" 2>/dev/null \
| cut -d= -f2- || phone_url=$("$ROOT/joplin-hotspot-alias.sh" status | awk '/URL на телефоне/{getline; print}' | tr -d ' ')
echo " $(grep '^JOPLIN_PHONE_URL=' "$HOME/.config/joplin-webdav/env" 2>/dev/null | cut -d= -f2-)"
echo ""
echo "При смене подсети (10.219→10.74) URL меняется — alias LaunchAgent поднимет *.100,"
echo "новый URL: ./joplin-hotspot-alias.sh status"

View File

@@ -0,0 +1,25 @@
#!/bin/sh
# Одноразово: passwordless sudo только для joplin-hotspot-alias.sh ensure
set -e
SCRIPT="$(CDPATH= cd -- "$(dirname "$0")" && pwd)/joplin-hotspot-alias.sh"
DEST="/etc/sudoers.d/joplin-hotspot-alias"
USER_NAME="$(whoami)"
[ -x "$SCRIPT" ] || chmod +x "$SCRIPT"
TMP="$(mktemp)"
trap 'rm -f "$TMP"' EXIT
cat >"$TMP" <<EOF
# Joplin WebDAV: alias *.100 на en0 после reconnect хотспота (только этот скрипт)
${USER_NAME} ALL=(ALL) NOPASSWD: ${SCRIPT} ensure
EOF
echo "Будет создан $DEST:"
cat "$TMP"
echo ""
sudo cp "$TMP" "$DEST"
sudo chmod 440 "$DEST"
sudo visudo -c -f "$DEST"
echo "OK. LaunchAgent сможет поднимать alias без пароля."

View File

@@ -0,0 +1,45 @@
#!/bin/sh
# LaunchAgent: каждые 60 с проверять alias *.100 (нужен joplin-hotspot-alias-install-sudo.sh).
set -e
ROOT="$(CDPATH= cd -- "$(dirname "$0")" && pwd)"
ALIAS="$ROOT/joplin-hotspot-alias.sh"
PLIST="$HOME/Library/LaunchAgents/com.eternal.joplin-hotspot-alias.plist"
chmod +x "$ROOT"/joplin-hotspot-alias*.sh
mkdir -p "$HOME/Library/LaunchAgents" "$HOME/Library/Logs/joplin-webdav"
cat >"$PLIST" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.eternal.joplin-hotspot-alias</string>
<key>ProgramArguments</key>
<array>
<string>$ALIAS</string>
<string>ensure</string>
</array>
<key>StartInterval</key>
<integer>60</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>$HOME/Library/Logs/joplin-webdav/alias-launchd.out.log</string>
<key>StandardErrorPath</key>
<string>$HOME/Library/Logs/joplin-webdav/alias-launchd.err.log</string>
</dict>
</plist>
EOF
launchctl bootout "gui/$(id -u)/com.eternal.joplin-hotspot-alias" 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" "$PLIST"
launchctl enable "gui/$(id -u)/com.eternal.joplin-hotspot-alias" 2>/dev/null || true
echo "LaunchAgent com.eternal.joplin-hotspot-alias установлен (каждые 60 с)."
echo "Для работы без пароля один раз:"
echo " $ROOT/joplin-hotspot-alias-install-sudo.sh"
echo "Сейчас:"
"$ALIAS" status

View File

@@ -0,0 +1,149 @@
#!/bin/sh
# Стабильный URL для Joplin на телефоне при Android-хотспоте: http://<подсеть>.100:8080
# Alias *.100 на en0 (DHCP primary не трогаем). LaunchAgent поднимает alias после reconnect.
#
# ./joplin-hotspot-alias.sh status
# ./joplin-hotspot-alias.sh ensure
#
# Passwordless: ./joplin-hotspot-alias-install-sudo.sh
set -e
CONFIG="${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}"
WIFI_DEV="${WIFI_DEVICE:-en0}"
PORT="${JOPLIN_WEBDAV_PORT:-8080}"
LOG="$HOME/Library/Logs/joplin-webdav/alias.log"
ipv4_subnet() {
printf '%s\n' "$1" | awk -F. '{print $1"."$2"."$3}'
}
ipv4_last_octet() {
printf '%s\n' "$1" | awk -F. '{print $4}'
}
default_gateway() {
route -n get default 2>/dev/null | awk '/gateway:/{print $2; exit}'
}
load_config() {
if [ -f "$CONFIG" ]; then
# shellcheck disable=SC1090
. "$CONFIG"
fi
PORT="${JOPLIN_WEBDAV_PORT:-$PORT}"
}
joplin_phone_ip() {
load_config
gw="$(default_gateway 2>/dev/null || true)"
[ -n "$gw" ] || return 1
subnet="$(ipv4_subnet "$gw")"
if [ -n "${JOPLIN_STATIC_IP:-}" ]; then
last="$(ipv4_last_octet "$JOPLIN_STATIC_IP")"
else
last=100
fi
printf '%s\n' "${subnet}.${last}"
}
phone_url() {
ip="$(joplin_phone_ip 2>/dev/null || true)"
[ -n "$ip" ] || return 1
printf 'http://%s:%s\n' "$ip" "$PORT"
}
has_ip_on_dev() {
ip="$1"
dev="$2"
ifconfig "$dev" 2>/dev/null | grep -q "inet ${ip} "
}
log_msg() {
mkdir -p "$(dirname "$LOG")"
printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >>"$LOG"
}
run_priv() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
else
sudo "$@"
fi
}
write_phone_url_env() {
url="$(phone_url 2>/dev/null || true)"
[ -n "$url" ] && [ -f "$CONFIG" ] || return 0
if grep -q '^JOPLIN_PHONE_URL=' "$CONFIG" 2>/dev/null; then
sed -i '' "s|^JOPLIN_PHONE_URL=.*|JOPLIN_PHONE_URL=$url|" "$CONFIG" 2>/dev/null \
|| sed -i "s|^JOPLIN_PHONE_URL=.*|JOPLIN_PHONE_URL=$url|" "$CONFIG"
else
printf 'JOPLIN_PHONE_URL=%s\n' "$url" >>"$CONFIG"
fi
}
cmd_status() {
load_config
target="$(joplin_phone_ip 2>/dev/null || true)"
primary="$(ipconfig getifaddr "$WIFI_DEV" 2>/dev/null || true)"
gw="$(default_gateway 2>/dev/null || true)"
url="$(phone_url 2>/dev/null || true)"
echo "mode: Android-хотспот (alias *.100)"
echo "device: $WIFI_DEV"
echo "primary: ${primary:-(none)}"
echo "gateway: ${gw:-(none)}"
echo "joplin IP: ${target:-(no gateway)}"
if [ -n "$target" ] && has_ip_on_dev "$target" "$WIFI_DEV"; then
echo "alias: OK"
elif [ -n "$target" ] && [ "$primary" = "$target" ]; then
echo "alias: OK (primary)"
elif [ -n "$target" ]; then
echo "alias: MISSING — телефон не достучится"
echo " fix: $0 ensure"
fi
if [ -n "$url" ]; then
echo ""
echo "URL на телефоне (работает с Android-хотспота):"
echo " $url"
echo ""
echo "⚠ http://*.local:8080 с телефона НЕ работает (Android не резолвит mDNS клиентов хотспота)"
fi
}
cmd_ensure() {
target="$(joplin_phone_ip 2>/dev/null || true)"
if [ -z "$target" ]; then
log_msg "skip: no gateway"
exit 0
fi
primary="$(ipconfig getifaddr "$WIFI_DEV" 2>/dev/null || true)"
if [ -z "$primary" ]; then
log_msg "skip: no primary IP"
exit 0
fi
if [ "$primary" = "$target" ] || has_ip_on_dev "$target" "$WIFI_DEV"; then
write_phone_url_env
exit 0
fi
log_msg "add alias $target on $WIFI_DEV (primary $primary)"
run_priv ifconfig "$WIFI_DEV" inet "$target" netmask 255.255.255.0 alias
write_phone_url_env
echo "alias OK: $target"
echo "URL на телефоне: $(phone_url)"
}
usage() {
echo "Usage: $(basename "$0") status|ensure" >&2
exit 1
}
case "${1:-ensure}" in
status) cmd_status ;;
ensure) cmd_ensure ;;
-h|--help) usage ;;
*) usage ;;
esac

View File

@@ -0,0 +1,165 @@
#!/bin/sh
# Стабильный URL для Joplin на телефоне: http://<LocalHostName>.local:8080
# Не зависит от подсети хотспота (10.219.x → 10.74.x). Alias *.100 не нужен.
#
# ./joplin-mdns-setup.sh status
# ./joplin-mdns-setup.sh install # записать URL в env (rename опционально)
# ./joplin-mdns-setup.sh verify
set -e
CONFIG="${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}"
PORT="${JOPLIN_WEBDAV_PORT:-8080}"
WIFI_DEV="${WIFI_DEVICE:-en0}"
# Пусто = текущий LocalHostName Mac (у вас часто Eternals → eternals.local)
PREFERRED_HOST="${JOPLIN_MDNS_HOST:-}"
load_config() {
if [ -f "$CONFIG" ]; then
# shellcheck disable=SC1090
. "$CONFIG"
fi
PORT="${JOPLIN_WEBDAV_PORT:-$PORT}"
PREFERRED_HOST="${JOPLIN_MDNS_HOST:-$PREFERRED_HOST}"
}
current_local_hostname() {
scutil --get LocalHostName 2>/dev/null || true
}
mdns_host() {
load_config
if [ -n "$PREFERRED_HOST" ]; then
printf '%s\n' "$PREFERRED_HOST"
else
current_local_hostname
fi
}
mdns_fqdn() {
printf '%s.local\n' "$(mdns_host | tr '[:upper:]' '[:lower:]')"
}
phone_url() {
host="$(mdns_host | tr '[:upper:]' '[:lower:]')"
printf 'http://%s.local:%s\n' "$host" "$PORT"
}
primary_ip() {
ipconfig getifaddr "$WIFI_DEV" 2>/dev/null || true
}
resolve_mdns_ip() {
host="$(mdns_fqdn)"
dscacheutil -q host -a name "$host" 2>/dev/null \
| awk '/ip_address:/ {print $2}' | grep -v '^127\.' | head -1
}
cmd_status() {
load_config
local_name="$(current_local_hostname)"
host="$(mdns_host)"
ip="$(primary_ip)"
resolved="$(resolve_mdns_ip 2>/dev/null || true)"
url="$(phone_url)"
echo "LocalHostName: ${local_name:-?}"
echo "mDNS host: $host$(mdns_fqdn)"
echo "primary $WIFI_DEV: ${ip:-(none)}"
echo "mDNS → IP: ${resolved:-(none)}"
echo ""
echo "mDNS URL (НЕ для Android-хотспота — телефон не резолвит .local клиентов):"
echo " $url"
echo "URL на Mac: http://127.0.0.1:${PORT}"
echo "Телефон-хотспот: ./joplin-hotspot-alias.sh status"
if [ -n "$PREFERRED_HOST" ] && [ "$local_name" != "$PREFERRED_HOST" ]; then
echo ""
echo "В env JOPLIN_MDNS_HOST=$PREFERRED_HOST, LocalHostName=$local_name"
echo " install переименует Mac или уберите JOPLIN_MDNS_HOST из env"
elif [ -n "$ip" ] && [ -n "$resolved" ] && [ "$ip" = "$resolved" ]; then
echo ""
echo "OK: mDNS на Mac резолвится (для телефона используйте alias *.100)"
elif [ -n "$ip" ] && [ -z "$resolved" ]; then
echo ""
echo "⚠ mDNS пока не резолвится — подождите или переподключите WiFi"
elif [ -z "$ip" ]; then
echo ""
echo "⚠ Нет IP на $WIFI_DEV"
fi
}
write_env_mdns() {
load_config
url="$(phone_url)"
host="$(mdns_host)"
if [ ! -f "$CONFIG" ]; then
echo "Нет $CONFIG — сначала joplin-webdav-install.sh" >&2
return 1
fi
if grep -q '^JOPLIN_MDNS_HOST=' "$CONFIG" 2>/dev/null; then
sed -i '' "s|^JOPLIN_MDNS_HOST=.*|JOPLIN_MDNS_HOST=$host|" "$CONFIG" 2>/dev/null \
|| sed -i "s|^JOPLIN_MDNS_HOST=.*|JOPLIN_MDNS_HOST=$host|" "$CONFIG"
else
printf 'JOPLIN_MDNS_HOST=%s\n' "$host" >>"$CONFIG"
fi
if grep -q '^JOPLIN_PHONE_URL=' "$CONFIG" 2>/dev/null; then
sed -i '' "s|^JOPLIN_PHONE_URL=.*|JOPLIN_PHONE_URL=$url|" "$CONFIG" 2>/dev/null \
|| sed -i "s|^JOPLIN_PHONE_URL=.*|JOPLIN_PHONE_URL=$url|" "$CONFIG"
else
printf 'JOPLIN_PHONE_URL=%s\n' "$url" >>"$CONFIG"
fi
}
cmd_install() {
load_config
local_name="$(current_local_hostname)"
target="$(mdns_host)"
if [ -n "$PREFERRED_HOST" ] && [ "$local_name" != "$PREFERRED_HOST" ]; then
echo "Переименование LocalHostName: $local_name$PREFERRED_HOST"
if [ "$(id -u)" -eq 0 ]; then
scutil --set LocalHostName "$PREFERRED_HOST"
else
sudo scutil --set LocalHostName "$PREFERRED_HOST"
fi
else
echo "Используем текущий LocalHostName: $local_name (→ $(mdns_fqdn))"
fi
write_env_mdns
echo ""
echo "На телефоне в Joplin WebDAV (один раз):"
echo " $(phone_url)"
echo ""
sleep 2
cmd_verify || true
}
cmd_verify() {
ip="$(primary_ip)"
resolved="$(resolve_mdns_ip 2>/dev/null || true)"
if [ -z "$ip" ]; then
echo "verify: нет IP на $WIFI_DEV" >&2
exit 1
fi
if [ "$ip" = "$resolved" ]; then
echo "verify OK: $(mdns_fqdn)$ip"
exit 0
fi
echo "verify: mDNS=${resolved:-none} ip=$ip (часто OK через 30с после connect)" >&2
exit 1
}
usage() {
echo "Usage: $(basename "$0") status|install|verify" >&2
exit 1
}
case "${1:-status}" in
status) cmd_status ;;
install) cmd_install ;;
verify) cmd_verify ;;
-h|--help) usage ;;
*) usage ;;
esac

View File

@@ -0,0 +1,90 @@
#!/bin/sh
# Установка: конфиг, launchd (автозапуск), первый старт WebDAV.
set -e
ROOT="$(CDPATH= cd -- "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/joplin-webdav"
CONFIG="$CONFIG_DIR/env"
LAUNCH_AGENT="$HOME/Library/LaunchAgents/com.eternal.joplin-webdav.plist"
SERVE="$ROOT/joplin-webdav-serve.sh"
mkdir -p "$CONFIG_DIR" "$HOME/JoplinSync" "$HOME/Library/Logs/joplin-webdav"
if [ ! -f "$CONFIG" ]; then
PASS=$(openssl rand -base64 18 | tr -d '/+=' | head -c 24)
cat > "$CONFIG" <<EOF
# Локальный WebDAV для Joplin. Только LAN. Не коммитить.
JOPLIN_WEBDAV_USER=joplin
JOPLIN_WEBDAV_PASS=$PASS
JOPLIN_WEBDAV_PORT=8080
JOPLIN_WEBDAV_ROOT=$HOME/JoplinSync
# Опционально (legacy alias *.100 — не нужен при mDNS):
# JOPLIN_STATIC_IP=10.219.227.100
# JOPLIN_MDNS_HOST=joplin-mac
# JOPLIN_PHONE_URL=http://joplin-mac.local:8080
EOF
chmod 600 "$CONFIG"
echo "Создан $CONFIG"
else
echo "Конфиг уже есть: $CONFIG"
fi
chmod +x "$ROOT"/joplin-webdav-*.sh
if ! command -v rclone >/dev/null 2>&1; then
echo "Устанавливаю rclone..."
brew install rclone
fi
mkdir -p "$HOME/Library/LaunchAgents"
cat > "$LAUNCH_AGENT" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.eternal.joplin-webdav</string>
<key>ProgramArguments</key>
<array>
<string>$SERVE</string>
<string>--foreground</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>$HOME/Library/Logs/joplin-webdav/launchd.out.log</string>
<key>StandardErrorPath</key>
<string>$HOME/Library/Logs/joplin-webdav/launchd.err.log</string>
</dict>
</plist>
EOF
launchctl bootout "gui/$(id -u)/com.eternal.joplin-webdav" 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" "$LAUNCH_AGENT"
launchctl enable "gui/$(id -u)/com.eternal.joplin-webdav" 2>/dev/null || true
launchctl enable "gui/$(id -u)/com.eternal.joplin-webdav" 2>/dev/null || true
chmod +x "$ROOT"/joplin-mdns-setup.sh 2>/dev/null || true
if [ -x "$ROOT/joplin-mdns-setup.sh" ]; then
echo ""
echo "=== mDNS (стабильный URL на телефоне) ==="
if [ "$(scutil --get LocalHostName 2>/dev/null)" = "joplin-mac" ]; then
"$ROOT/joplin-mdns-setup.sh" status || true
else
echo "LocalHostName ещё не joplin-mac. Один раз:"
echo " $ROOT/joplin-mdns-setup.sh install"
fi
fi
sleep 2
"$ROOT/joplin-webdav-status.sh"
echo ""
echo "Пароль для Joplin:"
grep JOPLIN_WEBDAV_PASS "$CONFIG" | cut -d= -f2-
echo ""
echo "На телефоне (один раз, навсегда): http://joplin-mac.local:8080"
echo "Установка имени: $ROOT/joplin-mdns-setup.sh install"

View File

@@ -0,0 +1,7 @@
#!/bin/sh
# Перечитать ~/.config/joplin-webdav/env и перезапустить WebDAV (после смены пароля).
set -e
uid=$(id -u)
launchctl kickstart -k "gui/${uid}/com.eternal.joplin-webdav"
sleep 2
"$(dirname "$0")/joplin-webdav-status.sh"

View File

@@ -0,0 +1,72 @@
#!/bin/sh
# Локальный WebDAV для синхронизации Joplin (Mac ↔ телефон по LAN).
# Данные: ~/JoplinSync. Учётка: ~/.config/joplin-webdav/env
#
# ./joplin-webdav-serve.sh # фон
# ./joplin-webdav-serve.sh --foreground # передний план (для launchd)
set -e
CONFIG="${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}"
LOG_DIR="$HOME/Library/Logs/joplin-webdav"
PID_FILE="$HOME/.config/joplin-webdav/rclone.pid"
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
mkdir -p "$LOG_DIR" "$(dirname "$PID_FILE")"
if [ ! -f "$CONFIG" ]; then
echo "Нет $CONFIG — запустите: $SCRIPT_DIR/joplin-webdav-install.sh" >&2
exit 1
fi
# shellcheck disable=SC1090
. "$CONFIG"
: "${JOPLIN_WEBDAV_USER:?}"
: "${JOPLIN_WEBDAV_PASS:?}"
: "${JOPLIN_WEBDAV_PORT:=8080}"
: "${JOPLIN_WEBDAV_ROOT:=$HOME/JoplinSync}"
mkdir -p "$JOPLIN_WEBDAV_ROOT"
RCLONE="$(command -v rclone || echo /opt/homebrew/bin/rclone)"
if [ ! -x "$RCLONE" ]; then
echo "rclone не найден. Установите: brew install rclone" >&2
exit 1
fi
run_rclone() {
exec "$RCLONE" serve webdav "$JOPLIN_WEBDAV_ROOT" \
--addr "0.0.0.0:${JOPLIN_WEBDAV_PORT}" \
--user "$JOPLIN_WEBDAV_USER" \
--pass "$JOPLIN_WEBDAV_PASS" \
--vfs-cache-mode minimal \
--log-file "$LOG_DIR/rclone.log" \
--log-level INFO
}
case "${1:-}" in
--foreground|-f)
run_rclone
;;
*)
if [ -f "$PID_FILE" ]; then
old_pid=$(cat "$PID_FILE")
if kill -0 "$old_pid" 2>/dev/null; then
echo "Уже запущен (PID $old_pid), порт ${JOPLIN_WEBDAV_PORT}"
exit 0
fi
rm -f "$PID_FILE"
fi
nohup "$0" --foreground >>"$LOG_DIR/stdout.log" 2>&1 &
echo $! >"$PID_FILE"
sleep 1
if kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
echo "WebDAV запущен (PID $(cat "$PID_FILE")), порт ${JOPLIN_WEBDAV_PORT}"
else
echo "Не удалось запустить. См. $LOG_DIR/stdout.log" >&2
rm -f "$PID_FILE"
exit 1
fi
;;
esac

View File

@@ -0,0 +1,73 @@
#!/bin/sh
CONFIG="${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}"
PID_FILE="$HOME/.config/joplin-webdav/rclone.pid"
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
echo "=== WebDAV Joplin ==="
if [ -f "$CONFIG" ]; then
# shellcheck disable=SC1090
. "$CONFIG"
echo "Пользователь: ${JOPLIN_WEBDAV_USER:-?}"
echo "Порт: ${JOPLIN_WEBDAV_PORT:-8080}"
echo "Папка: ${JOPLIN_WEBDAV_ROOT:-$HOME/JoplinSync}"
else
echo "Конфиг не найден: $CONFIG"
fi
echo ""
echo "=== Процесс ==="
if pgrep -f "rclone serve webdav" >/dev/null 2>&1; then
pgrep -lf "rclone serve webdav" 2>/dev/null || true
else
echo "Не запущен → ./docs/apps/joplin/scripts/joplin-webdav-serve.sh"
fi
port="${JOPLIN_WEBDAV_PORT:-8080}"
echo ""
echo "=== URL для телефона (Android-хотспот) ==="
if [ -x "$SCRIPT_DIR/joplin-hotspot-alias.sh" ]; then
"$SCRIPT_DIR/joplin-hotspot-alias.sh" status
else
echo "(нет joplin-hotspot-alias.sh)"
fi
echo ""
echo "=== mDNS (.local) — с телефона НЕ работает ==="
if [ -x "$SCRIPT_DIR/joplin-mdns-setup.sh" ]; then
host="$(scutil --get LocalHostName 2>/dev/null | tr '[:upper:]' '[:lower:]' || echo '?')"
echo "http://${host}.local:${port} — только Mac/Windows; Android-хотспот не резолвит"
fi
echo ""
echo "=== IP Mac (DHCP, справочно) ==="
ip=$(ipconfig getifaddr en0 2>/dev/null || true)
[ -n "$ip" ] && echo "primary en0: $ip" || echo "нет IP"
echo ""
echo "=== Порт :8080 ==="
lsof -nP -iTCP:"$port" -sTCP:LISTEN 2>/dev/null || echo "не слушает"
echo ""
echo "=== URL в Joplin (Mac) ==="
settings="$HOME/.config/joplin-desktop/settings.json"
if [ -f "$settings" ]; then
grep -o '"sync\.6\.path": *"[^"]*"' "$settings" 2>/dev/null | sed 's/.*"\(http[^"]*\)".*/\1/' \
| while read -r u; do echo "settings.json: $u"; done
fi
echo ""
echo "=== rclone (запросы с телефона?) ==="
log="$HOME/Library/Logs/joplin-webdav/rclone.log"
if [ -f "$log" ]; then
phone_lines=$(grep -E 'from 10\.|from 192\.168\.' "$log" 2>/dev/null | tail -3)
if [ -n "$phone_lines" ]; then
echo "$phone_lines"
else
echo "нет запросов с LAN (только 127.0.0.1?) — телефон не достучался"
fi
fi
echo ""
echo "=== Учётка ==="
[ -f "$CONFIG" ] && echo "Пароль: $CONFIG → JOPLIN_WEBDAV_PASS"

View File

@@ -0,0 +1,18 @@
#!/bin/sh
PID_FILE="$HOME/.config/joplin-webdav/rclone.pid"
if [ ! -f "$PID_FILE" ]; then
echo "WebDAV не запущен (нет $PID_FILE)"
exit 0
fi
pid=$(cat "$PID_FILE")
if kill -0 "$pid" 2>/dev/null; then
kill "$pid" 2>/dev/null || true
sleep 1
kill -9 "$pid" 2>/dev/null || true
echo "Остановлен (PID $pid)"
else
echo "Процесс $pid уже не работает"
fi
rm -f "$PID_FILE"