pflogsumm - Produce Postfix MTA logfile summary
-Copyright (C) 1998-2025 by James S. Seymour, Release 1.1.13
+Copyright (C) 1998-2025 by James S. Seymour, Release 1.1.14
=head1 SYNOPSIS
-
- pflogsumm [--config <file>] [--bounce-detail <cnt>]
- [--colwidth <n>] [--deferral-detail <cnt>] [--detail <cnt>]
- [-d <date [range]>] [--dow0mon] [-e] [-h <cnt>] [-i]
- [--iso-date-time] [--mailq] [-m] [--no-no-msg-size]
+ pflogsumm [--config <file>] [--bounce-detail <cnt>] [--colwidth <n>]
+ [-d|--date-range <date [range]>] [--deferral-detail <cnt>]
+ [--detail <cnt>] [--dow0mon] [-e|--extended-detail]
+ [--expired-detail <cnt> ] [-h|--host-cnt <cnt>] [-i|--ignore-case]
+ [--iso-date-time] [-m|--uucp-mung] [--mailq] [--no-no-msg-size]
[--problems-first] [--pscrn-detail <cnt>] [--pscrn-stats]
- [-q] [--rej-add-from] [--rej-add-to] [--reject-detail <cnt>]
- [--smtp-detail <cnt>] [--smtpd-stats] [--smtpd-warning-detail <cnt>]
- [--srs-mung] [--syslog-name=string] [-u <cnt>]
- [--unprocd-file <filename> ] [--use-orig-to] [--verbose-msg-detail]
- [--verp-mung[=<n>]] [-x] [--zero-fill] [file1 [filen]]
+ [-q|--quiet] [--rej-add-from] [--rej-add-to] [--reject-detail <cnt>]
+ [--smtp-detail <cnt>] [--smtpd-stats]
+ [--smtpd-warning-detail <cnt>] [--srs-mung] [--syslog-name=string]
+ [-u|--user-cnt <cnt>] [--unprocd-file <filename> ] [--use-orig-to]
+ [--verbose-msg-detail] [--verp-mung[=<n>]] [-x|--debug] [--zero-fill]
+ [file1 [filen]]
pflogsumm --[dump-config|help|version]
"2025-07 - 2025-08" == 2025-07-01 - 2025-08-31
+ --debug Enable debugging to STDERR
+
+ See Also: -x
+
--dow0mon
First day of the week is Monday, rather than Sunday.
pflogsumm --dump-config <add'l args> |grep -v ' = $'
+ --expired-detail <cnt>
+
+ Limit detailed message queue time expired reports to
+ the top <cnt>. 0 to suppress entirely.
+
-e
--extended-detail
-x Enable debugging to STDERR
+ See Also: --debug
+
--zero-fill "Zero-fill" certain arrays so reports come out with
data in columns that that might otherwise be blank.
my $haveConfigSimple = $@ ? 0 : 1;
my $mailqCmd = "mailq";
-my $release = "1.1.13";
+my $release = "1.1.14";
# Variables and constants used throughout pflogsumm
our (
};
my (
- $cmd, $qid, $addr, $orig_to, $size, $relay, $status, $delay,
+ $svc, $qid, $addr, $orig_to, $size, $relay, $status, $delay, $tls,
$strtDate, $endDate,
%panics, %fatals, %warnings, %masterMsgs,
- %deferred, %bounced,
+ %deferred, %bounced, %expired,
%noMsgSize, %msgDetail,
$msgsRcvd, $msgsDlvrd, $sizeRcvd, $sizeDlvrd,
$msgMonStr, $msgMon, $msgDay, $msgTimeStr, $msgHr, $msgMin, $msgSec,
%warns, $msgsWrnd,
%discards, $msgsDscrdd,
%holds, $msgsHld,
- %rcvdMsg, $msgsFwdd, $msgsBncd,
+ %rcvdMsg, $msgsFwdd, $msgsBncd, $msgsExprd,
$msgsDfrdCnt, $msgsDfrd, %msgDfrdFlgs,
%connTime, %smtpdPerDay, %smtpdPerDom, $smtpdConnCnt, $smtpdTotTime,
%pscrnConnTime, %pscrnPerDay, %pscrnPerIP, $pscrnConnCnt, $pscrnTotTime,
($progName = $0) =~ s/^.*\///;
$usageMsg =
- "usage: $progName [--config <file>] [--bounce-detail <cnt>]
- [--colwidth <n>] [--deferral-detail <cnt>] [--detail <cnt>]
- [-d <date [range]>] [--dow0mon] [-e] [-h <cnt>] [-i]
- [--iso-date-time] [--mailq] [-m] [--no-no-msg-size]
+ "usage: $progName [--config <file>] [--bounce-detail <cnt>] [--colwidth <n>]
+ [-d|--date-range <date [range]>] [--deferral-detail <cnt>]
+ [--detail <cnt>] [--dow0mon] [-e|--extended-detail]
+ [--expired-detail <cnt> ] [-h|--host-cnt <cnt>] [-i|--ignore-case]
+ [--iso-date-time] [-m|--uucp-mung] [--mailq] [--no-no-msg-size]
[--problems-first] [--pscrn-detail <cnt>] [--pscrn-stats]
- [-q] [--rej-add-from] [--rej-add-to] [--reject-detail <cnt>]
- [--smtp-detail <cnt>] [--smtpd-stats] [--smtpd-warning-detail <cnt>]
- [--srs-mung] [--syslog-name=string] [-u <cnt>]
- [--unprocd-file <filename> ] [--use-orig-to] [--verbose-msg-detail]
- [--verp-mung[=<n>]] [-x] [--zero-fill] [file1 [filen]]
-
- $progName --[dump-config|help|version]
+ [-q|--quiet] [--rej-add-from] [--rej-add-to] [--reject-detail <cnt>]
+ [--smtp-detail <cnt>] [--smtpd-stats]
+ [--smtpd-warning-detail <cnt>] [--srs-mung] [--syslog-name=string]
+ [-u|--user-cnt <cnt>] [--unprocd-file <filename> ] [--use-orig-to]
+ [--verbose-msg-detail] [--verp-mung[=<n>]] [-x|--debug] [--zero-fill]
+ [file1 [filen]]
- Note: Where both long- and short-form options exist only the
- latter are shown above. See man page for long-form equivalents.";
+ $progName --[dump-config|help|version]";
#
# Central options specifications. This allows us to create a unified set
'detail' => { type => 'i' },
'dow0mon' => { type => 'b' },
'dump-config' => { type => 'b' },
+ 'expired-detail' => { type => 'i' },
'extended-detail' => { type => 'b', short => 'e' },
'help' => { type => 'b' },
'host-cnt' => { type => 'i', short => 'h' },
# internally: 0 == none, undefined == -1 == all
#
$opts{'colwidth'} = 0 if($opts{'verbose-msg-detail'}); # This one's a bit different
-foreach my $optName (qw(bounce-detail colwidth deferral-detail host-cnt pscrn-detail reject-detail smtp-detail smtpd-warning-detail user-cnt)) {
+foreach my $optName (qw(bounce-detail colwidth deferral-detail expired-detail host-cnt pscrn-detail reject-detail smtp-detail smtpd-warning-detail user-cnt)) {
$opts{$optName} = -1 unless(defined($opts{$optName}));
}
# If --detail was specified, set anything that's not enumerated to it
if(defined($opts{'detail'})) {
- foreach my $optName (qw (bounce-detail deferral-detail host-cnt pscrn-detail reject-detail smtp-detail smtpd-warning-detail user-cnt)) {
+ foreach my $optName (qw (bounce-detail deferral-detail expired-detail host-cnt pscrn-detail reject-detail smtp-detail smtpd-warning-detail user-cnt)) {
$opts{$optName} = $opts{'detail'} unless($opts{"$optName"} != -1);
}
}
next unless((($msgYr, $msgMon, $msgDay, $msgHr, $msgMin, $msgSec, $logRmdr) = line_matches_dates($_, $strtDate, $endDate)) == 7);
# Snag first date seen
- ($fromDate{'yr'}, $fromDate{'mon'}, $fromDate{'day'}) = ($msgYr, $msgMon, $msgDay) unless($fromDate{'mon'});
+ ($fromDate{'yr'}, $fromDate{'mon'}, $fromDate{'day'}) = ($msgYr, $msgMon, $msgDay) unless(defined($fromDate{'mon'}));
# Snag last date seen
($thruDate{'yr'}, $thruDate{'mon'}, $thruDate{'day'}) = ($msgYr, $msgMon, $msgDay);
- unless((($cmd, $qid) = $logRmdr =~ m#^(?:postfix|$syslogName)(?:/(?:smtps|submission))?/([^\[:]*).*?: ([^:\s]+)#o) == 2 ||
- (($cmd, $qid) = $logRmdr =~ m#^((?:postfix)(?:-script)?)(?:\[\d+\])?: ([^:\s]+)#o) == 2)
+ unless((($svc, $qid) = $logRmdr =~ m#^(?:postfix|$syslogName)(?:/(?:smtps|submission))?/([^\[:]*).*?: ([^:\s]+)#o) == 2 ||
+ (($svc, $qid) = $logRmdr =~ m#^((?:postfix)(?:-script)?)(?:\[\d+\])?: ([^:\s]+)#o) == 2)
{
print $unProcd "[01]: $_" if $unProcd;
next;
}
# regexp rejects happen in "cleanup"
- if($cmd eq "cleanup" && (my($rejSubTyp, $rejReas, $rejRmdr) = $logRmdr =~
+ if($svc eq "cleanup" && (my($rejSubTyp, $rejReas, $rejRmdr) = $logRmdr =~
/\/cleanup\[\d+\]: .*?\b((?:milter-)?reject|warning|hold|discard): (header|body|END-OF-MESSAGE) (.*)$/) == 3)
{
$rejRmdr =~ s/( from \S+?)?; from=<.*$// unless($opts{'verbose-msg-detail'});
# FIXME: In retrospect: I've no idea where I came up with the magic numbers I pass to this function.
$rejRmdr = string_trimmer($rejRmdr, 64);
if($rejSubTyp eq "reject" or $rejSubTyp eq "milter-reject") {
- ++$rejects{$cmd}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
+ ++$rejects{$svc}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
++$msgsRjctd;
if($opts{'debug'}) {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$rejSubTyp: $rejSubTyp, --\$msgsRcvd");
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$rejSubTyp: $rejSubTyp, --\$msgsRcvd");
++$qidTracker{$qid}{'lateRejects'};
print STDERR "dbg: late reject \$rcvdMsg{$qid}{'size'}: $rcvdMsg{$qid}{'size'}\n" if $rcvdMsg{$qid}{'size'};
}
--$msgsRcvd; # Late Reject: It will have already been counted as "Received," even though it ultimately is not
} elsif($rejSubTyp eq "warning") {
- ++$warns{$cmd}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
+ ++$warns{$svc}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
++$msgsWrnd;
} elsif($rejSubTyp eq "hold") {
- ++$holds{$cmd}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
+ ++$holds{$svc}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
++$msgsHld;
} elsif($rejSubTyp eq "discard") {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$rejSubTyp: $rejSubTyp") if $opts{'debug'};
- ++$discards{$cmd}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$rejSubTyp: $rejSubTyp") if $opts{'debug'};
+ ++$discards{$svc}{$rejReas}{$rejRmdr} unless($opts{'reject-detail'} == 0);
++$msgsDscrdd;
}
delete($rcvdMsg{$qid}); # We're done with this
$warnReas =~ s/(process .+) pid \d+ (exit status \d+)/$1 $2/;
}
$warnReas = string_trimmer($warnReas, 66);
- unless($cmd eq "smtpd" && $opts{'smtpd-warning-detail'} == 0) {
- ++$warnings{$cmd}{$warnReas};
+ unless($svc eq "smtpd" && $opts{'smtpd-warning-detail'} == 0) {
+ ++$warnings{$svc}{$warnReas};
}
} elsif($qid eq 'fatal') {
(my $fatalReas = $logRmdr) =~ s/^.*fatal: //;
$fatalReas = string_trimmer($fatalReas, 66);
- ++$fatals{$cmd}{$fatalReas};
+ ++$fatals{$svc}{$fatalReas};
} elsif($qid eq 'panic') {
(my $panicReas = $logRmdr) =~ s/^.*panic: //;
$panicReas = string_trimmer($panicReas, 66);
- ++$panics{$cmd}{$panicReas};
+ ++$panics{$svc}{$panicReas};
} elsif($qid eq 'reject') {
proc_smtpd_reject($logRmdr, \%rejects, \$msgsRjctd, \$rejPerHr[$msgHr],
\${$msgsPerDay{$revMsgDateStr}}[4]);
} elsif($qid eq 'discard') {
proc_smtpd_reject($logRmdr, \%discards, \$msgsDscrdd, \$rejPerHr[$msgHr],
\${$msgsPerDay{$revMsgDateStr}}[4]);
- } elsif($cmd eq 'master') {
+ } elsif($svc eq 'master') {
++$masterMsgs{(split(/^.*master.*: /, $logRmdr))[1]};
- } elsif($cmd eq 'smtpd' || $cmd eq 'postscreen') {
- if((my ($clientInfo)) = $logRmdr =~ /\[\d+\]: \w+: client=(.+?)(?:,|$)/) {
- #
- # Warning: this code in two places!
- #
+ } elsif($svc eq 'smtpd' || $svc eq 'postscreen' || $svc eq 'pickup') {
+ if((my ($clientInfo)) = $logRmdr =~ /(?|\[\d+\]: \w+: client=(.+?)(?:,|$)|\/(pickup)\[\d+\]: \w+: (?:sender|uid)=)/) {
++$rcvPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[0];
if($opts{'debug'}) {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, ++\$msgsRcvd");
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, ++\$msgsRcvd");
++$qidTracker{$qid}{'rcvdCnt'};
}
++$msgsRcvd;
- $rcvdMsg{$qid}{'whence'} = gimme_domain($clientInfo); # Whence it came
+ $rcvdMsg{$qid}{'whence'} = $clientInfo eq 'pickup'? $clientInfo : gimme_domain($clientInfo); # Whence it came
} elsif(my($rejSubTyp) = $logRmdr =~ /\[\d+\]: \w+: (reject(?:_warning)?|hold|discard): /) {
if($rejSubTyp eq 'reject') {
proc_smtpd_reject($logRmdr, \%rejects, \$msgsRjctd,
# Experimental
unless($qid eq 'NOQUEUE') {
if($opts{'debug'}) {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$rejSubTyp: $rejSubTyp, --\$msgsRcvd");
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$rejSubTyp: $rejSubTyp, --\$msgsRcvd");
++$qidTracker{$qid}{'lateRejects'};
print STDERR "dbg: late reject \$rcvdMsg{$qid}{'size'}: $rcvdMsg{$qid}{'size'}\n" if $rcvdMsg{$qid}{'size'};
}
\$rejPerHr[$msgHr],
\${$msgsPerDay{$revMsgDateStr}}[4]);
} elsif($rejSubTyp eq 'hold') {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$rejSubTyp: $rejSubTyp") if $opts{'debug'};
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$rejSubTyp: $rejSubTyp") if $opts{'debug'};
proc_smtpd_reject($logRmdr, \%holds, \$msgsHld,
\$rejPerHr[$msgHr],
\${$msgsPerDay{$revMsgDateStr}}[4]);
} elsif($rejSubTyp eq 'discard') {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$rejSubTyp: $rejSubTyp") if $opts{'debug'};
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$rejSubTyp: $rejSubTyp") if $opts{'debug'};
proc_smtpd_reject($logRmdr, \%discards, \$msgsDscrdd,
\$rejPerHr[$msgHr],
\${$msgsPerDay{$revMsgDateStr}}[4]);
}
}
else {
- if($cmd eq 'smtpd') {
+ if($svc eq 'smtpd') {
next unless(defined($opts{'smtpd-stats'}));
if($logRmdr =~ /: connect from /) {
$logRmdr =~ /\/smtpd\[(\d+)\]: /;
$smtpdTotTime += $tSecs;
}
}
- } elsif($cmd eq 'postscreen' && (defined $opts{'pscrn-stats'} || $opts{'pscrn-detail'})) {
+ } elsif($svc eq 'postscreen' && (defined $opts{'pscrn-stats'} || $opts{'pscrn-detail'})) {
my ($pscrnAct, $clientIP, $clientPort, $pscrnAddl, $capCnt);
print STDERR "\n" if($opts{'debug'});
if($capCnt == 4) {
print STDERR "Bumping \$pscrnHits{\"$pscrnAct $pscrnAddl\"}{\"$clientIP\"} on \$logRmdr: \"$logRmdr\"\n" if($opts{'debug'});
++$pscrnHits{"$pscrnAct $pscrnAddl"}{$clientIP} if($opts{'pscrn-detail'});
- print STDERR "\$cmd: \"$cmd\", \$logRmdr: \"$logRmdr\"\n" if($opts{'debug'});
+ print STDERR "\$svc: \"$svc\", \$logRmdr: \"$logRmdr\"\n" if($opts{'debug'});
} else {
print STDERR "Bumping \$pscrnHits{\"$pscrnAct\"}{\"$clientIP\"} on \$logRmdr: \"$logRmdr\"\n" if($opts{'debug'});
++$pscrnHits{$pscrnAct}{$clientIP} if($opts{'pscrn-detail'});
- print STDERR "\$cmd: \"$cmd\", \$logRmdr: \"$logRmdr\"\n" if($opts{'debug'});
+ print STDERR "\$svc: \"$svc\", \$logRmdr: \"$logRmdr\"\n" if($opts{'debug'});
}
};
$sizeRcvd += $size;
}
}
- elsif((($addr, $orig_to, $relay, $delay, $status, $toRmdr) = $logRmdr =~
- /to=<([^>]*)>, (?:orig_to=<([^>]*)>, )?relay=([^,]+), (?:conn_use=[^,]+, )?delay=([^,]+), (?:delays=[^,]+, )?(?:dsn=[^,]+, )?status=(\S+)(.*)$/) >= 4)
+ elsif(((
+ $addr,
+ $orig_to,
+ $relay,
+ $delay,
+ $tls, # <— new optional capture
+ $status,
+ $toRmdr
+ ) = $logRmdr =~ m{
+ to=<([^>]*)>,\s+
+ (?:orig_to=<([^>]*)>,\s+)? # optional
+ relay=([^,]+),\s+
+ (?:conn_use=[^,]+,\s+)? # optional
+ delay=([^,]+),\s+
+ (?:delays=[^,]+,\s+)? # optional
+ (?:tls=([^,]+),\s+)? # <— optional tls=... (captures if present)
+ (?:dsn=[^,]+,\s+)? # optional
+ status=(\S+)(.*)$
+ }x) >= 4)
{
$addr = $orig_to if($opts{'use-orig-to'} && $orig_to);
# was it actually forwarded, rather than delivered?
if(my ($newQid) = $toRmdr =~ /\(forwarded as ([^\)]+)\)/) {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$status: $status, forwarded as new qid $1, ++\$msgsFwdd") if $opts{'debug'};
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$status: $status, forwarded as new qid $1, ++\$msgsFwdd") if $opts{'debug'};
++$msgsFwdd;
delete($rcvdMsg{$qid}); # We're done with this
next;
++$dlvPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[1];
if($opts{'debug'}) {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$status: $status, ++\$msgsDlvrd");
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$status: $status, ++\$msgsDlvrd");
++$qidTracker{$qid}{'dlvrdCnt'};
}
++$msgsDlvrd;
$reason .= $moreReason if($moreReason); # ick
# Finally...
$reason = said_string_trimmer($reason, 66);
- ++$deferred{$cmd}{$host}{$reason};
+ ++$deferred{$svc}{$host}{$reason};
} else {
- ++$deferred{$cmd}{$deferredReas};
+ ++$deferred{$svc}{$deferredReas};
}
}
++$dfrPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[2];
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$status: $status, ++\$msgsDfrd") if $opts{'debug'};
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$status: $status, ++\$msgsDfrd") if $opts{'debug'};
++$msgsDfrdCnt;
++$msgsDfrd unless($msgDfrdFlgs{$qid}++);
++${$recipDom{$domAddr}}[MSG_DFRS_I];
{
${$recipDom{$domAddr}}[MSG_DLY_MAX_I] = $delay
}
+ # For "expired" detail reports
+ if($rcvdMsg{$qid}) {
+ my ($relay) = $logRmdr =~ /, relay=([^:]+):/;
+ $rcvdMsg{$qid}{'relay'} = $relay;
+ }
+
} elsif($status eq 'bounced') {
unless($opts{'bounce-detail'} == 0) {
my ($bounceReas) = $logRmdr =~ /, status=bounced \((.+)\)/;
}
++$bncPerHr[$msgHr];
++${$msgsPerDay{$revMsgDateStr}}[3];
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, \$status: $status, ++\$msgsBncd") if $opts{'debug'};
+ push(@{$qidTracker{$qid}{'status'}}, "\$svc: $svc, \$status: $status, ++\$msgsBncd") if $opts{'debug'};
++$msgsBncd;
} else {
print $unProcd "[03]: $_\n" if $unProcd;
}
}
- elsif($cmd eq 'pickup' && $logRmdr =~ /: (sender|uid)=/) {
- #
- # Warning: this code in two places!
- #
- ++$rcvPerHr[$msgHr];
- ++${$msgsPerDay{$revMsgDateStr}}[0];
- if($opts{'debug'}) {
- push(@{$qidTracker{$qid}{'status'}}, "\$cmd: $cmd, ++\$msgsRcvd");
- ++$qidTracker{$qid}{'rcvdCnt'};
- }
- ++$msgsRcvd;
- $rcvdMsg{$qid}{'whence'} = "pickup"; # Whence it came
- }
- elsif($cmd eq 'smtp' && $opts{'smtp-detail'} != 0) {
+ elsif($svc eq 'smtp' && $opts{'smtp-detail'} != 0) {
# Was an IPv6 problem here
if($logRmdr =~ /.* connect to (\S+?): ([^;]+); address \S+ port.*$/) {
++$smtpMsgs{lc($2)}{$1};
print $unProcd "[04]: $_\n" if $unProcd;
}
}
- elsif($cmd =~ /^n?qmgr$/ && $logRmdr =~ /\bremoved$/) {
+ elsif($svc =~ /^n?qmgr$/ && $logRmdr =~ /, status=expired, returned to sender$/) {
+ ++$expired{$rcvdMsg{$qid}{'relay'}};
+ ++$msgsExprd;
+ }
+ elsif($svc =~ /^n?qmgr$/ && $logRmdr =~ /\bremoved$/) {
delete($rcvdMsg{$qid}); # We're done with this
}
else
{
- print $unProcd "[05]: $_\n" if $unProcd;
+ print $unProcd "[05]: (\$svc: \"$svc\") $_\n" if $unProcd;
}
}
}
printf " (%d%s deferrals)", adj_int_units($msgsDfrdCnt) if($msgsDfrdCnt);
print "\n";
printf " %6d%s bounced\n", adj_int_units($msgsBncd);
+printf " %6d%s expired\n", adj_int_units($msgsExprd);
printf " %6d%s rejected (%d%%)\n", adj_int_units($msgsRjctd), $msgsRjctdPct;
printf " %6d%s reject warnings\n", adj_int_units($msgsWrnd);
printf " %6d%s held\n", adj_int_units($msgsHld);
unless($opts{'bounce-detail'} == 0) {
print_nested_hash(\%bounced, "message bounce detail (by relay)", $opts{'bounce-detail'}, $opts{'quiet'});
}
+ unless($opts{'expired-detail'} == 0) {
+ print_nested_hash(\%expired, "message expired detail (by relay)", $opts{'expired-detail'}, $opts{'quiet'});
+ }
unless($opts{'reject-detail'} == 0) {
print_nested_hash(\%rejects, "message reject detail", $opts{'reject-detail'}, $opts{'quiet'});
print_nested_hash(\%warns, "message reject warning detail", $opts{'reject-detail'}, $opts{'quiet'});
$rejReas =~ s/^\d{3} \d\.\d\.\d (Server configuration (?:error|problem));.+$/$1/;
# Condense fqrdns.pcre reports
$rejReas =~ s/^Unverified (Client host rejected: Generic - Please relay via ISP).*$/$1/;
+ # Condense nullMX reports
+ $rejReas =~ s/^(Sender address rejected: Domain) .+ (does not accept mail \(nullMX\)).*$/$1 $2/;
} elsif($rejTyp eq "MAIL") { # *more* special treatment :-( grrrr...
$rejReas =~ s/^\d{3} (?:<.+>: )?([^;:]+)[;:]?.*$/$1/;
} elsif($rejTyp eq "connect") { # and still *more* special treatment :-( *sigh*...