479 lines
21 KiB
Bash
479 lines
21 KiB
Bash
#!/bin/sh
|
||
# shellcheck shell=dash
|
||
# ==============================================================================
|
||
# Tachyon Uninstaller & Cleanup Script
|
||
# Полное чистое удаление Tachyon с сохранением резервной копии конфигурации.
|
||
# ==============================================================================
|
||
|
||
set -u
|
||
|
||
UNINSTALLER_VERSION="1.3.0"
|
||
|
||
# ─── TUI helpers & Color detection ───────────────────────────────────────────
|
||
ESC="$(printf '\033')"
|
||
_tui_colors=0
|
||
if [ -t 1 ] 2>/dev/null; then
|
||
case "${TERM:-dumb}" in
|
||
dumb) _tui_colors=0 ;;
|
||
*) _tui_colors=1 ;;
|
||
esac
|
||
fi
|
||
|
||
if [ "$_tui_colors" -eq 1 ]; then
|
||
_c_reset="${ESC}[0m"
|
||
_c_bold="${ESC}[1m"
|
||
_c_dim="${ESC}[2m"
|
||
_c_red="${ESC}[31;1m"
|
||
_c_green="${ESC}[32;1m"
|
||
_c_yellow="${ESC}[33;1m"
|
||
_c_blue="${ESC}[34;1m"
|
||
_c_cyan="${ESC}[36;1m"
|
||
_c_magenta="${ESC}[35;1m"
|
||
else
|
||
_c_reset=''
|
||
_c_bold=''
|
||
_c_dim=''
|
||
_c_red=''
|
||
_c_green=''
|
||
_c_yellow=''
|
||
_c_blue=''
|
||
_c_cyan=''
|
||
_c_magenta=''
|
||
fi
|
||
|
||
_tui_width() {
|
||
if [ -t 1 ] 2>/dev/null && command -v stty >/dev/null 2>&1; then
|
||
_w="$(stty size 2>/dev/null | awk '{print $2}')"
|
||
[ -n "$_w" ] && [ "$_w" -gt 0 ] 2>/dev/null && printf '%s' "$_w" && return 0
|
||
fi
|
||
printf '70'
|
||
}
|
||
|
||
_tui_hline() {
|
||
_w="$(_tui_width)"
|
||
_char="${1:--}"
|
||
_i=0
|
||
while [ "$_i" -lt "$_w" ]; do
|
||
printf '%s' "$_char"
|
||
_i=$((_i + 1))
|
||
done
|
||
}
|
||
|
||
tui_banner() {
|
||
printf '\n'
|
||
printf ' %s%s⚡ Tachyon Clean Uninstaller%s v%s\n' "$_c_cyan" "$_c_bold" "$_c_reset" "$UNINSTALLER_VERSION"
|
||
printf ' %sПолное удаление пакетов, сетевых правил и восстановление DNS%s\n' "$_c_dim" "$_c_reset"
|
||
printf ' %s%s%s\n\n' "$_c_dim" "$(_tui_hline '─')" "$_c_reset"
|
||
}
|
||
|
||
tui_step() {
|
||
_step_no="$1"
|
||
_step_total="$2"
|
||
_step_text="$3"
|
||
printf ' %s%s[ %s/%s ]%s %s%s%s\n' \
|
||
"$_c_blue" "$_c_bold" \
|
||
"$_step_no" "$_step_total" \
|
||
"$_c_reset" \
|
||
"$_c_bold" "$_step_text" "$_c_reset"
|
||
}
|
||
|
||
tui_ok() {
|
||
printf ' %s%s✓%s %s\n' "$_c_green" "$_c_bold" "$_c_reset" "$1"
|
||
}
|
||
|
||
tui_warn() {
|
||
printf ' %s%s⚠%s %s\n' "$_c_yellow" "$_c_bold" "$_c_reset" "$1"
|
||
}
|
||
|
||
tui_info() {
|
||
printf ' %s%sℹ%s %s\n' "$_c_cyan" "$_c_dim" "$_c_reset" "$1"
|
||
}
|
||
|
||
# ─── Options parsing ─────────────────────────────────────────────────────────
|
||
OPT_PURGE=0
|
||
OPT_YES=0
|
||
OPT_KEEP_BINARIES=0
|
||
|
||
for _arg in "$@"; do
|
||
case "$_arg" in
|
||
--purge|-p)
|
||
OPT_PURGE=1
|
||
;;
|
||
--yes|-y)
|
||
OPT_YES=1
|
||
;;
|
||
--keep-binaries)
|
||
OPT_KEEP_BINARIES=1
|
||
;;
|
||
--help|-h)
|
||
printf 'Использование: %s [ОПЦИИ]\n' "$0"
|
||
printf 'Опции:\n'
|
||
printf ' -y, --yes Выполнить удаление без подтверждения\n'
|
||
printf ' -p, --purge Полное удаление вместе с резервными копиями конфига\n'
|
||
printf ' --keep-binaries Не удалять бинарники sing-box / zapret / byedpi\n'
|
||
printf ' -h, --help Показать эту справку\n\n'
|
||
exit 0
|
||
;;
|
||
*)
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# ─── Root check ──────────────────────────────────────────────────────────────
|
||
if [ "$(id -u 2>/dev/null || echo 1)" -ne 0 ]; then
|
||
printf '%sОшибка: скрипт удаления должен запускаться с правами root!%s\n' "$_c_red" "$_c_reset" >&2
|
||
exit 1
|
||
fi
|
||
|
||
tui_banner
|
||
|
||
# ─── Confirmation prompt ─────────────────────────────────────────────────────
|
||
if [ "$OPT_YES" -eq 0 ] && [ -t 0 ] 2>/dev/null; then
|
||
printf ' Вы действительно хотите удалить %sTachyon%s с этого роутера?\n' "$_c_bold" "$_c_reset"
|
||
if [ "$OPT_PURGE" -eq 1 ]; then
|
||
printf ' %sВнимание: указан флаг --purge. Все конфигурации и бэкапы будут удалены!%s\n' "$_c_red" "$_c_reset"
|
||
else
|
||
printf ' Рабочая конфигурация будет сохранена в резервную копию.\n'
|
||
fi
|
||
printf ' Продолжить? [y/N]: '
|
||
read -r _answer
|
||
case "$_answer" in
|
||
y|Y|yes|Yes|YES|да|Да|ДА)
|
||
;;
|
||
*)
|
||
printf '\n %sУдаление отменено пользователем.%s\n\n' "$_c_yellow" "$_c_reset"
|
||
exit 0
|
||
;;
|
||
esac
|
||
printf '\n'
|
||
fi
|
||
|
||
TOTAL_STEPS=6
|
||
CURRENT_STEP=1
|
||
|
||
# ─── STEP 1: Backup Configuration ────────────────────────────────────────────
|
||
tui_step "$CURRENT_STEP" "$TOTAL_STEPS" "Создание резервной копии конфигурации..."
|
||
BACKUP_PATH=""
|
||
if [ "$OPT_PURGE" -eq 0 ]; then
|
||
TIMESTAMP="$(date +%Y%m%d_%H%M%S 2>/dev/null || date +%s)"
|
||
if [ -f "/etc/config/tachyon" ]; then
|
||
BACKUP_PATH="/etc/config/tachyon.backup-${TIMESTAMP}"
|
||
cp -af "/etc/config/tachyon" "$BACKUP_PATH" 2>/dev/null || true
|
||
cp -af "/etc/config/tachyon" "/etc/config/tachyon.bak" 2>/dev/null || true
|
||
chmod 600 "$BACKUP_PATH" "/etc/config/tachyon.bak" 2>/dev/null || true
|
||
tui_ok "Конфигурация успешно сохранена в: ${BACKUP_PATH}"
|
||
else
|
||
tui_info "Конфигурационный файл /etc/config/tachyon не найден, бэкап пропущен."
|
||
fi
|
||
else
|
||
tui_warn "Режим --purge: резервное копирование конфигурации отключено."
|
||
fi
|
||
|
||
CURRENT_STEP=$((CURRENT_STEP + 1))
|
||
|
||
# ─── STEP 2: Stop Services & Daemons ─────────────────────────────────────────
|
||
tui_step "$CURRENT_STEP" "$TOTAL_STEPS" "Остановка служб и фоновых процессов..."
|
||
|
||
# Remove stale locks so stop doesn't block on orphaned states
|
||
rm -f /var/run/tachyon/starting /var/run/tachyon/reloading /var/run/tachyon*.lock 2>/dev/null || true
|
||
|
||
if [ -f "/etc/init.d/tachyon" ]; then
|
||
if command -v timeout >/dev/null 2>&1; then
|
||
timeout 8 /etc/init.d/tachyon stop >/dev/null 2>&1 || true
|
||
else
|
||
/etc/init.d/tachyon stop >/dev/null 2>&1 || true
|
||
fi
|
||
/etc/init.d/tachyon disable >/dev/null 2>&1 || true
|
||
tui_ok "Служба /etc/init.d/tachyon остановлена и отключена"
|
||
fi
|
||
|
||
# Stop and remove managed sing-box service if created by Tachyon
|
||
if [ -f "/etc/init.d/sing-box" ]; then
|
||
if grep -q "Tachyon managed sing-box" "/etc/init.d/sing-box" 2>/dev/null; then
|
||
if command -v timeout >/dev/null 2>&1; then
|
||
timeout 8 /etc/init.d/sing-box stop >/dev/null 2>&1 || true
|
||
else
|
||
/etc/init.d/sing-box stop >/dev/null 2>&1 || true
|
||
fi
|
||
/etc/init.d/sing-box disable >/dev/null 2>&1 || true
|
||
rm -f /etc/init.d/sing-box /etc/rc.d/*sing-box* 2>/dev/null || true
|
||
tui_ok "Управляемый сервис sing-box остановлен и удален"
|
||
fi
|
||
fi
|
||
|
||
# Terminate running DPI and proxy processes if any
|
||
killall -9 sing-box >/dev/null 2>&1 || true
|
||
killall -9 nfqws >/dev/null 2>&1 || true
|
||
killall -9 nfqws2 >/dev/null 2>&1 || true
|
||
killall -9 ciadpi >/dev/null 2>&1 || true
|
||
killall -9 tachyon >/dev/null 2>&1 || true
|
||
|
||
# Terminate running background Tachyon daemons (watchdog, telegram, failover, etc.)
|
||
_self_pid="$$"
|
||
ps 2>/dev/null | grep -E 'dns_failover|watchdog|telegram' | grep -v grep | awk '{print $1}' | while read -r _pid; do
|
||
if [ -n "$_pid" ] && [ "$_pid" != "$_self_pid" ]; then
|
||
kill -9 "$_pid" 2>/dev/null || true
|
||
fi
|
||
done
|
||
|
||
tui_ok "Фоновые процессы sing-box, zapret, byedpi и сервисы Tachyon завершены"
|
||
|
||
CURRENT_STEP=$((CURRENT_STEP + 1))
|
||
|
||
# ─── STEP 3: Clean up Network, nftables & Policy Routing ─────────────────────
|
||
tui_step "$CURRENT_STEP" "$TOTAL_STEPS" "Очистка сетевых таблиц nftables и политик маршрутизации..."
|
||
|
||
# Remove nftables tables & drop-in file
|
||
if command -v nft >/dev/null 2>&1; then
|
||
nft delete table inet TachyonTable >/dev/null 2>&1 || true
|
||
nft delete table inet tachyon >/dev/null 2>&1 || true
|
||
nft delete table ip tachyon >/dev/null 2>&1 || true
|
||
nft delete table ip6 tachyon >/dev/null 2>&1 || true
|
||
rm -f /usr/share/nftables.d/chain-pre/input/10-tachyon.nft 2>/dev/null || true
|
||
# Restart firewall to purge in-memory dynamic rules from inet fw4
|
||
if [ -x "/etc/init.d/firewall" ]; then
|
||
/etc/init.d/firewall restart >/dev/null 2>&1 || true
|
||
fi
|
||
tui_ok "Таблицы nftables (TachyonTable) удалены, фаервол сброшен"
|
||
fi
|
||
|
||
# Remove IP policy routing rules & flush routing tables
|
||
if command -v ip >/dev/null 2>&1; then
|
||
# IPv4 and IPv6 rules used by Tachyon (0x04000000 / table tachyon / priority 105)
|
||
ip -4 rule del fwmark 0x04000000/0x04000000 table tachyon priority 105 >/dev/null 2>&1 || true
|
||
ip -6 rule del fwmark 0x04000000/0x04000000 table tachyon priority 105 >/dev/null 2>&1 || true
|
||
ip -4 rule del fwmark 0x10000000/0x10000000 lookup 100 >/dev/null 2>&1 || true
|
||
ip -4 rule del fwmark 0x1/0x1 lookup 100 >/dev/null 2>&1 || true
|
||
ip -4 rule del fwmark 0x2/0x2 lookup 100 >/dev/null 2>&1 || true
|
||
ip route flush table tachyon >/dev/null 2>&1 || true
|
||
ip route flush table 105 >/dev/null 2>&1 || true
|
||
ip route flush table 100 >/dev/null 2>&1 || true
|
||
|
||
# Clean /etc/iproute2/rt_tables entry
|
||
if [ -f "/etc/iproute2/rt_tables" ]; then
|
||
sed -i '/105[[:space:]]\+tachyon/d' /etc/iproute2/rt_tables 2>/dev/null || true
|
||
fi
|
||
|
||
# Clean network namespaces and diagnostic veth pairs
|
||
ip netns del fkpsc >/dev/null 2>&1 || true
|
||
ip link del fkpsc0 >/dev/null 2>&1 || true
|
||
rm -rf /etc/netns/fkpsc 2>/dev/null || true
|
||
|
||
tui_ok "Политики маршрутизации (table tachyon/105/100, fwmark) полностью сброшены"
|
||
fi
|
||
|
||
CURRENT_STEP=$((CURRENT_STEP + 1))
|
||
|
||
# ─── STEP 4: Restore DNS & dnsmasq ───────────────────────────────────────────
|
||
tui_step "$CURRENT_STEP" "$TOTAL_STEPS" "Восстановление конфигурации DNS и dnsmasq..."
|
||
|
||
rm -f /etc/dnsmasq.d/tachyon*.conf 2>/dev/null || true
|
||
rm -f /tmp/dnsmasq.d/tachyon*.conf 2>/dev/null || true
|
||
rm -rf /tmp/tachyon 2>/dev/null || true
|
||
|
||
# Restore /etc/config/dhcp via UCI
|
||
if command -v uci >/dev/null 2>&1 && [ -f "/etc/config/dhcp" ]; then
|
||
# Remove sing-box DNS 127.0.0.42
|
||
uci -q del_list dhcp.@dnsmasq[0].server="127.0.0.42" 2>/dev/null || true
|
||
|
||
# Restore original servers from tachyon_server backup
|
||
_orig_servers="$(uci -q get dhcp.@dnsmasq[0].tachyon_server 2>/dev/null || true)"
|
||
if [ -n "$_orig_servers" ]; then
|
||
uci -q delete dhcp.@dnsmasq[0].server 2>/dev/null || true
|
||
for _srv in $_orig_servers; do
|
||
[ "$_srv" != "127.0.0.42" ] && uci -q add_list dhcp.@dnsmasq[0].server="$_srv" 2>/dev/null || true
|
||
done
|
||
uci -q delete dhcp.@dnsmasq[0].tachyon_server 2>/dev/null || true
|
||
fi
|
||
|
||
# Restore backed-up options
|
||
for _opt in noresolv cachesize rebind_protection localuse addn_hosts notinterface; do
|
||
_val="$(uci -q get "dhcp.@dnsmasq[0].tachyon_${_opt}" 2>/dev/null || true)"
|
||
if [ -n "$_val" ]; then
|
||
uci -q set "dhcp.@dnsmasq[0].${_opt}=${_val}" 2>/dev/null || true
|
||
uci -q delete "dhcp.@dnsmasq[0].tachyon_${_opt}" 2>/dev/null || true
|
||
fi
|
||
done
|
||
|
||
# Failsafe: if noresolv remains 1, reset to 0 so router queries ISP/upstream resolvers
|
||
if [ "$(uci -q get dhcp.@dnsmasq[0].noresolv 2>/dev/null)" = "1" ]; then
|
||
uci -q set dhcp.@dnsmasq[0].noresolv="0" 2>/dev/null || true
|
||
fi
|
||
# Failsafe: if cachesize remains 0, restore standard default 150
|
||
if [ "$(uci -q get dhcp.@dnsmasq[0].cachesize 2>/dev/null)" = "0" ]; then
|
||
uci -q set dhcp.@dnsmasq[0].cachesize="150" 2>/dev/null || true
|
||
fi
|
||
|
||
uci -q delete dhcp.tachyon 2>/dev/null || true
|
||
uci -q commit dhcp 2>/dev/null || true
|
||
tui_ok "Параметры DHCP и DNS dnsmasq возвращены в исходное состояние"
|
||
fi
|
||
|
||
# Restart dnsmasq to apply clean DNS configuration
|
||
if [ -f "/etc/init.d/dnsmasq" ]; then
|
||
/etc/init.d/dnsmasq restart >/dev/null 2>&1 || true
|
||
tui_ok "Служба dnsmasq перезапущена в штатном режиме"
|
||
fi
|
||
|
||
CURRENT_STEP=$((CURRENT_STEP + 1))
|
||
|
||
# ─── STEP 5: Clean Crontabs & Remove Packages ────────────────────────────────
|
||
tui_step "$CURRENT_STEP" "$TOTAL_STEPS" "Очистка crontab и удаление установленных пакетов..."
|
||
|
||
# Clean root crontab from Tachyon jobs
|
||
if command -v crontab >/dev/null 2>&1; then
|
||
_crontmp="$(mktemp /tmp/cron.XXXXXX 2>/dev/null || echo '/tmp/cron.tachyon.tmp')"
|
||
crontab -l 2>/dev/null | grep -v -E 'tachyon|parental_quota_tick' > "$_crontmp" || true
|
||
crontab "$_crontmp" 2>/dev/null || true
|
||
rm -f "$_crontmp" 2>/dev/null || true
|
||
tui_ok "Задачи планировщика crontab очищены"
|
||
fi
|
||
|
||
if command -v apk >/dev/null 2>&1 && [ -d "/lib/apk/db" ]; then
|
||
for _pkg in luci-i18n-tachyon-ru luci-app-tachyon tachyon; do
|
||
if [ -f /etc/apk/world ]; then
|
||
sed -i -E "/^${_pkg}([><= ].*)?$/d" /etc/apk/world 2>/dev/null || true
|
||
fi
|
||
if apk info -e "$_pkg" >/dev/null 2>&1; then
|
||
apk del "$_pkg" >/dev/null 2>&1 || true
|
||
fi
|
||
done
|
||
if [ "$OPT_KEEP_BINARIES" -eq 0 ]; then
|
||
for _pkg in sing-box-extended sing-box-tiny; do
|
||
if [ -f /etc/apk/world ]; then
|
||
sed -i -E "/^${_pkg}([><= ].*)?$/d" /etc/apk/world 2>/dev/null || true
|
||
fi
|
||
if apk info -e "$_pkg" >/dev/null 2>&1; then
|
||
apk del "$_pkg" >/dev/null 2>&1 || true
|
||
fi
|
||
done
|
||
if [ ! -f /etc/init.d/sing-box ] || grep -q "Tachyon managed sing-box" /etc/init.d/sing-box 2>/dev/null; then
|
||
if [ -f /etc/apk/world ]; then
|
||
sed -i -E '/^sing-box([><= ].*)?$/d' /etc/apk/world 2>/dev/null || true
|
||
fi
|
||
if apk info -e "sing-box" >/dev/null 2>&1; then
|
||
apk del "sing-box" >/dev/null 2>&1 || true
|
||
fi
|
||
rm -f /usr/bin/sing-box 2>/dev/null || true
|
||
fi
|
||
fi
|
||
tui_ok "Пакеты удалены через apk-tools"
|
||
elif command -v opkg >/dev/null 2>&1; then
|
||
_wait=0
|
||
while [ -f /var/lock/opkg.lock ] || [ -f /var/run/opkg.lock ]; do
|
||
_wait=$((_wait + 1))
|
||
[ "$_wait" -ge 10 ] && break
|
||
sleep 1
|
||
done
|
||
for _pkg in luci-i18n-tachyon-ru luci-app-tachyon tachyon; do
|
||
if opkg list-installed "$_pkg" 2>/dev/null | grep -q "^$_pkg "; then
|
||
opkg remove --force-depends --force-remove "$_pkg" >/dev/null 2>&1 || true
|
||
fi
|
||
done
|
||
if [ "$OPT_KEEP_BINARIES" -eq 0 ]; then
|
||
for _pkg in sing-box-extended sing-box-tiny; do
|
||
if opkg list-installed "$_pkg" 2>/dev/null | grep -q "^$_pkg "; then
|
||
opkg remove --force-depends --force-remove "$_pkg" >/dev/null 2>&1 || true
|
||
fi
|
||
done
|
||
if [ ! -f /etc/init.d/sing-box ] || grep -q "Tachyon managed sing-box" /etc/init.d/sing-box 2>/dev/null; then
|
||
if opkg list-installed "sing-box" 2>/dev/null | grep -q "^sing-box "; then
|
||
opkg remove --force-depends --force-remove "sing-box" >/dev/null 2>&1 || true
|
||
fi
|
||
rm -f /usr/bin/sing-box 2>/dev/null || true
|
||
fi
|
||
fi
|
||
tui_ok "Пакеты удалены через opkg"
|
||
fi
|
||
|
||
CURRENT_STEP=$((CURRENT_STEP + 1))
|
||
|
||
# ─── STEP 6: Remove Leftover Files & LuCI Cache ──────────────────────────────
|
||
tui_step "$CURRENT_STEP" "$TOTAL_STEPS" "Очистка оставшихся файлов, хуков и кэша LuCI..."
|
||
|
||
rm -rf /usr/lib/tachyon 2>/dev/null || true
|
||
rm -rf /usr/share/tachyon 2>/dev/null || true
|
||
rm -rf /www/luci-static/resources/view/tachyon 2>/dev/null || true
|
||
rm -f /usr/share/luci/menu.d/luci-app-tachyon.json 2>/dev/null || true
|
||
rm -f /usr/share/rpcd/acl.d/luci-app-tachyon.json 2>/dev/null || true
|
||
rm -f /etc/uci-defaults/50_luci-tachyon 2>/dev/null || true
|
||
rm -f /etc/tachyon_commit 2>/dev/null || true
|
||
rm -f /usr/bin/tachyon 2>/dev/null || true
|
||
rm -f /etc/init.d/tachyon 2>/dev/null || true
|
||
rm -f /etc/hotplug.d/iface/99-tachyon-wan-monitor 2>/dev/null || true
|
||
rm -f /www/cgi-bin/tachyon-agent 2>/dev/null || true
|
||
rm -f /usr/lib/cgi-bin/tachyon-agent 2>/dev/null || true
|
||
|
||
# Optional binary removal
|
||
if [ "$OPT_KEEP_BINARIES" -eq 0 ]; then
|
||
# Remove sing-box binary if it was managed by Tachyon
|
||
if [ ! -f "/lib/apk/db/installed" ] && command -v opkg >/dev/null 2>&1; then
|
||
if ! opkg list-installed "sing-box*" 2>/dev/null | grep -q "^sing-box"; then
|
||
rm -f /usr/bin/sing-box 2>/dev/null || true
|
||
fi
|
||
fi
|
||
rm -f /usr/lib/libcronet.so 2>/dev/null || true
|
||
fi
|
||
|
||
# Clean translations
|
||
rm -f /usr/lib/lua/luci/i18n/tachyon.* 2>/dev/null || true
|
||
find /usr/lib/lua/luci/i18n/ -name "tachyon.*" -delete 2>/dev/null || true
|
||
|
||
# Clear runtime and temporary state
|
||
rm -rf /var/run/tachyon* /var/log/tachyon* /tmp/sing-box /tmp/tachyon* /tmp/ai_doctor* /tmp/tg_* /tmp/warp_* 2>/dev/null || true
|
||
|
||
# Clear LuCI index and module caches
|
||
rm -f /var/luci-indexcache* /tmp/luci-indexcache* /tmp/luci-modulecache/* 2>/dev/null || true
|
||
|
||
# Clean ucitrack entry
|
||
if [ -f "/etc/config/ucitrack" ]; then
|
||
uci -q delete ucitrack.@tachyon[0] 2>/dev/null || true
|
||
uci -q commit ucitrack 2>/dev/null || true
|
||
fi
|
||
|
||
# Purge configs and persistent state if requested
|
||
if [ "$OPT_PURGE" -eq 1 ]; then
|
||
rm -f /etc/config/tachyon* 2>/dev/null || true
|
||
rm -rf /etc/tachyon /etc/.tachyon /etc/backup/tachyon_config /etc/sing-box 2>/dev/null || true
|
||
tui_ok "Все конфигурации и скрытые состояния Tachyon удалены (--purge)"
|
||
fi
|
||
|
||
# Restart rpcd and uhttpd to immediately update LuCI menu
|
||
if [ -f "/etc/init.d/rpcd" ]; then
|
||
/etc/init.d/rpcd restart >/dev/null 2>&1 || true
|
||
fi
|
||
if [ -f "/etc/init.d/uhttpd" ]; then
|
||
/etc/init.d/uhttpd restart >/dev/null 2>&1 || true
|
||
fi
|
||
|
||
# Check if parent Forkop / Podkop / NetShift services exist and restore them
|
||
if [ -f "/etc/init.d/forkop" ]; then
|
||
/etc/init.d/forkop enable >/dev/null 2>&1 || true
|
||
/etc/init.d/forkop restart >/dev/null 2>&1 || true
|
||
tui_ok "Обнаружен родительский сервис Forkop — восстановлен и запущен"
|
||
elif [ -f "/etc/init.d/podkop" ]; then
|
||
/etc/init.d/podkop enable >/dev/null 2>&1 || true
|
||
/etc/init.d/podkop restart >/dev/null 2>&1 || true
|
||
tui_ok "Обнаружен родительский сервис Podkop — восстановлен и запущен"
|
||
elif [ -f "/etc/init.d/netshift" ]; then
|
||
/etc/init.d/netshift enable >/dev/null 2>&1 || true
|
||
/etc/init.d/netshift restart >/dev/null 2>&1 || true
|
||
tui_ok "Обнаружен родительский сервис NetShift — восстановлен и запущен"
|
||
fi
|
||
|
||
tui_ok "Кэш LuCI очищен, файлы и остаточные фрагменты полностью удалены"
|
||
|
||
# ─── Final Summary ───────────────────────────────────────────────────────────
|
||
printf '\n'
|
||
printf ' %s%s%s\n' "$_c_dim" "$(_tui_hline '─')" "$_c_reset"
|
||
printf ' %s%s✓ Tachyon успешно и чисто удален с вашего роутера!%s\n' "$_c_green" "$_c_bold" "$_c_reset"
|
||
|
||
if [ "$OPT_PURGE" -eq 0 ] && [ -n "$BACKUP_PATH" ]; then
|
||
printf ' %s📁 Резервная копия конфигурации сохранена:%s %s%s%s\n' "$_c_cyan" "$_c_reset" "$_c_bold" "$BACKUP_PATH" "$_c_reset"
|
||
printf ' %s (а также продублирована в /etc/config/tachyon.bak)%s\n' "$_c_dim" "$_c_reset"
|
||
fi
|
||
|
||
printf ' %s🌐 Сетевой стек и DNS возвращены в штатный режим OpenWrt.%s\n\n' "$_c_dim" "$_c_reset"
|
||
|
||
exit 0
|