205 lines
4.8 KiB
Bash
Executable file
205 lines
4.8 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
LIB_DIR="$SCRIPT_DIR/lib"
|
|
|
|
for _lib in ui log input steps; do
|
|
_path="$LIB_DIR/${_lib}.sh"
|
|
if [ ! -f "$_path" ]; then
|
|
echo "[ERROR] Missing lib: $_path" >&2
|
|
exit 1
|
|
fi
|
|
source "$_path"
|
|
done
|
|
|
|
FULL=false
|
|
YES=false
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--full|-f) FULL=true ;;
|
|
--yes|-y) YES=true ;;
|
|
--help|-h)
|
|
echo ""
|
|
echo " Usage: $0 [options]"
|
|
echo ""
|
|
echo " No flags — removes wrapper, sudoers, runtime"
|
|
echo " keeps repos, venv, configs and data"
|
|
echo ""
|
|
echo " --full — everything above + repos, venv, configs and data"
|
|
echo " --yes — skip confirmation prompt"
|
|
echo ""
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "Unknown flag: $arg"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
clear
|
|
print_header "HYDRA-VEIL UNINSTALLER" "v2.0.0"
|
|
printf " ${DIM}%s${RESET}\n" "$(date '+%Y-%m-%d %H:%M:%S') — $(uname -n)"
|
|
print_divider
|
|
|
|
if $FULL; then
|
|
label_warn "Mode --full: everything will be removed (repos, venv, configs, data)"
|
|
else
|
|
label_info "Normal mode: repos, venv, configs and data will be kept"
|
|
label_info "Use --full to remove everything"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
if ! $YES; then
|
|
if ! ask_confirm "Continue with uninstall?"; then
|
|
log_warn "Uninstall cancelled."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
print_divider
|
|
|
|
_rm() {
|
|
local target="$1"
|
|
if [ -e "$target" ]; then
|
|
rm -rf "$target"
|
|
label_ok "Removed: $target"
|
|
else
|
|
label_info "Not found: $target"
|
|
fi
|
|
}
|
|
|
|
print_section "1. sing-box process"
|
|
|
|
_stop_singbox() {
|
|
local pid=""
|
|
|
|
if [ -f "$SINGBOX_PID_FILE" ]; then
|
|
pid=$(cat "$SINGBOX_PID_FILE" 2>/dev/null || echo "")
|
|
fi
|
|
|
|
if [[ -z "$pid" || ! "$pid" =~ ^[0-9]+$ ]]; then
|
|
pid=$(pgrep -x sing-box 2>/dev/null | head -1 || echo "")
|
|
fi
|
|
|
|
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null; then
|
|
log_info "Stopping sing-box PID $pid..."
|
|
kill -TERM "$pid" 2>/dev/null || true
|
|
local elapsed=0
|
|
while kill -0 "$pid" 2>/dev/null && (( elapsed < 16 )); do
|
|
sleep 0.5
|
|
(( elapsed++ )) || true
|
|
done
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill -KILL "$pid" 2>/dev/null || true
|
|
sleep 0.3
|
|
label_ok "sing-box killed (SIGKILL)"
|
|
else
|
|
label_ok "sing-box stopped (SIGTERM)"
|
|
fi
|
|
else
|
|
label_info "sing-box is not running"
|
|
fi
|
|
}
|
|
|
|
if [ -x "$SINGBOX_WRAPPER" ]; then
|
|
sudo "$SINGBOX_WRAPPER" "" stop 2>/dev/null && label_ok "Stopped via wrapper" || _stop_singbox
|
|
else
|
|
_stop_singbox
|
|
fi
|
|
|
|
if ip link show tun0 &>/dev/null 2>&1; then
|
|
sudo ip link delete tun0 2>/dev/null && label_ok "tun0 removed" || label_warn "Could not remove tun0"
|
|
else
|
|
label_info "tun0 not found"
|
|
fi
|
|
|
|
print_divider
|
|
print_section "2. Wrapper"
|
|
|
|
if [ -f "$SINGBOX_WRAPPER" ]; then
|
|
sudo rm -f "$SINGBOX_WRAPPER"
|
|
label_ok "Removed: $SINGBOX_WRAPPER"
|
|
else
|
|
label_info "Not found: $SINGBOX_WRAPPER"
|
|
fi
|
|
|
|
print_divider
|
|
print_section "3. Sudoers"
|
|
|
|
if [ -f "$SUDOERS_PATH" ]; then
|
|
sudo rm -f "$SUDOERS_PATH"
|
|
label_ok "Removed: $SUDOERS_PATH"
|
|
else
|
|
label_info "Not found: $SUDOERS_PATH"
|
|
fi
|
|
|
|
_orphans=$(sudo grep -rl "hydraveil" /etc/sudoers.d/ 2>/dev/null || true)
|
|
if [ -n "$_orphans" ]; then
|
|
label_warn "Orphaned sudoers entries found:"
|
|
echo "$_orphans" | while read -r f; do
|
|
sudo rm -f "$f" && label_ok " Removed: $f"
|
|
done
|
|
else
|
|
label_info "No orphaned entries in sudoers.d"
|
|
fi
|
|
|
|
print_divider
|
|
print_section "4. Runtime"
|
|
|
|
_rm "$SINGBOX_PID_FILE"
|
|
_rm "$SINGBOX_LOG_FILE"
|
|
_rm "$HV_DATA_DIR/runtime"
|
|
|
|
print_divider
|
|
|
|
if $FULL; then
|
|
print_section "5. Data"
|
|
_rm "$HV_DATA_DIR"
|
|
|
|
print_section "6. Configs"
|
|
_rm "$HV_CONFIG_DIR"
|
|
_rm "$HV_CACHE_DIR"
|
|
_rm "$HV_STATE_DIR"
|
|
|
|
print_section "7. Venv"
|
|
_rm "$HV_VENV"
|
|
|
|
print_section "8. Repos"
|
|
for _dir in "$HV_CORE" "$HV_CLI" "$HV_GUI" "$HV_ESSENTIALS"; do
|
|
_rm "$_dir"
|
|
done
|
|
|
|
if [ -d "$HV_BASE" ] && [ -z "$(ls -A "$HV_BASE" 2>/dev/null)" ]; then
|
|
rmdir "$HV_BASE"
|
|
label_ok "Empty base directory removed: $HV_BASE"
|
|
fi
|
|
|
|
if [ -L "$SINGBOX_BIN" ]; then
|
|
sudo rm -f "$SINGBOX_BIN"
|
|
label_ok "sing-box symlink removed: $SINGBOX_BIN"
|
|
else
|
|
label_info "sing-box is not a symlink — kept: $SINGBOX_BIN"
|
|
fi
|
|
|
|
print_divider
|
|
fi
|
|
|
|
echo ""
|
|
label_ok "Uninstall complete"
|
|
|
|
if $FULL; then
|
|
label_ok "Mode --full: everything removed"
|
|
else
|
|
echo ""
|
|
label_info "Kept: repos, venv, configs, data"
|
|
label_info "To remove everything: $0 --full"
|
|
fi
|
|
|
|
echo ""
|
|
print_divider
|
|
echo ""
|