first commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# kerio-queue-clean.sh
|
||||
|
||||
Entfernt Nachrichten aus der Kerio-Connect-Queue (`/opt/kerio/mailserver/store/queue`)
|
||||
anhand von Filterregeln, z. B. wenn ein kompromittiertes Konto die Queue mit Spam flutet.
|
||||
|
||||
- durchsucht die Queue rekursiv (inkl. Unterverzeichnisse)
|
||||
- schaut in `<name>.env` (Umschlag) und `<name>.eml` (Header/Inhalt)
|
||||
- entfernt immer alle Dateien `<name>.*` einer Nachricht
|
||||
- Kommandozeile **oder** ncurses-Oberfläche (`dialog` bzw. `whiptail`)
|
||||
|
||||
## Schnellstart
|
||||
|
||||
```bash
|
||||
# ncurses-Oberfläche
|
||||
sudo ./kerio-queue-clean.sh
|
||||
|
||||
# erst nur ansehen
|
||||
sudo ./kerio-queue-clean.sh -s hacked@firma.de -n
|
||||
|
||||
# dann entfernen: Dienst kurz stoppen, Backup + Log
|
||||
sudo ./kerio-queue-clean.sh -s hacked@firma.de -S -b /root/queue-backup -l /var/log/kerio-queue-clean.log
|
||||
```
|
||||
|
||||
## Filter
|
||||
|
||||
| Option | prüft |
|
||||
|---|---|
|
||||
| `-s` Absender | Umschlag-Absender / Auth-User aus `.env`, `From:`, `Return-Path:`, `Sender:` |
|
||||
| `-r` Empfänger | Umschlag-Empfänger aus `.env`, `To:`, `Cc:`, `Delivered-To:` |
|
||||
| `-j` Betreff | `Subject:` |
|
||||
| `-c` Inhalt | komplette `.eml` (Header + Body) |
|
||||
|
||||
Mehrere Muster des gleichen Typs sind ODER-verknüpft, verschiedene Typen UND-verknüpft.
|
||||
Standard ist ein Teilstring-Vergleich, mit `-x` werden die Muster als Regex ausgewertet. Groß-/Kleinschreibung wird nie unterschieden.
|
||||
|
||||
Mit `--inspect` siehst du den Aufbau einiger `.env`-Dateien, um die Filter zu prüfen.
|
||||
|
||||
Alle Optionen zeigt `./kerio-queue-clean.sh --help`.
|
||||
Executable
+462
@@ -0,0 +1,462 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# kerio-queue-clean.sh
|
||||
#
|
||||
# Entfernt Nachrichten aus der Kerio-Connect-Queue anhand von Filterregeln
|
||||
# (Absender, Empfaenger, Betreff, Inhalt). Gedacht fuer den Fall, dass ein
|
||||
# kompromittiertes Konto die Queue mit Spam flutet.
|
||||
#
|
||||
# Jede Nachricht besteht aus <name>.eml (Mail) und <name>.env (Umschlag).
|
||||
# Die Queue darf Unterverzeichnisse haben; es wird rekursiv gesucht.
|
||||
#
|
||||
# Aufruf ohne Parameter (oder mit -i) startet die ncurses-Oberflaeche
|
||||
# (dialog oder whiptail). Siehe --help.
|
||||
|
||||
set -o pipefail
|
||||
|
||||
VERSION="1.0"
|
||||
QUEUE_DIR="/opt/kerio/mailserver/store/queue"
|
||||
SERVICE_NAME="kerio-connect"
|
||||
BACKUP_DIR=""
|
||||
LOG_FILE=""
|
||||
USE_REGEX=0
|
||||
DRY_RUN=0
|
||||
ASSUME_YES=0
|
||||
STOP_SERVICE=0
|
||||
TUI=0
|
||||
INSPECT=0
|
||||
|
||||
SENDERS=()
|
||||
RCPTS=()
|
||||
SUBJECTS=()
|
||||
CONTENTS=()
|
||||
|
||||
TMPDIR_KQ=$(mktemp -d "${TMPDIR:-/tmp}/kerio-queue-clean.XXXXXX") || exit 1
|
||||
trap 'rm -rf "$TMPDIR_KQ"' EXIT
|
||||
RESULT_FILE="$TMPDIR_KQ/result.tsv"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Matcher: liest <name>.env (optional) und <name>.eml und gibt bei Treffer
|
||||
# eine Zeile "Umschlag-Absender <TAB> From-Header <TAB> Betreff" aus.
|
||||
# Muster kommen ueber ENVIRON (keine Escape-Verarbeitung wie bei -v).
|
||||
# - mehrere Muster desselben Typs -> ODER
|
||||
# - verschiedene Typen kombiniert -> UND
|
||||
# ---------------------------------------------------------------------------
|
||||
read -r -d '' AWK_MATCH <<'AWK'
|
||||
function hit(s, pats, n, a, i, p) {
|
||||
n = split(pats, a, "\n")
|
||||
s = tolower(s)
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (a[i] == "") continue
|
||||
p = tolower(a[i])
|
||||
if (rx) { if (s ~ p) return 1 }
|
||||
else if (index(s, p)) return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
function hdr_done( name, val) {
|
||||
if (cur == "") return
|
||||
name = tolower(cur); sub(/:.*/, "", name)
|
||||
val = cur; sub(/^[^:]*:[ \t]*/, "", val)
|
||||
if (name == "from" || name == "return-path" || name == "sender") {
|
||||
hsend = hsend "\n" val
|
||||
if (name == "from" && hfrom == "") hfrom = val
|
||||
} else if (name == "to" || name == "cc" || name == "delivered-to" || name == "x-original-to") {
|
||||
hrcpt = hrcpt "\n" val
|
||||
} else if (name == "subject" && subj == "") {
|
||||
subj = val
|
||||
}
|
||||
cur = ""
|
||||
}
|
||||
function clean(s) { gsub(/[\t\r\n]+/, " ", s); sub(/^ +/, "", s); return s }
|
||||
BEGIN {
|
||||
sp = ENVIRON["KQ_SENDERS"]; rp = ENVIRON["KQ_RCPTS"]
|
||||
jp = ENVIRON["KQ_SUBJECTS"]; cp = ENVIRON["KQ_CONTENTS"]
|
||||
rx = ENVIRON["KQ_REGEX"] + 0; envf = ENVIRON["KQ_ENVF"]
|
||||
}
|
||||
FILENAME == envf {
|
||||
sub(/\r$/, "")
|
||||
if ($0 != "") envl[++en] = $0
|
||||
next
|
||||
}
|
||||
{
|
||||
sub(/\r$/, "")
|
||||
if (!inbody) {
|
||||
if ($0 == "") { hdr_done(); inbody = 1; if (cp == "" || chit) exit; next }
|
||||
if ($0 ~ /^[ \t]/) { sub(/^[ \t]+/, " "); cur = cur $0 }
|
||||
else { hdr_done(); cur = $0 }
|
||||
if (cp != "" && !chit && hit($0, cp)) chit = 1
|
||||
next
|
||||
}
|
||||
if (cp != "" && hit($0, cp)) { chit = 1; exit }
|
||||
}
|
||||
END {
|
||||
hdr_done()
|
||||
# Umschlag auswerten: Zeilen mit Schluesselwort vor der Adresse zuordnen,
|
||||
# sonst gilt: erste Adresszeile = Absender, weitere = Empfaenger.
|
||||
kw = 0
|
||||
for (i = 1; i <= en; i++) {
|
||||
pre = tolower(envl[i]); sub(/[<@].*/, "", pre)
|
||||
if (pre ~ /from|sender|return|auth|user/) { esend = esend "\n" envl[i]; if (efirst == "") efirst = envl[i]; kw = 1 }
|
||||
else if (pre ~ /rcpt|recip|to/) { ercpt = ercpt "\n" envl[i]; kw = 1 }
|
||||
}
|
||||
if (!kw) {
|
||||
for (i = 1; i <= en; i++) {
|
||||
if (envl[i] !~ /@|<>/) continue
|
||||
if (efirst == "") { efirst = envl[i]; esend = envl[i] }
|
||||
else ercpt = ercpt "\n" envl[i]
|
||||
}
|
||||
}
|
||||
ok = 1
|
||||
if (sp != "" && !hit(esend "\n" hsend, sp)) ok = 0
|
||||
if (rp != "" && !hit(ercpt "\n" hrcpt, rp)) ok = 0
|
||||
if (jp != "" && !hit(subj, jp)) ok = 0
|
||||
if (cp != "" && !chit) ok = 0
|
||||
if (ok) printf "%s\t%s\t%s\n", clean(efirst), clean(hfrom), clean(subj)
|
||||
}
|
||||
AWK
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Hilfsfunktionen
|
||||
# ---------------------------------------------------------------------------
|
||||
die() { echo "FEHLER: $*" >&2; exit 1; }
|
||||
info() { echo "$*" >&2; }
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
kerio-queue-clean.sh $VERSION - Mails nach Filterregeln aus der Kerio-Connect-Queue entfernen
|
||||
|
||||
Aufruf:
|
||||
$0 ncurses-Oberflaeche starten
|
||||
$0 [Optionen] Kommandozeilenmodus
|
||||
|
||||
Filter (mehrfach angebbar; gleicher Typ = ODER, verschiedene Typen = UND):
|
||||
-s, --sender MUSTER Absender (Umschlag/.env, From:, Return-Path:, Sender:)
|
||||
-r, --recipient MUSTER Empfaenger (Umschlag/.env, To:, Cc:, Delivered-To:)
|
||||
-j, --subject MUSTER Betreff
|
||||
-c, --content MUSTER beliebiger Text in der .eml (Header + Body)
|
||||
-x, --regex Muster als erweiterte Regex statt Teilstring
|
||||
(Gross-/Kleinschreibung wird immer ignoriert)
|
||||
|
||||
Aktionen:
|
||||
-n, --dry-run nur auflisten, nichts loeschen
|
||||
-y, --yes ohne Rueckfrage loeschen
|
||||
-b, --backup DIR Treffer nach DIR verschieben statt loeschen
|
||||
-S, --stop-service Kerio-Dienst waehrend des Loeschens stoppen (empfohlen)
|
||||
--service NAME Name des Dienstes (Standard: $SERVICE_NAME)
|
||||
-l, --log DATEI geloeschte Mails protokollieren
|
||||
|
||||
Sonstiges:
|
||||
-d, --queue DIR Queue-Verzeichnis (Standard: $QUEUE_DIR)
|
||||
-i, --tui ncurses-Oberflaeche erzwingen
|
||||
--inspect [N] N Beispiel-.env-Dateien + Header zeigen (Standard 3)
|
||||
-h, --help diese Hilfe
|
||||
|
||||
Beispiele:
|
||||
$0 -s hacked@firma.de -n
|
||||
$0 -s hacked@firma.de -S -b /root/queue-backup -l /var/log/kerio-queue-clean.log
|
||||
$0 -x -s '^.*@firma\.de' -j 'invoice|payment' -y
|
||||
EOF
|
||||
}
|
||||
|
||||
export_patterns() {
|
||||
local IFS=$'\n'
|
||||
export KQ_SENDERS="${SENDERS[*]}"
|
||||
export KQ_RCPTS="${RCPTS[*]}"
|
||||
export KQ_SUBJECTS="${SUBJECTS[*]}"
|
||||
export KQ_CONTENTS="${CONTENTS[*]}"
|
||||
export KQ_REGEX="$USE_REGEX"
|
||||
}
|
||||
|
||||
have_filter() {
|
||||
(( ${#SENDERS[@]} + ${#RCPTS[@]} + ${#SUBJECTS[@]} + ${#CONTENTS[@]} > 0 ))
|
||||
}
|
||||
|
||||
check_queue() {
|
||||
[[ -d $QUEUE_DIR ]] || { echo "Queue-Verzeichnis '$QUEUE_DIR' existiert nicht."; return 1; }
|
||||
[[ -r $QUEUE_DIR ]] || { echo "Keine Leserechte auf '$QUEUE_DIR' (als root starten?)."; return 1; }
|
||||
return 0
|
||||
}
|
||||
|
||||
# scan_queue MODE (MODE: quiet | stderr | gauge)
|
||||
# Schreibt Treffer nach $RESULT_FILE: basis<TAB>umschlag<TAB>from<TAB>betreff
|
||||
scan_queue() {
|
||||
local mode=$1 total i=0 eml base res last=-1 pct
|
||||
: > "$RESULT_FILE"
|
||||
export_patterns
|
||||
total=$(find "$QUEUE_DIR" -type f -name '*.eml' 2>/dev/null | wc -l)
|
||||
(( total == 0 )) && { [[ $mode == gauge ]] && echo 100; return 0; }
|
||||
while IFS= read -r -d '' eml; do
|
||||
i=$((i + 1))
|
||||
base=${eml%.eml}
|
||||
if [[ -f $base.env ]]; then
|
||||
res=$(KQ_ENVF="$base.env" awk "$AWK_MATCH" "$base.env" "$eml" 2>/dev/null)
|
||||
else
|
||||
res=$(KQ_ENVF="" awk "$AWK_MATCH" "$eml" 2>/dev/null)
|
||||
fi
|
||||
[[ -n $res ]] && printf '%s\t%s\n' "$base" "$res" >> "$RESULT_FILE"
|
||||
pct=$(( i * 100 / total ))
|
||||
if (( pct != last )); then
|
||||
last=$pct
|
||||
case $mode in
|
||||
gauge) echo "$pct" ;;
|
||||
stderr) printf '\rDurchsuche Queue: %3d%% (%d/%d)' "$pct" "$i" "$total" >&2 ;;
|
||||
esac
|
||||
fi
|
||||
done < <(find "$QUEUE_DIR" -type f -name '*.eml' -print0 2>/dev/null)
|
||||
[[ $mode == stderr ]] && echo >&2
|
||||
return 0
|
||||
}
|
||||
|
||||
service_ctl() { # service_ctl stop|start
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl "$1" "$SERVICE_NAME"
|
||||
elif [[ -x /etc/init.d/$SERVICE_NAME ]]; then
|
||||
"/etc/init.d/$SERVICE_NAME" "$1"
|
||||
else
|
||||
echo "Dienst '$SERVICE_NAME' kann nicht gesteuert werden." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# delete_matches LISTE MODE (MODE: quiet | stderr | gauge)
|
||||
# Loescht (oder verschiebt) alle Dateien <basis>.* der Eintraege in LISTE.
|
||||
delete_matches() {
|
||||
local list=$1 mode=$2 total i=0 base env from subj rel f done_cnt=0 err_cnt=0
|
||||
total=$(wc -l < "$list")
|
||||
(( total == 0 )) && return 0
|
||||
while IFS=$'\t' read -r base env from subj; do
|
||||
i=$((i + 1))
|
||||
local files=()
|
||||
for f in "$base".*; do [[ -e $f ]] && files+=("$f"); done
|
||||
if (( ${#files[@]} > 0 )); then
|
||||
if [[ -n $BACKUP_DIR ]]; then
|
||||
rel=${base#"$QUEUE_DIR"/}
|
||||
mkdir -p "$BACKUP_DIR/$(dirname "$rel")" &&
|
||||
mv -f -- "${files[@]}" "$BACKUP_DIR/$(dirname "$rel")/"
|
||||
else
|
||||
rm -f -- "${files[@]}"
|
||||
fi
|
||||
if (( $? == 0 )); then
|
||||
done_cnt=$((done_cnt + 1))
|
||||
[[ -n $LOG_FILE ]] && printf '%s\t%s\t%s\t%s\t%s\n' \
|
||||
"$(date '+%F %T')" "$base" "$env" "$from" "$subj" >> "$LOG_FILE"
|
||||
else
|
||||
err_cnt=$((err_cnt + 1))
|
||||
fi
|
||||
fi
|
||||
case $mode in
|
||||
gauge) echo $(( i * 100 / total )) ;;
|
||||
stderr) (( i % 100 == 0 || i == total )) && printf '\rEntferne: %d/%d' "$i" "$total" >&2 ;;
|
||||
esac
|
||||
done < "$list"
|
||||
[[ $mode == stderr ]] && echo >&2
|
||||
echo "$done_cnt $err_cnt" > "$TMPDIR_KQ/delete.stat"
|
||||
}
|
||||
|
||||
delete_with_service() { # delete_with_service LISTE MODE
|
||||
local stopped=0
|
||||
if (( STOP_SERVICE )); then
|
||||
if service_ctl stop >/dev/null 2>&1; then stopped=1
|
||||
else echo "Warnung: Dienst konnte nicht gestoppt werden." >&2; fi
|
||||
fi
|
||||
delete_matches "$1" "$2"
|
||||
(( stopped )) && service_ctl start >/dev/null 2>&1
|
||||
return 0
|
||||
}
|
||||
|
||||
inspect_queue() {
|
||||
local n=${1:-3} env eml
|
||||
check_queue || exit 1
|
||||
while IFS= read -r -d '' env; do
|
||||
eml=${env%.env}.eml
|
||||
echo "===== $env ====="
|
||||
cat -- "$env"
|
||||
if [[ -f $eml ]]; then
|
||||
echo "----- Header aus $(basename "$eml") -----"
|
||||
awk '/^\r?$/ {exit} /^(From|To|Cc|Subject|Return-Path|Sender):/' "$eml"
|
||||
fi
|
||||
echo
|
||||
n=$((n - 1)); (( n <= 0 )) && break
|
||||
done < <(find "$QUEUE_DIR" -type f -name '*.env' -print0)
|
||||
}
|
||||
|
||||
print_results() {
|
||||
local base env from subj
|
||||
printf '%-40s %-30s %s\n' "DATEI" "ABSENDER" "BETREFF"
|
||||
while IFS=$'\t' read -r base env from subj; do
|
||||
printf '%-40s %-30s %s\n' "${base#"$QUEUE_DIR"/}" "${env:-$from}" "$subj"
|
||||
done < "$RESULT_FILE"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Kommandozeilenmodus
|
||||
# ---------------------------------------------------------------------------
|
||||
run_cli() {
|
||||
check_queue >&2 || exit 1
|
||||
have_filter || die "Mindestens ein Filter (-s/-r/-j/-c) ist noetig. Siehe --help."
|
||||
|
||||
scan_queue stderr
|
||||
local count
|
||||
count=$(wc -l < "$RESULT_FILE")
|
||||
print_results
|
||||
echo
|
||||
echo "Treffer: $count"
|
||||
(( count == 0 )) && exit 0
|
||||
(( DRY_RUN )) && { echo "Trockenlauf - nichts geloescht."; exit 0; }
|
||||
|
||||
if (( ! ASSUME_YES )); then
|
||||
local action="LOESCHEN"
|
||||
[[ -n $BACKUP_DIR ]] && action="nach $BACKUP_DIR VERSCHIEBEN"
|
||||
read -r -p "$count Nachrichten $action? Zum Bestaetigen 'ja' eingeben: " ans
|
||||
[[ $ans == ja ]] || { echo "Abgebrochen."; exit 0; }
|
||||
fi
|
||||
|
||||
delete_with_service "$RESULT_FILE" stderr
|
||||
local ok err
|
||||
read -r ok err < "$TMPDIR_KQ/delete.stat"
|
||||
echo "Erledigt: $ok entfernt, $err Fehler."
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ncurses-Oberflaeche (dialog oder whiptail)
|
||||
# ---------------------------------------------------------------------------
|
||||
DLG=""
|
||||
ui() { "$DLG" --backtitle "Kerio Connect Queue Cleaner $VERSION" "$@" 3>&1 1>&2 2>&3; }
|
||||
|
||||
join_list() { local IFS=';'; echo "$*"; }
|
||||
split_list() { # split_list ARRAYNAME "a;b;c"
|
||||
local -n _arr=$1
|
||||
local item
|
||||
_arr=()
|
||||
IFS=';' read -r -a _tmp <<< "$2"
|
||||
for item in "${_tmp[@]}"; do
|
||||
item=$(sed 's/^[[:space:]]*//; s/[[:space:]]*$//' <<< "$item")
|
||||
[[ -n $item ]] && _arr+=("$item")
|
||||
done
|
||||
}
|
||||
|
||||
edit_list() { # edit_list ARRAYNAME TITEL
|
||||
local -n _ref=$1
|
||||
local val
|
||||
val=$(ui --title "$2" --inputbox \
|
||||
"Mehrere Muster mit ';' trennen (ODER-Verknuepfung).\nLeer lassen = Filter aus." \
|
||||
10 70 "$(join_list "${_ref[@]}")") || return
|
||||
split_list "$1" "$val"
|
||||
}
|
||||
|
||||
yn() { (( $1 )) && echo "an" || echo "aus"; }
|
||||
|
||||
tui_search_and_delete() {
|
||||
local msg rows cols count
|
||||
if ! msg=$(check_queue); then ui --msgbox "$msg" 8 70; return; fi
|
||||
if ! have_filter; then ui --msgbox "Bitte zuerst mindestens einen Filter setzen." 8 60; return; fi
|
||||
|
||||
scan_queue gauge | ui --title "Suche" --gauge "Durchsuche $QUEUE_DIR ..." 8 70 0
|
||||
count=$(wc -l < "$RESULT_FILE")
|
||||
if (( count == 0 )); then ui --msgbox "Keine passenden Nachrichten gefunden." 8 50; return; fi
|
||||
|
||||
rows=$(tput lines 2>/dev/null || echo 24); cols=$(tput cols 2>/dev/null || echo 80)
|
||||
local selected="$TMPDIR_KQ/selected.tsv"
|
||||
|
||||
if (( count <= 2000 )); then
|
||||
local args=() i=0 base env from subj w=$((cols - 20))
|
||||
while IFS=$'\t' read -r base env from subj; do
|
||||
i=$((i + 1))
|
||||
local text="${env:-$from} | $subj"
|
||||
args+=("$i" " ${text:0:$w}" on)
|
||||
done < "$RESULT_FILE"
|
||||
local choice
|
||||
choice=$(ui --title "$count Treffer" --separate-output --checklist \
|
||||
"Zu entfernende Nachrichten (Leertaste = abwaehlen):" \
|
||||
$((rows - 4)) $((cols - 6)) $((rows - 12)) "${args[@]}") || return
|
||||
[[ -z $choice ]] && return
|
||||
awk 'NR==FNR {sel[$1]; next} (FNR in sel)' <(echo "$choice") "$RESULT_FILE" > "$selected"
|
||||
else
|
||||
print_results > "$TMPDIR_KQ/list.txt"
|
||||
ui --title "$count Treffer" --scrolltext --textbox "$TMPDIR_KQ/list.txt" $((rows - 4)) $((cols - 6))
|
||||
cp "$RESULT_FILE" "$selected"
|
||||
fi
|
||||
|
||||
count=$(wc -l < "$selected")
|
||||
local action="LOESCHEN"
|
||||
[[ -n $BACKUP_DIR ]] && action="nach $BACKUP_DIR VERSCHIEBEN"
|
||||
local svc=""
|
||||
(( STOP_SERVICE )) && svc="\n\nDer Dienst '$SERVICE_NAME' wird dafuer kurz gestoppt."
|
||||
ui --title "Bestaetigung" --defaultno --yesno "$count Nachrichten wirklich $action?$svc" 10 70 || return
|
||||
|
||||
delete_with_service "$selected" gauge | ui --title "Entferne" --gauge "Entferne Nachrichten ..." 8 70 0
|
||||
local ok err
|
||||
read -r ok err < "$TMPDIR_KQ/delete.stat"
|
||||
ui --msgbox "Fertig.\n\nEntfernt: $ok\nFehler: $err" 10 50
|
||||
}
|
||||
|
||||
run_tui() {
|
||||
if command -v dialog >/dev/null 2>&1; then DLG=dialog
|
||||
elif command -v whiptail >/dev/null 2>&1; then DLG=whiptail
|
||||
else die "Weder 'dialog' noch 'whiptail' installiert (apt install dialog). Alternativ Parameter nutzen, siehe --help."
|
||||
fi
|
||||
|
||||
local choice val
|
||||
while true; do
|
||||
choice=$(ui --title "Hauptmenue" --cancel-button "Beenden" --menu \
|
||||
"Filter setzen und dann 'Suchen' waehlen.\nGleicher Typ = ODER, verschiedene Typen = UND." 22 78 12 \
|
||||
1 "Queue-Pfad : $QUEUE_DIR" \
|
||||
2 "Absender : $(join_list "${SENDERS[@]}")" \
|
||||
3 "Empfaenger : $(join_list "${RCPTS[@]}")" \
|
||||
4 "Betreff : $(join_list "${SUBJECTS[@]}")" \
|
||||
5 "Inhalt (.eml) : $(join_list "${CONTENTS[@]}")" \
|
||||
6 "Regex-Modus : $(yn $USE_REGEX)" \
|
||||
7 "Backup statt rm : ${BACKUP_DIR:-aus}" \
|
||||
8 "Dienst stoppen : $(yn $STOP_SERVICE) ($SERVICE_NAME)" \
|
||||
9 "Protokoll : ${LOG_FILE:-aus}" \
|
||||
S ">> Suchen und entfernen" \
|
||||
I " Beispiel .env/Header ansehen" \
|
||||
Q " Beenden") || break
|
||||
case $choice in
|
||||
1) val=$(ui --inputbox "Queue-Verzeichnis:" 8 70 "$QUEUE_DIR") && QUEUE_DIR=${val%/} ;;
|
||||
2) edit_list SENDERS "Absender" ;;
|
||||
3) edit_list RCPTS "Empfaenger" ;;
|
||||
4) edit_list SUBJECTS "Betreff" ;;
|
||||
5) edit_list CONTENTS "Inhalt" ;;
|
||||
6) USE_REGEX=$(( !USE_REGEX )) ;;
|
||||
7) val=$(ui --inputbox "Backup-Verzeichnis (leer = endgueltig loeschen):" 8 70 "$BACKUP_DIR") && BACKUP_DIR=${val%/} ;;
|
||||
8) STOP_SERVICE=$(( !STOP_SERVICE )) ;;
|
||||
9) val=$(ui --inputbox "Protokolldatei (leer = aus):" 8 70 "${LOG_FILE:-/var/log/kerio-queue-clean.log}") && LOG_FILE=$val ;;
|
||||
S) tui_search_and_delete ;;
|
||||
I) inspect_queue 3 > "$TMPDIR_KQ/inspect.txt" 2>&1
|
||||
ui --title "Beispiele" --scrolltext --textbox "$TMPDIR_KQ/inspect.txt" 22 90 ;;
|
||||
Q) break ;;
|
||||
esac
|
||||
done
|
||||
clear
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Parameter
|
||||
# ---------------------------------------------------------------------------
|
||||
[[ $# -eq 0 ]] && TUI=1
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-s|--sender) SENDERS+=("${2:?$1 braucht ein Argument}"); shift ;;
|
||||
-r|--recipient) RCPTS+=("${2:?$1 braucht ein Argument}"); shift ;;
|
||||
-j|--subject) SUBJECTS+=("${2:?$1 braucht ein Argument}"); shift ;;
|
||||
-c|--content) CONTENTS+=("${2:?$1 braucht ein Argument}"); shift ;;
|
||||
-x|--regex) USE_REGEX=1 ;;
|
||||
-n|--dry-run) DRY_RUN=1 ;;
|
||||
-y|--yes) ASSUME_YES=1 ;;
|
||||
-b|--backup) BACKUP_DIR="${2:?$1 braucht ein Argument}"; BACKUP_DIR=${BACKUP_DIR%/}; shift ;;
|
||||
-S|--stop-service) STOP_SERVICE=1 ;;
|
||||
--service) SERVICE_NAME="${2:?$1 braucht ein Argument}"; shift ;;
|
||||
-l|--log) LOG_FILE="${2:?$1 braucht ein Argument}"; shift ;;
|
||||
-d|--queue) QUEUE_DIR="${2:?$1 braucht ein Argument}"; QUEUE_DIR=${QUEUE_DIR%/}; shift ;;
|
||||
-i|--tui) TUI=1 ;;
|
||||
--inspect) INSPECT=1; [[ ${2:-} =~ ^[0-9]+$ ]] && { INSPECT=$2; shift; } ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) usage >&2; die "Unbekannte Option: $1" ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if (( INSPECT )); then inspect_queue "$INSPECT"; exit 0; fi
|
||||
if (( TUI )); then run_tui; else run_cli; fi
|
||||
Reference in New Issue
Block a user