#!/usr/bin/env bash set -euo pipefail log(){ printf '[%s] %s\n' "$(date +'%F %T')" "$*"; } need_root() { if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then echo "Esegui come root (usa sudo)." >&2 exit 1 fi } detect_os() { local id="unknown" like="" if [[ -r /etc/os-release ]]; then # shellcheck disable=SC1091 . /etc/os-release id="${ID:-unknown}" like="${ID_LIKE:-}" fi echo "$id" "$like" } is_arch_like() { local id="$1" like="$2" [[ "$id" == "arch" || "$id" == "manjaro" || "$id" == "endeavouros" ]] && return 0 [[ "$like" == *"arch"* ]] && return 0 return 1 } is_fedora_like() { local id="$1" like="$2" [[ "$id" == "fedora" ]] && return 0 [[ "$like" == *"fedora"* || "$like" == *"rhel"* ]] && return 0 return 1 } is_suse_like() { local id="$1" like="$2" [[ "$id" == opensuse* || "$id" == "suse" || "$id" == "sles" ]] && return 0 [[ "$like" == *"suse"* ]] && return 0 return 1 } have_systemd() { command -v systemctl >/dev/null 2>&1 } # Robust: works for installed units, generated units, aliases unit_exists() { local u="$1" systemctl cat "$u" >/dev/null 2>&1 } unit_active() { local u="$1" systemctl is-active --quiet "$u" 2>/dev/null } disable_stop_if_present() { local u="$1" if unit_exists "$u" || systemctl list-units --type=service --all 2>/dev/null | awk '{print $1}' | grep -qx "$u"; then log "Stop+disable (se presente): $u" systemctl disable --now "$u" >/dev/null 2>&1 || true fi } daemon_reload() { systemctl daemon-reload >/dev/null 2>&1 || true } # ---- BRIDGE IMPLEMENTATIONS ---- # Fedora-like: wrapper unit che comanda clamd@scan write_bridge_wrapper_fedora() { local bridge="/etc/systemd/system/clamav-daemon.service" local target="clamd@scan.service" unit_exists "$target" || { echo "Fedora-like: manca $target" >&2; exit 1; } log "Creo bridge wrapper: clamav-daemon.service -> $target (wrapper oneshot)" cat > "$bridge" <<'EOF' [Unit] Description=ClamAV daemon bridge (wrapper to clamd@scan) Wants=clamd@scan.service After=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/systemctl start clamd@scan.service ExecStop=/usr/bin/systemctl stop clamd@scan.service ExecReload=/usr/bin/systemctl reload clamd@scan.service [Install] WantedBy=multi-user.target EOF } # openSUSE-like: wrapper (robusto) verso clamd.service write_bridge_wrapper_suse() { local bridge="/etc/systemd/system/clamav-daemon.service" local target="clamd.service" unit_exists "$target" || { echo "openSUSE-like: manca $target" >&2; exit 1; } log "Creo bridge wrapper: clamav-daemon.service -> $target (wrapper oneshot)" cat > "$bridge" <<'EOF' [Unit] Description=ClamAV daemon bridge (wrapper to clamd) Wants=clamd.service After=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/systemctl start clamd.service ExecStop=/usr/bin/systemctl stop clamd.service ExecReload=/usr/bin/systemctl reload clamd.service [Install] WantedBy=multi-user.target EOF } enable_start_common() { local to_enable=("$@") for u in "${to_enable[@]}"; do if unit_exists "$u"; then log "Enable+start: $u" systemctl enable --now "$u" >/dev/null 2>&1 || true systemctl restart "$u" >/dev/null 2>&1 || true fi done } show_status() { local u="$1" log "Stato servizio: $u" systemctl --no-pager --full status "$u" || true } main() { need_root local id like read -r id like < <(detect_os) log "OS rilevato: ID=${id} ID_LIKE=${like}" if is_arch_like "$id" "$like"; then log "Arch-like: richiesto NO-OP. Esco senza modifiche." exit 0 fi if ! is_fedora_like "$id" "$like" && ! is_suse_like "$id" "$like"; then log "Distro non target (né Fedora-like né SUSE-like): nessuna modifica." exit 0 fi have_systemd || { echo "systemd/systemctl non trovato: impossibile creare bridge" >&2; exit 1; } # Ferma/disable eventuali definizioni precedenti del bridge e socket disable_stop_if_present "clamav-daemon.socket" disable_stop_if_present "clamav-daemon.service" if is_fedora_like "$id" "$like"; then write_bridge_wrapper_fedora daemon_reload # abilita target + bridge (bridge utile per comandi uniformi) enable_start_common "clamd@scan.service" "clamav-daemon.service" show_status "clamd@scan.service" show_status "clamav-daemon.service" exit 0 fi if is_suse_like "$id" "$like"; then write_bridge_wrapper_suse daemon_reload # abilita target + bridge (bridge utile per comandi uniformi) enable_start_common "clamd.service" "clamav-daemon.service" show_status "clamd.service" show_status "clamav-daemon.service" exit 0 fi } main "$@"