Update mail-status.sh
Neni povinne cat > /etc/postfix/addr_hygiene.pcre <<'EOF' /[[:space:]<>;,()"]/ REJECT 5.1.3 Bad address syntax EOF postconf -e 'smtpd_sender_restrictions = check_sender_access pcre:/etc/postfix/addr_hygiene.pcre, $smtpd_sender_restrictions' Zmena v produkčnom main.cf. Pred ňou si pozri aktuálnu hodnotu cez postconf -n smtpd_sender_restrictions. Ak je prázdna, $smtpd_sender_restrictions z príkazu vynechaj, inak vznikne rekurzia a postfix check zlyhá. Pravidlo zámerne neblokuje =, + ani /, ktoré používajú SRS, BATV a VERP adresy.
This commit is contained in:
1 parent
dde33eec1a
commit
f36b563e09
1 file changed
+88
-17
+88
-17
@@ -1,11 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# mail-stats - Postfix Mail Summary Tool (v5.0.3)
|
# mail-stats - Postfix Mail Summary Tool (v5.0.4)
|
||||||
#
|
#
|
||||||
# Requires: bash >= 4.2, GNU coreutils/findutils, util-linux (flock),
|
# Requires: bash >= 4.2, GNU coreutils/findutils, util-linux (flock),
|
||||||
# gawk (recommended) or mawk 1.3.4 (verified by a self-test at start)
|
# gawk (recommended) or mawk 1.3.4 (verified by a self-test at start)
|
||||||
# Optional: gzip/xz/bzip2/zstd (rotated logs), journalctl, less
|
# Optional: gzip/xz/bzip2/zstd (rotated logs), journalctl, less
|
||||||
#
|
#
|
||||||
|
# 5.0.4: ambiguous log lines (spoofing via quoted addresses) are detected and
|
||||||
|
# flagged ("sent?", "REJECT?") instead of silently trusted;
|
||||||
|
# state table uses age-based eviction (unqueued > 1h, queued >
|
||||||
|
# maximal_queue_lifetime + 1d) instead of a full reset
|
||||||
# 5.0.3: log injection fixes (attacker-controlled Subject/addresses/remote
|
# 5.0.3: log injection fixes (attacker-controlled Subject/addresses/remote
|
||||||
# replies could forge "sent"/"reject" records or hide deliveries):
|
# replies could forge "sent"/"reject" records or hide deliveries):
|
||||||
# - parser anchors on the program/queue-id field positions
|
# - parser anchors on the program/queue-id field positions
|
||||||
@@ -55,7 +59,7 @@ if (( EUID == 0 )); then
|
|||||||
unset -v TMPDIR XDG_RUNTIME_DIR
|
unset -v TMPDIR XDG_RUNTIME_DIR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
readonly VERSION="5.0.3"
|
readonly VERSION="5.0.4"
|
||||||
|
|
||||||
die() { local m="$*"; printf 'Error: %s\n' "${m//[[:cntrl:]]/?}" >&2; exit 1; }
|
die() { local m="$*"; printf 'Error: %s\n' "${m//[[:cntrl:]]/?}" >&2; exit 1; }
|
||||||
warn() { local m="$*"; printf 'Warning: %s\n' "${m//[[:cntrl:]]/?}" >&2; }
|
warn() { local m="$*"; printf 'Warning: %s\n' "${m//[[:cntrl:]]/?}" >&2; }
|
||||||
@@ -106,6 +110,11 @@ ENVIRONMENT (resource limits for the parser):
|
|||||||
MAIL_STATS_MEM_KB (default 1048576) ulimit -v
|
MAIL_STATS_MEM_KB (default 1048576) ulimit -v
|
||||||
MAIL_STATS_CPU_SEC (default 300) ulimit -t (not in watch mode)
|
MAIL_STATS_CPU_SEC (default 300) ulimit -t (not in watch mode)
|
||||||
MAIL_STATS_FSIZE_KB (default 1048576) ulimit -f (not in watch mode)
|
MAIL_STATS_FSIZE_KB (default 1048576) ulimit -f (not in watch mode)
|
||||||
|
MAIL_STATS_MAX_STATE (default 200000) max tracked queue IDs
|
||||||
|
|
||||||
|
A status ending with "?" (e.g. "sent?") marks a log line that contains the
|
||||||
|
Postfix field structure more than once (possible injection via a quoted
|
||||||
|
address or a remote reply). Verify such records directly in the log.
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@@ -198,11 +207,25 @@ fi
|
|||||||
|
|
||||||
# Resource limits - validated as strings BEFORE any arithmetic use:
|
# Resource limits - validated as strings BEFORE any arithmetic use:
|
||||||
# bash (( )) evaluates variable contents, e.g. 'x[$(cmd)]' would execute cmd
|
# bash (( )) evaluates variable contents, e.g. 'x[$(cmd)]' would execute cmd
|
||||||
: "${MAIL_STATS_MEM_KB:=1048576}" "${MAIL_STATS_CPU_SEC:=300}" "${MAIL_STATS_FSIZE_KB:=1048576}"
|
: "${MAIL_STATS_MEM_KB:=1048576}" "${MAIL_STATS_CPU_SEC:=300}" "${MAIL_STATS_FSIZE_KB:=1048576}" "${MAIL_STATS_MAX_STATE:=200000}"
|
||||||
for lim in MAIL_STATS_MEM_KB MAIL_STATS_CPU_SEC MAIL_STATS_FSIZE_KB; do
|
for lim in MAIL_STATS_MEM_KB MAIL_STATS_CPU_SEC MAIL_STATS_FSIZE_KB MAIL_STATS_MAX_STATE; do
|
||||||
[[ ${!lim} =~ ^[1-9][0-9]{0,11}$ ]] || die "$lim must be a positive integer."
|
[[ ${!lim} =~ ^[1-9][0-9]{0,11}$ ]] || die "$lim must be a positive integer."
|
||||||
done
|
done
|
||||||
readonly MAIL_STATS_MEM_KB MAIL_STATS_CPU_SEC MAIL_STATS_FSIZE_KB
|
readonly MAIL_STATS_MEM_KB MAIL_STATS_CPU_SEC MAIL_STATS_FSIZE_KB MAIL_STATS_MAX_STATE
|
||||||
|
|
||||||
|
# Queue lifetime for state eviction: maximal_queue_lifetime (default unit: days) + 1 day
|
||||||
|
QLIFE_SEC=518400
|
||||||
|
if command -v postconf > /dev/null 2>&1; then
|
||||||
|
qlife_raw=$(postconf -h maximal_queue_lifetime 2> /dev/null || true)
|
||||||
|
if [[ $qlife_raw =~ ^([0-9]{1,6})([smhdw]?)$ ]]; then
|
||||||
|
case ${BASH_REMATCH[2]} in
|
||||||
|
s) qlife_mul=1 ;; m) qlife_mul=60 ;; h) qlife_mul=3600 ;; w) qlife_mul=604800 ;; *) qlife_mul=86400 ;;
|
||||||
|
esac
|
||||||
|
QLIFE_SEC=$(( 10#${BASH_REMATCH[1]} * qlife_mul + 86400 ))
|
||||||
|
fi
|
||||||
|
unset qlife_raw qlife_mul
|
||||||
|
fi
|
||||||
|
readonly QLIFE_SEC
|
||||||
|
|
||||||
# Run a command with resource limits (parser/sort only, not journalctl/gzip)
|
# Run a command with resource limits (parser/sort only, not journalctl/gzip)
|
||||||
run_limited() {
|
run_limited() {
|
||||||
@@ -407,8 +430,13 @@ BEGIN {
|
|||||||
# (no {n,m} intervals: broken/unsupported in some mawk builds)
|
# (no {n,m} intervals: broken/unsupported in some mawk builds)
|
||||||
hx = "[0-9A-F]"; lg = "[0-9B-DF-HJ-NP-TV-Zb-df-hj-np-tv-z]"
|
hx = "[0-9A-F]"; lg = "[0-9B-DF-HJ-NP-TV-Zb-df-hj-np-tv-z]"
|
||||||
QID_RE = "^(" hx hx hx hx hx hx hx "*|" lg lg lg lg lg lg lg lg lg lg lg "*):$"
|
QID_RE = "^(" hx hx hx hx hx hx hx "*|" lg lg lg lg lg lg lg lg lg lg lg "*):$"
|
||||||
MAX_STATE = 200000
|
MAX_STATE = ENVIRON["MS_MAX_STATE"] + 0; if (MAX_STATE < 100) MAX_STATE = 200000
|
||||||
nstate = 0; npend = 0; warned = 0
|
QLIFE = ENVIRON["MS_QLIFE"] + 0; if (QLIFE < 3600) QLIFE = 518400
|
||||||
|
UNQ_AGE = 3600 # queue ids never seen by qmgr (aborted sessions)
|
||||||
|
nstate = 0; npend = 0; warned = 0; warned_ev = 0; amb_count = 0
|
||||||
|
# fixed Postfix structures; more than one occurrence = ambiguous line
|
||||||
|
DLV_RE = ">, (orig_to=<[^>]*>, )?relay=[^ ,]+, (conn_use=[0-9]+, )?delay=[0-9.]+, (delays=[0-9./]+, )?dsn=[0-9.]+, status=[a-z]+"
|
||||||
|
REJ_RE = "; from=<[^>]*> to=<[^>]*> proto="
|
||||||
}
|
}
|
||||||
|
|
||||||
function chk(val, filt, lfilt, r) {
|
function chk(val, filt, lfilt, r) {
|
||||||
@@ -464,15 +492,40 @@ function out(rec, f) {
|
|||||||
if (w_mode) fflush()
|
if (w_mode) fflush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function count_re(str, re, n) {
|
||||||
|
n = 0
|
||||||
|
while (match(str, re)) { n++; str = substr(str, RSTART + (RLENGTH > 0 ? RLENGTH : 1)) }
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
function track(q) {
|
function track(q) {
|
||||||
if (q in seen) return
|
if (!(q in seen)) {
|
||||||
if (nstate >= MAX_STATE) reset_state()
|
if (nstate >= MAX_STATE) sweep()
|
||||||
seen[q] = 1; nstate++
|
seen[q] = 1; nstate++
|
||||||
}
|
}
|
||||||
|
last[q] = l_sec
|
||||||
|
}
|
||||||
|
|
||||||
|
# Age-based eviction: aborted sessions first, then messages older than the
|
||||||
|
# queue lifetime; thresholds are halved only if that is not enough
|
||||||
|
function sweep( q, ks, k, i, ua, qa, target, forced) {
|
||||||
|
ua = UNQ_AGE; qa = QLIFE; target = int(MAX_STATE * 0.75); forced = 0
|
||||||
|
while (1) {
|
||||||
|
k = 0; split("", ks)
|
||||||
|
for (q in seen) if ((l_sec - last[q]) > ((q in queued) ? qa : ua)) ks[++k] = q
|
||||||
|
for (i = 1; i <= k; i++) forget(ks[i])
|
||||||
|
if (nstate <= target) break
|
||||||
|
if (ua <= 60 && qa <= 60) { reset_state(); return }
|
||||||
|
if (ua > 60) ua = int(ua / 2)
|
||||||
|
else { qa = int(qa / 2); forced = 1 }
|
||||||
|
}
|
||||||
|
if (forced && !warned_ev++) print "Warning: state table full, evicted queued messages older than " qa "s; some records may lack sender/IP/size (raise MAIL_STATS_MAX_STATE)." > "/dev/stderr"
|
||||||
|
}
|
||||||
|
|
||||||
function forget(q) {
|
function forget(q) {
|
||||||
if (q in seen) { delete seen[q]; nstate-- }
|
if (q in seen) { delete seen[q]; nstate-- }
|
||||||
delete c_ip[q]; delete c_time[q]; delete snd[q]; delete subj[q]; delete sz[q]; delete orig[q]
|
delete c_ip[q]; delete c_time[q]; delete snd[q]; delete subj[q]; delete sz[q]; delete orig[q]
|
||||||
|
delete last[q]; delete queued[q]
|
||||||
}
|
}
|
||||||
|
|
||||||
function flush_pend(q, patch, i, f, n, rec) {
|
function flush_pend(q, patch, i, f, n, rec) {
|
||||||
@@ -501,9 +554,9 @@ function flush_all_pend( q, ks, k, i) {
|
|||||||
function reset_state() {
|
function reset_state() {
|
||||||
flush_all_pend()
|
flush_all_pend()
|
||||||
split("", seen); split("", c_ip); split("", c_time); split("", snd)
|
split("", seen); split("", c_ip); split("", c_time); split("", snd)
|
||||||
split("", subj); split("", sz); split("", orig)
|
split("", subj); split("", sz); split("", orig); split("", last); split("", queued)
|
||||||
nstate = 0
|
nstate = 0
|
||||||
if (!warned++) print "Warning: correlation state limit (" MAX_STATE " queue IDs) reached and reset; some records may lack sender/IP/size." > "/dev/stderr"
|
if (!warned++) print "Warning: state table full of recent entries (" MAX_STATE " queue IDs), full reset; some records may lack sender/IP/size (raise MAIL_STATS_MAX_STATE)." > "/dev/stderr"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Content filter re-injection: carry origin data from src to dst queue id
|
# Content filter re-injection: carry origin data from src to dst queue id
|
||||||
@@ -534,7 +587,7 @@ function emit(q, to, relay, st, dsn, reason, rec) {
|
|||||||
out(rec)
|
out(rec)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec, amb) {
|
||||||
# rest: "reject: RCPT from host[ip]: 554 5.7.1 ...; from=<s> to=<r> proto=... helo=<...>"
|
# rest: "reject: RCPT from host[ip]: 554 5.7.1 ...; from=<s> to=<r> proto=... helo=<...>"
|
||||||
r = rest; sub(/^(milter-)?reject: /, "", r)
|
r = rest; sub(/^(milter-)?reject: /, "", r)
|
||||||
ip = (q != "NOQUEUE" && (q in c_ip)) ? c_ip[q] : "unknown"
|
ip = (q != "NOQUEUE" && (q in c_ip)) ? c_ip[q] : "unknown"
|
||||||
@@ -544,7 +597,8 @@ function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
|||||||
}
|
}
|
||||||
f = "-"; t = "-"
|
f = "-"; t = "-"
|
||||||
# Postfix appends "; from=<..> to=<..> proto=" after the reply text
|
# Postfix appends "; from=<..> to=<..> proto=" after the reply text
|
||||||
if (match(r, /; from=<[^>]*> to=<[^>]*> proto=/)) {
|
amb = (count_re(r, REJ_RE) > 1)
|
||||||
|
if (!amb && match(r, REJ_RE)) {
|
||||||
ss = substr(r, RSTART, RLENGTH); r = substr(r, 1, RSTART - 1)
|
ss = substr(r, RSTART, RLENGTH); r = substr(r, 1, RSTART - 1)
|
||||||
match(ss, /from=<[^>]*>/); f = substr(ss, RSTART + 6, RLENGTH - 7); f = (f == "") ? "<>" : clean(f, 0)
|
match(ss, /from=<[^>]*>/); f = substr(ss, RSTART + 6, RLENGTH - 7); f = (f == "") ? "<>" : clean(f, 0)
|
||||||
match(ss, /to=<[^>]*>/); t = clean(substr(ss, RSTART + 4, RLENGTH - 5), 0)
|
match(ss, /to=<[^>]*>/); t = clean(substr(ss, RSTART + 4, RLENGTH - 5), 0)
|
||||||
@@ -552,6 +606,10 @@ function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
|||||||
re = clean(r, 512)
|
re = clean(r, 512)
|
||||||
dsn = "-"; if (match(re, /^[245][0-9][0-9] [245]\.[0-9]+\.[0-9]+/)) { dsn = substr(re, RSTART + 4, RLENGTH - 4) }
|
dsn = "-"; if (match(re, /^[245][0-9][0-9] [245]\.[0-9]+\.[0-9]+/)) { dsn = substr(re, RSTART + 4, RLENGTH - 4) }
|
||||||
st = (re ~ /[Gg]reylist/) ? "GREYLIST" : "REJECT"
|
st = (re ~ /[Gg]reylist/) ? "GREYLIST" : "REJECT"
|
||||||
|
if (amb) {
|
||||||
|
amb_count++; st = st "?"; f = "?"; t = "?"
|
||||||
|
re = clean("AMBIGUOUS LOG LINE (possible injection), verify in log: " r, 600)
|
||||||
|
}
|
||||||
rec = l_key OFS l_ts OFS ((q in c_time) ? c_time[q] : l_ts) OFS q OFS ((q in orig) ? orig[q] : "-")
|
rec = l_key OFS l_ts OFS ((q in c_time) ? c_time[q] : l_ts) OFS q OFS ((q in orig) ? orig[q] : "-")
|
||||||
rec = rec OFS ip OFS "-" OFS f OFS t OFS st OFS ((q in sz) ? sz[q] : 0)
|
rec = rec OFS ip OFS "-" OFS f OFS t OFS st OFS ((q in sz) ? sz[q] : 0)
|
||||||
rec = rec OFS dsn OFS ((q in subj) ? subj[q] : "-") OFS re
|
rec = rec OFS dsn OFS ((q in subj) ? subj[q] : "-") OFS re
|
||||||
@@ -563,6 +621,8 @@ function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
|||||||
tt = l_time; gsub(/:/, "", tt)
|
tt = l_time; gsub(/:/, "", tt)
|
||||||
l_key = l_y l_mm l_dd tt
|
l_key = l_y l_mm l_dd tt
|
||||||
l_ts = l_y "-" l_mm "-" l_dd " " l_time
|
l_ts = l_y "-" l_mm "-" l_dd " " l_time
|
||||||
|
# monotonic pseudo-epoch (month = 31 days), good enough for age thresholds
|
||||||
|
l_sec = ((l_y * 12 + l_mm) * 31 + l_dd) * 86400 + substr(tt, 1, 2) * 3600 + substr(tt, 3, 2) * 60 + substr(tt, 5, 2)
|
||||||
|
|
||||||
# Everything after "<program>[pid]: <QUEUE_ID>: " is untrusted text only where
|
# Everything after "<program>[pid]: <QUEUE_ID>: " is untrusted text only where
|
||||||
# Postfix embeds foreign data (addresses, Subject, remote replies). All
|
# Postfix embeds foreign data (addresses, Subject, remote replies). All
|
||||||
@@ -593,7 +653,7 @@ function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
|||||||
if (rest ~ /^from=</) {
|
if (rest ~ /^from=</) {
|
||||||
# qmgr: from=<sender>, size=N, nrcpt=N (queue active) - anchored at the end
|
# qmgr: from=<sender>, size=N, nrcpt=N (queue active) - anchored at the end
|
||||||
if (match(rest, />, size=[0-9]+, nrcpt=[0-9]+ \(queue active\)$/)) {
|
if (match(rest, />, size=[0-9]+, nrcpt=[0-9]+ \(queue active\)$/)) {
|
||||||
s = substr(rest, 7, RSTART - 7); snd[qid] = (s == "") ? "<>" : clean(s, 0)
|
s = substr(rest, 7, RSTART - 7); snd[qid] = (s == "") ? "<>" : clean(s, 0); queued[qid] = 1
|
||||||
tail = substr(rest, RSTART); match(tail, /size=[0-9]+/)
|
tail = substr(rest, RSTART); match(tail, /size=[0-9]+/)
|
||||||
sz[qid] = substr(tail, RSTART + 5, RLENGTH - 5) + 0
|
sz[qid] = substr(tail, RSTART + 5, RLENGTH - 5) + 0
|
||||||
}
|
}
|
||||||
@@ -613,7 +673,8 @@ function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
|||||||
if (rest ~ /^to=</) {
|
if (rest ~ /^to=</) {
|
||||||
# fixed Postfix structure after the (untrusted) recipient address; the
|
# fixed Postfix structure after the (untrusted) recipient address; the
|
||||||
# first match wins so that text in the remote reply cannot spoof it
|
# first match wins so that text in the remote reply cannot spoof it
|
||||||
if (!match(rest, />, (orig_to=<[^>]*>, )?relay=[^ ,]+, (conn_use=[0-9]+, )?delay=[0-9.]+, (delays=[0-9.\/]+, )?dsn=[0-9.]+, status=[a-z]+/)) next
|
amb = (count_re(rest, DLV_RE) > 1)
|
||||||
|
if (!match(rest, DLV_RE)) next
|
||||||
to = clean(substr(rest, 5, RSTART - 5), 0)
|
to = clean(substr(rest, 5, RSTART - 5), 0)
|
||||||
mid = substr(rest, RSTART, RLENGTH)
|
mid = substr(rest, RSTART, RLENGTH)
|
||||||
tail = substr(rest, RSTART + RLENGTH)
|
tail = substr(rest, RSTART + RLENGTH)
|
||||||
@@ -623,6 +684,13 @@ function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
|||||||
reason = "-"
|
reason = "-"
|
||||||
if (tail ~ /^ \(.*\)$/) reason = clean(substr(tail, 3, length(tail) - 3), 512)
|
if (tail ~ /^ \(.*\)$/) reason = clean(substr(tail, 3, length(tail) - 3), 512)
|
||||||
|
|
||||||
|
if (amb) {
|
||||||
|
# never hide or link on an ambiguous line - show it flagged with the raw text
|
||||||
|
amb_count++; st = st "?"; sub(/:[0-9]+$/, "", relay)
|
||||||
|
reason = clean("AMBIGUOUS LOG LINE (possible injection), verify in log: " rest, 1024)
|
||||||
|
emit(qid, to, clean(relay, 255), st, dsn, reason)
|
||||||
|
next
|
||||||
|
}
|
||||||
# content filter hop (amavis & co.) - link to re-injected queue id, do not report
|
# content filter hop (amavis & co.) - link to re-injected queue id, do not report
|
||||||
if (relay ~ /^[^\[]*\[(127\.0\.0\.1|(ipv6:)?::1)\]:10[0-9][0-9][0-9]$/) {
|
if (relay ~ /^[^\[]*\[(127\.0\.0\.1|(ipv6:)?::1)\]:10[0-9][0-9][0-9]$/) {
|
||||||
if (st == "sent" && match(tail, /queued as [0-9A-Za-z]+\)$/)) link(qid, substr(tail, RSTART + 10, RLENGTH - 11))
|
if (st == "sent" && match(tail, /queued as [0-9A-Za-z]+\)$/)) link(qid, substr(tail, RSTART + 10, RLENGTH - 11))
|
||||||
@@ -633,7 +701,10 @@ function handle_reject(q, rest, p, r, f, t, ip, ss, re, dsn, st, rec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
END { flush_all_pend() }
|
END {
|
||||||
|
flush_all_pend()
|
||||||
|
if (amb_count) print "Warning: " amb_count " ambiguous log line(s) flagged with \"?\" status (possible log injection)." > "/dev/stderr"
|
||||||
|
}
|
||||||
'
|
'
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -702,7 +773,7 @@ check_pipe() {
|
|||||||
export MS_DAY_YMD="$DAY_YMD" MS_TIME="$TIME_FILTER" MS_FROM="$FROM_FILTER" MS_TO="$TO_FILTER" \
|
export MS_DAY_YMD="$DAY_YMD" MS_TIME="$TIME_FILTER" MS_FROM="$FROM_FILTER" MS_TO="$TO_FILTER" \
|
||||||
MS_ID="$ID_FILTER" MS_IP="$IP_FILTER" MS_STATUS="$STATUS_FILTER" MS_MIN_SIZE="$MIN_SIZE" \
|
MS_ID="$ID_FILTER" MS_IP="$IP_FILTER" MS_STATUS="$STATUS_FILTER" MS_MIN_SIZE="$MIN_SIZE" \
|
||||||
MS_REGEX="$REGEX_MODE" MS_WATCH="$WATCH_MODE" MS_GAWK="$IS_GAWK" MS_CUR_Y="$CUR_Y" \
|
MS_REGEX="$REGEX_MODE" MS_WATCH="$WATCH_MODE" MS_GAWK="$IS_GAWK" MS_CUR_Y="$CUR_Y" \
|
||||||
MS_CUR_M="$((10#$CUR_M))" MS_COLOR="$USE_COLOR" MS_CSV="$CSV_MODE" MS_DETAIL="$DETAIL_VIEW"
|
MS_CUR_M="$((10#$CUR_M))" MS_MAX_STATE="$MAIL_STATS_MAX_STATE" MS_QLIFE="$QLIFE_SEC" MS_COLOR="$USE_COLOR" MS_CSV="$CSV_MODE" MS_DETAIL="$DETAIL_VIEW"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# 8. WATCH MODE
|
# 8. WATCH MODE
|
||||||
|
|||||||
Reference in new issue
Block a user