| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Sisimai::Lhost::Postfix; |
|
2
|
47
|
|
|
47
|
|
5741
|
use parent 'Sisimai::Lhost'; |
|
|
47
|
|
|
|
|
98
|
|
|
|
47
|
|
|
|
|
388
|
|
|
3
|
47
|
|
|
47
|
|
3992
|
use v5.26; |
|
|
47
|
|
|
|
|
249
|
|
|
4
|
47
|
|
|
47
|
|
282
|
use strict; |
|
|
47
|
|
|
|
|
125
|
|
|
|
47
|
|
|
|
|
1454
|
|
|
5
|
47
|
|
|
47
|
|
246
|
use warnings; |
|
|
47
|
|
|
|
|
83
|
|
|
|
47
|
|
|
|
|
114161
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
1
|
4
|
sub description { 'Postfix: https://www.postfix.org/' } |
|
8
|
|
|
|
|
|
|
sub inquire { |
|
9
|
|
|
|
|
|
|
# Decode bounce messages from Postfix |
|
10
|
|
|
|
|
|
|
# @param [Hash] mhead Message headers of a bounce email |
|
11
|
|
|
|
|
|
|
# @param [String] mbody Message body of a bounce email |
|
12
|
|
|
|
|
|
|
# @return [Hash] Bounce data list and message/rfc822 part |
|
13
|
|
|
|
|
|
|
# @return [undef] failed to decode or the arguments are missing |
|
14
|
|
|
|
|
|
|
# @since v4.0.0 |
|
15
|
1458
|
|
|
1458
|
1
|
4809
|
my $class = shift; |
|
16
|
1458
|
|
100
|
|
|
5341
|
my $mhead = shift // return undef; |
|
17
|
1457
|
|
100
|
|
|
4105
|
my $mbody = shift // return undef; |
|
18
|
1456
|
|
|
|
|
2626
|
my $match = 0; |
|
19
|
|
|
|
|
|
|
|
|
20
|
1456
|
100
|
|
|
|
6201
|
if( index($mhead->{'subject'}, 'SMTP server: errors from ') > 0 ) { |
|
21
|
|
|
|
|
|
|
# src/smtpd/smtpd_chat.c:|337: post_mail_fprintf(notice, "Subject: %s SMTP server: errors from %s", |
|
22
|
|
|
|
|
|
|
# src/smtpd/smtpd_chat.c:|338: var_mail_name, state->namaddr); |
|
23
|
5
|
|
|
|
|
10
|
$match = 2; |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
} else { |
|
26
|
|
|
|
|
|
|
# Subject: Undelivered Mail Returned to Sender |
|
27
|
1451
|
100
|
|
|
|
6282
|
$match = 1 if $mhead->{'subject'} eq 'Undelivered Mail Returned to Sender'; |
|
28
|
|
|
|
|
|
|
} |
|
29
|
1456
|
100
|
100
|
|
|
7919
|
return undef if $match == 0 || $mhead->{'x-aol-ip'}; |
|
30
|
|
|
|
|
|
|
|
|
31
|
620
|
|
|
|
|
3445
|
require Sisimai::RFC1123; |
|
32
|
620
|
|
|
|
|
2519
|
require Sisimai::SMTP::Reply; |
|
33
|
620
|
|
|
|
|
5199
|
require Sisimai::SMTP::Status; |
|
34
|
620
|
|
|
|
|
2249
|
require Sisimai::SMTP::Command; |
|
35
|
620
|
|
|
|
|
1577
|
state $indicators = __PACKAGE__->INDICATORS; |
|
36
|
620
|
|
|
|
|
1379
|
state $boundaries = ['Content-Type: message/rfc822', 'Content-Type: text/rfc822-headers']; |
|
37
|
620
|
|
|
|
|
1652
|
state $startingof = { |
|
38
|
|
|
|
|
|
|
# Postfix manual - bounce(5) - http://www.postfix.org/bounce.5.html |
|
39
|
|
|
|
|
|
|
'message' => [ |
|
40
|
|
|
|
|
|
|
['The ', 'Postfix '], # The Postfix program, The Postfix on program |
|
41
|
|
|
|
|
|
|
['The ', 'mail system'], # The mail system |
|
42
|
|
|
|
|
|
|
['The ', 'program'], # The pogram |
|
43
|
|
|
|
|
|
|
['This is the', 'Postfix'], # This is the Postfix program |
|
44
|
|
|
|
|
|
|
['This is the', 'mail system'], # This is the mail system at host |
|
45
|
|
|
|
|
|
|
], |
|
46
|
|
|
|
|
|
|
}; |
|
47
|
|
|
|
|
|
|
|
|
48
|
620
|
|
|
|
|
1298
|
my $permessage = {}; # (Hash) Store values of each Per-Message field |
|
49
|
620
|
|
|
|
|
3694
|
my $dscontents = [__PACKAGE__->DELIVERYSTATUS]; my $v = undef; |
|
|
620
|
|
|
|
|
1418
|
|
|
50
|
620
|
|
|
|
|
4402
|
my $emailparts = Sisimai::RFC5322->part($mbody, $boundaries); |
|
51
|
620
|
|
|
|
|
1458
|
my $recipients = 0; # (Integer) The number of 'Final-Recipient' header |
|
52
|
620
|
|
|
|
|
1580
|
my $anotherset = {}; # (Hash) Another error information |
|
53
|
620
|
|
|
|
|
1227
|
my $nomessages = 0; # (Integer) Delivery report unavailable |
|
54
|
620
|
|
|
|
|
1103
|
my @commandset; # (Array) ``in reply to * command'' list |
|
55
|
620
|
|
|
|
|
1242
|
my $p = ''; |
|
56
|
|
|
|
|
|
|
|
|
57
|
620
|
100
|
|
|
|
2485
|
if( $match == 2 ) { |
|
58
|
|
|
|
|
|
|
# The message body starts with 'Transcript of session follows.' |
|
59
|
5
|
|
|
|
|
1098
|
require Sisimai::SMTP::Transcript; |
|
60
|
5
|
|
50
|
|
|
59
|
my $transcript = Sisimai::SMTP::Transcript->rise($emailparts->[0], 'In:', 'Out:') || return undef; |
|
61
|
5
|
50
|
|
|
|
20
|
return undef if scalar @$transcript == 0; |
|
62
|
|
|
|
|
|
|
|
|
63
|
5
|
|
|
|
|
12
|
for my $e ( @$transcript ) { |
|
64
|
|
|
|
|
|
|
# Pick email addresses, error messages, and the last SMTP command. |
|
65
|
40
|
|
66
|
|
|
65
|
$v ||= $dscontents->[-1]; |
|
66
|
40
|
|
|
|
|
64
|
$p = $e->{'response'}; |
|
67
|
|
|
|
|
|
|
|
|
68
|
40
|
100
|
66
|
|
|
138
|
if( $e->{'command'} eq 'EHLO' || $e->{'command'} eq 'HELO' ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# Use the argument of EHLO/HELO command as a value of "lhost" |
|
70
|
5
|
|
|
|
|
14
|
$v->{'lhost'} = $e->{'argument'}; |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
} elsif( $e->{'command'} eq 'MAIL' ) { |
|
73
|
|
|
|
|
|
|
# Set the argument of "MAIL" command to pseudo To: header of the original message |
|
74
|
5
|
50
|
|
|
|
49
|
$emailparts->[1] .= sprintf("To: %s\n", $e->{'argument'}) unless length $emailparts->[1]; |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
} elsif( $e->{'command'} eq 'RCPT' ) { |
|
77
|
|
|
|
|
|
|
# RCPT TO: <...> |
|
78
|
5
|
50
|
|
|
|
39
|
if( $v->{'recipient'} ) { |
|
79
|
|
|
|
|
|
|
# There are multiple recipient addresses in the transcript of session |
|
80
|
0
|
|
|
|
|
0
|
push @$dscontents, __PACKAGE__->DELIVERYSTATUS; |
|
81
|
0
|
|
|
|
|
0
|
$v = $dscontents->[-1]; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
5
|
|
|
|
|
13
|
$v->{'recipient'} = $e->{'argument'}; |
|
84
|
5
|
|
|
|
|
7
|
$recipients++; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
40
|
100
|
|
|
|
129
|
next if int($p->{'reply'}) < 400; |
|
87
|
|
|
|
|
|
|
|
|
88
|
5
|
|
|
|
|
11
|
push @commandset, $e->{'command'}; |
|
89
|
5
|
|
33
|
|
|
64
|
$v->{'diagnosis'} ||= join ' ', $p->{'text'}->@*; |
|
90
|
5
|
|
33
|
|
|
53
|
$v->{'replycode'} ||= $p->{'reply'}; |
|
91
|
5
|
|
33
|
|
|
33
|
$v->{'status'} ||= $p->{'status'}; |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
} else { |
|
94
|
615
|
|
|
|
|
5814
|
my $fieldtable = Sisimai::RFC1894->FIELDTABLE; |
|
95
|
615
|
|
|
|
|
1217
|
my $readcursor = 0; # (Integer) Points the current cursor position |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# The message body is a general bounce mail message of Postfix |
|
98
|
615
|
|
|
|
|
8542
|
for my $e ( split("\n", $emailparts->[0]) ) { |
|
99
|
|
|
|
|
|
|
# Read error messages and delivery status lines from the head of the email to the previous |
|
100
|
|
|
|
|
|
|
# line of the beginning of the original message. |
|
101
|
19708
|
100
|
|
|
|
44143
|
unless( $readcursor ) { |
|
102
|
|
|
|
|
|
|
# Beginning of the bounce message or message/delivery-status part |
|
103
|
3204
|
100
|
|
|
|
6435
|
$readcursor |= $indicators->{'deliverystatus'} if grep { Sisimai::String->aligned(\$e, $_) } $startingof->{'message'}->@*; |
|
|
16020
|
|
|
|
|
40547
|
|
|
104
|
3204
|
|
|
|
|
4874
|
next; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
16504
|
100
|
66
|
|
|
61739
|
next if ($readcursor & $indicators->{'deliverystatus'}) == 0 || $e eq ""; |
|
107
|
|
|
|
|
|
|
|
|
108
|
12463
|
100
|
|
|
|
38256
|
if( my $f = Sisimai::RFC1894->match($e) ) { |
|
109
|
|
|
|
|
|
|
# $e matched with any field defined in RFC3464 |
|
110
|
4310
|
50
|
|
|
|
12464
|
next unless my $o = Sisimai::RFC1894->field($e); |
|
111
|
4310
|
|
|
|
|
12080
|
$v = $dscontents->[-1]; |
|
112
|
|
|
|
|
|
|
|
|
113
|
4310
|
100
|
|
|
|
11439
|
if( $o->[3] eq 'addr' ) { |
|
|
|
100
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# Final-Recipient: rfc822; kijitora@example.jp |
|
115
|
|
|
|
|
|
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp |
|
116
|
1052
|
100
|
|
|
|
4824
|
if( Sisimai::Address->is_emailaddress($o->[2]) ) { |
|
117
|
|
|
|
|
|
|
# The email address is a valid email address, avoid an email address without a |
|
118
|
|
|
|
|
|
|
# valid domain part such as "neko@mailhost". |
|
119
|
1047
|
100
|
|
|
|
3436
|
if( $o->[0] eq 'final-recipient' ) { |
|
120
|
|
|
|
|
|
|
# Final-Recipient: rfc822; kijitora@example.jp |
|
121
|
555
|
100
|
|
|
|
2011
|
if( $v->{'recipient'} ) { |
|
122
|
|
|
|
|
|
|
# There are multiple recipient addresses in the message body. |
|
123
|
15
|
|
|
|
|
98
|
push @$dscontents, __PACKAGE__->DELIVERYSTATUS; |
|
124
|
15
|
|
|
|
|
41
|
$v = $dscontents->[-1]; |
|
125
|
|
|
|
|
|
|
} |
|
126
|
555
|
|
|
|
|
1310
|
$v->{'recipient'} = $o->[2]; |
|
127
|
555
|
|
|
|
|
1753
|
$recipients++; |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
} else { |
|
130
|
|
|
|
|
|
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp |
|
131
|
492
|
|
|
|
|
2148
|
$v->{'alias'} = $o->[2]; |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
} elsif( $o->[3] eq 'code' ) { |
|
135
|
|
|
|
|
|
|
# Diagnostic-Code: SMTP; 550 5.1.1 ... User Unknown |
|
136
|
560
|
|
|
|
|
1590
|
$v->{'spec'} = $o->[1]; |
|
137
|
560
|
100
|
|
|
|
2137
|
$v->{'spec'} = 'SMTP' if uc $v->{'spec'} eq 'X-POSTFIX'; |
|
138
|
560
|
|
|
|
|
2185
|
$v->{'diagnosis'} = $o->[2]; |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
} else { |
|
141
|
|
|
|
|
|
|
# Other DSN fields defined in RFC3464 |
|
142
|
2698
|
50
|
|
|
|
7015
|
next unless exists $fieldtable->{ $o->[0] }; |
|
143
|
2698
|
100
|
100
|
|
|
12101
|
next if $o->[3] eq "host" && Sisimai::RFC1123->is_internethost($o->[2]) == 0; |
|
144
|
2682
|
|
|
|
|
9256
|
$v->{ $fieldtable->{ $o->[0] } } = $o->[2]; |
|
145
|
|
|
|
|
|
|
|
|
146
|
2682
|
100
|
|
|
|
7801
|
next unless $f == 1; |
|
147
|
1089
|
|
|
|
|
5038
|
$permessage->{ $fieldtable->{ $o->[0] } } = $o->[2]; |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
} else { |
|
150
|
|
|
|
|
|
|
# If you do so, please include this problem report. You can |
|
151
|
|
|
|
|
|
|
# delete your own text from the attached returned message. |
|
152
|
|
|
|
|
|
|
# |
|
153
|
|
|
|
|
|
|
# The mail system |
|
154
|
|
|
|
|
|
|
# |
|
155
|
|
|
|
|
|
|
# : host mx.example.co.jp[192.0.2.153] said: 550 |
|
156
|
|
|
|
|
|
|
# 5.1.1 ... User Unknown (in reply to RCPT TO command) |
|
157
|
8153
|
100
|
66
|
|
|
39070
|
if( index($p, 'Diagnostic-Code:') == 0 && index($e, ' ') > -1 ) { |
|
|
|
100
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Continued line of the value of Diagnostic-Code header |
|
159
|
821
|
|
|
|
|
2873
|
$v->{'diagnosis'} .= ' '.Sisimai::String->sweep($e); |
|
160
|
821
|
|
|
|
|
2246
|
$e = 'Diagnostic-Code: '.$e; |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
} elsif( Sisimai::String->aligned(\$e, ['X-Postfix-Sender:', 'rfc822;', '@']) ) { |
|
163
|
|
|
|
|
|
|
# X-Postfix-Sender: rfc822; shironeko@example.org |
|
164
|
523
|
|
|
|
|
4596
|
$emailparts->[1] .= sprintf("X-Postfix-Sender: %s\n", substr($e, index($e, ';') + 1,)); |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
} else { |
|
167
|
|
|
|
|
|
|
# Alternative error message and recipient |
|
168
|
6809
|
100
|
100
|
|
|
38790
|
if( index($e, ' (in reply to ') > -1 || index($e, 'command)') > -1 ) { |
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# 5.1.1 ... User Unknown (in reply to RCPT TO |
|
170
|
603
|
100
|
|
|
|
5172
|
my $cv = Sisimai::SMTP::Command->find($e); push @commandset, $cv if $cv; |
|
|
603
|
|
|
|
|
2194
|
|
|
171
|
603
|
100
|
|
|
|
3378
|
$anotherset->{'diagnosis'} .= ' '.$e if $anotherset->{'diagnosis'}; |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
} elsif( Sisimai::String->aligned(\$e, ['<', '@', '>', '(expanded from <', '):']) ) { |
|
174
|
|
|
|
|
|
|
# (expanded from ): user ... |
|
175
|
40
|
|
|
|
|
104
|
my $p1 = index($e, '> '); |
|
176
|
40
|
|
|
|
|
114
|
my $p2 = index($e, '(expanded from ', $p1); |
|
177
|
40
|
|
|
|
|
3503
|
my $p3 = index($e, '>): ', $p2 + 14); |
|
178
|
40
|
|
|
|
|
500
|
$anotherset->{'recipient'} = Sisimai::Address->s3s4(substr($e, 0, $p1)); |
|
179
|
40
|
|
|
|
|
261
|
$anotherset->{'alias'} = Sisimai::Address->s3s4(substr($e, $p2 + 15, $p3 - $p2 - 15)); |
|
180
|
40
|
|
|
|
|
214
|
$anotherset->{'diagnosis'} = substr($e, $p3 + 3,); |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
} elsif( index($e, '<') == 0 && Sisimai::String->aligned(\$e, ['<', '@', '>:']) ) { |
|
183
|
|
|
|
|
|
|
# : ... |
|
184
|
509
|
|
|
|
|
5760
|
$anotherset->{'recipient'} = Sisimai::Address->s3s4(substr($e, 0, index($e, '>'))); |
|
185
|
509
|
|
|
|
|
2967
|
$anotherset->{'diagnosis'} = substr($e, index($e, '>:') + 2,); |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
} elsif( index($e, '--- Delivery report unavailable ---') > -1 ) { |
|
188
|
|
|
|
|
|
|
# postfix-3.1.4/src/bounce/bounce_notify_util.c |
|
189
|
|
|
|
|
|
|
# bounce_notify_util.c:602|if (bounce_info->log_handle == 0 |
|
190
|
|
|
|
|
|
|
# bounce_notify_util.c:602||| bounce_log_rewind(bounce_info->log_handle)) { |
|
191
|
|
|
|
|
|
|
# bounce_notify_util.c:602|if (IS_FAILURE_TEMPLATE(bounce_info->template)) { |
|
192
|
|
|
|
|
|
|
# bounce_notify_util.c:602| post_mail_fputs(bounce, ""); |
|
193
|
|
|
|
|
|
|
# bounce_notify_util.c:602| post_mail_fputs(bounce, "\t--- delivery report unavailable ---"); |
|
194
|
|
|
|
|
|
|
# bounce_notify_util.c:602| count = 1; /* xxx don't abort */ |
|
195
|
|
|
|
|
|
|
# bounce_notify_util.c:602|} |
|
196
|
|
|
|
|
|
|
# bounce_notify_util.c:602|} else { |
|
197
|
5
|
|
|
|
|
14
|
$nomessages = 1; |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
} else { |
|
200
|
|
|
|
|
|
|
# Get an error message continued from the previous line |
|
201
|
5652
|
100
|
|
|
|
12924
|
next unless $anotherset->{'diagnosis'}; |
|
202
|
1996
|
100
|
|
|
|
7001
|
$anotherset->{'diagnosis'} .= ' '.substr($e, 4,) if index($e, ' ') == 0; |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
} |
|
205
|
|
|
|
|
|
|
} # End of message/delivery-status |
|
206
|
|
|
|
|
|
|
} continue { |
|
207
|
|
|
|
|
|
|
# Save the current line for the next loop |
|
208
|
19708
|
|
|
|
|
47076
|
$p = $e; |
|
209
|
|
|
|
|
|
|
} |
|
210
|
|
|
|
|
|
|
} # End of for() |
|
211
|
|
|
|
|
|
|
|
|
212
|
620
|
100
|
|
|
|
5270
|
unless( $recipients ) { |
|
213
|
|
|
|
|
|
|
# Fallback: get a recipient address from error messages |
|
214
|
75
|
|
|
|
|
233
|
for my $e ( 'recipient', 'alias' ) { |
|
215
|
|
|
|
|
|
|
# Set a valid recipient address picked from $anotherset |
|
216
|
140
|
100
|
|
|
|
1121
|
next unless Sisimai::Address->is_emailaddress($anotherset->{ $e }); |
|
217
|
15
|
|
|
|
|
82
|
$dscontents->[-1]->{'recipient'} = $anotherset->{ $e }; |
|
218
|
15
|
|
|
|
|
29
|
$recipients++; |
|
219
|
15
|
|
|
|
|
31
|
last; |
|
220
|
|
|
|
|
|
|
} |
|
221
|
|
|
|
|
|
|
|
|
222
|
75
|
100
|
|
|
|
251
|
if( $recipients == 0 ) { |
|
223
|
|
|
|
|
|
|
# Get a recipient address from message/rfc822 part if the delivery report was unavailable: |
|
224
|
|
|
|
|
|
|
# '--- Delivery report unavailable ---' |
|
225
|
60
|
|
|
|
|
260
|
my $p1 = index($emailparts->[1], "\nTo: "); |
|
226
|
60
|
|
|
|
|
176
|
my $p2 = index($emailparts->[1], "\n", $p1 + 6); |
|
227
|
60
|
100
|
66
|
|
|
398
|
if( $nomessages && $p1 > 0 ) { |
|
228
|
|
|
|
|
|
|
# Try to get a recipient address from To: field in the original |
|
229
|
|
|
|
|
|
|
# message at message/rfc822 part |
|
230
|
5
|
|
|
|
|
30
|
$dscontents->[-1]->{'recipient'} = Sisimai::Address->s3s4(substr($emailparts->[1], $p1 + 5, $p2 - $p1 - 5)); |
|
231
|
5
|
|
|
|
|
15
|
$recipients++; |
|
232
|
|
|
|
|
|
|
} |
|
233
|
|
|
|
|
|
|
} |
|
234
|
|
|
|
|
|
|
} |
|
235
|
620
|
100
|
|
|
|
2652
|
return undef unless $recipients; |
|
236
|
|
|
|
|
|
|
|
|
237
|
565
|
|
|
|
|
1494
|
for my $e ( @$dscontents ) { |
|
238
|
|
|
|
|
|
|
# Set default values if each value is empty. |
|
239
|
580
|
|
50
|
|
|
3724
|
$e->{ $_ } ||= $permessage->{ $_ } || '' for keys %$permessage; |
|
|
|
|
66
|
|
|
|
|
|
240
|
|
|
|
|
|
|
|
|
241
|
580
|
100
|
|
|
|
2273
|
if( $anotherset->{'diagnosis'} ) { |
|
242
|
|
|
|
|
|
|
# Copy alternative error message |
|
243
|
549
|
|
|
|
|
2251
|
$anotherset->{'diagnosis'} = Sisimai::String->sweep($anotherset->{'diagnosis'}); |
|
244
|
549
|
|
66
|
|
|
2188
|
$e->{'diagnosis'} ||= $anotherset->{'diagnosis'}; |
|
245
|
|
|
|
|
|
|
|
|
246
|
549
|
50
|
|
|
|
3097
|
if( $e->{'diagnosis'} =~ /\A\d+\z/ ) { |
|
247
|
|
|
|
|
|
|
# Override the value of diagnostic code message |
|
248
|
0
|
|
|
|
|
0
|
$e->{'diagnosis'} = $anotherset->{'diagnosis'}; |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
} else { |
|
251
|
|
|
|
|
|
|
# More detailed error message is in "$anotherset" |
|
252
|
549
|
|
|
|
|
1224
|
my $as = ''; # status |
|
253
|
549
|
|
|
|
|
1205
|
my $ar = ''; # replycode |
|
254
|
|
|
|
|
|
|
|
|
255
|
549
|
100
|
|
|
|
7073
|
if( Sisimai::SMTP::Status->is_ambiguous($e->{'status'}) ) { |
|
256
|
|
|
|
|
|
|
# Check the value of D.S.N. in $anotherset is neither an empty nor *.0.0. |
|
257
|
187
|
|
100
|
|
|
1048
|
$as = Sisimai::SMTP::Status->find($anotherset->{'diagnosis'}) || ''; |
|
258
|
187
|
100
|
|
|
|
863
|
$e->{'status'} = $as unless Sisimai::SMTP::Status->is_ambiguous($as); |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
|
|
261
|
549
|
50
|
33
|
|
|
2386
|
if( $e->{'replycode'} eq '' || substr($e->{'replycode'}, -2, 2) eq '00' ) { |
|
262
|
|
|
|
|
|
|
# Check the value of SMTP reply code in $anotherset |
|
263
|
549
|
|
100
|
|
|
4932
|
$ar = Sisimai::SMTP::Reply->find($anotherset->{'diagnosis'}) || ''; |
|
264
|
549
|
100
|
66
|
|
|
3600
|
if( length($ar) > 0 && substr($ar, -2, 2) ne '00' ) { |
|
265
|
|
|
|
|
|
|
# The SMTP reply code is neither an empty nor *00 |
|
266
|
481
|
|
|
|
|
1476
|
$e->{'replycode'} = $ar; |
|
267
|
|
|
|
|
|
|
} |
|
268
|
|
|
|
|
|
|
} |
|
269
|
|
|
|
|
|
|
|
|
270
|
549
|
|
|
|
|
880
|
while(1) { |
|
271
|
|
|
|
|
|
|
# Replace $e->{'diagnosis'} with the value of $anotherset->{'diagnosis'} when |
|
272
|
|
|
|
|
|
|
# all the following conditions have not matched. |
|
273
|
549
|
100
|
|
|
|
3032
|
last if length($as.$ar) == 0; |
|
274
|
481
|
50
|
|
|
|
1673
|
last if length($anotherset->{'diagnosis'}) < length($e->{'diagnosis'}); |
|
275
|
481
|
100
|
|
|
|
2203
|
last if index($anotherset->{'diagnosis'}, $e->{'diagnosis'}) == -1; |
|
276
|
|
|
|
|
|
|
|
|
277
|
449
|
|
|
|
|
1381
|
$e->{'diagnosis'} = $anotherset->{'diagnosis'}; |
|
278
|
449
|
|
|
|
|
1054
|
last; |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
} |
|
281
|
|
|
|
|
|
|
} |
|
282
|
580
|
|
|
|
|
2874
|
$e->{'diagnosis'} = Sisimai::String->sweep($e->{'diagnosis'}); |
|
283
|
580
|
|
100
|
|
|
3538
|
$e->{'command'} = shift @commandset || Sisimai::SMTP::Command->find($e->{'diagnosis'}) || ''; |
|
284
|
580
|
100
|
50
|
|
|
2334
|
$e->{'command'} ||= 'HELO' if index($e->{'diagnosis'}, 'refused to talk to me:') > -1; |
|
285
|
580
|
100
|
100
|
|
|
2961
|
$e->{'spec'} ||= 'SMTP' if Sisimai::String->aligned(\$e->{'diagnosis'}, ['host ', ' said:']); |
|
286
|
|
|
|
|
|
|
} |
|
287
|
565
|
|
|
|
|
6978
|
return {"ds" => $dscontents, "rfc822" => $emailparts->[1]}; |
|
288
|
|
|
|
|
|
|
} |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
1; |
|
291
|
|
|
|
|
|
|
__END__ |