sisimai 4.22.3-java → 4.22.4-java
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sisimai might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/Benchmarks.mk +54 -0
- data/ChangeLog.md +23 -2
- data/Developers.mk +42 -35
- data/Makefile +10 -0
- data/README-JA.md +13 -13
- data/README.md +14 -14
- data/lib/sisimai.rb +12 -18
- data/lib/sisimai/address.rb +64 -82
- data/lib/sisimai/arf.rb +27 -42
- data/lib/sisimai/bite/email.rb +2 -4
- data/lib/sisimai/bite/email/activehunter.rb +12 -17
- data/lib/sisimai/bite/email/amazonses.rb +30 -48
- data/lib/sisimai/bite/email/amazonworkmail.rb +20 -27
- data/lib/sisimai/bite/email/aol.rb +27 -35
- data/lib/sisimai/bite/email/apachejames.rb +17 -28
- data/lib/sisimai/bite/email/bigfoot.rb +20 -33
- data/lib/sisimai/bite/email/biglobe.rb +15 -24
- data/lib/sisimai/bite/email/courier.rb +37 -61
- data/lib/sisimai/bite/email/domino.rb +19 -28
- data/lib/sisimai/bite/email/einsundeins.rb +20 -34
- data/lib/sisimai/bite/email/exchange2003.rb +25 -43
- data/lib/sisimai/bite/email/exchange2007.rb +15 -23
- data/lib/sisimai/bite/email/exim.rb +101 -120
- data/lib/sisimai/bite/email/ezweb.rb +28 -44
- data/lib/sisimai/bite/email/facebook.rb +26 -37
- data/lib/sisimai/bite/email/fml.rb +11 -20
- data/lib/sisimai/bite/email/gmx.rb +17 -27
- data/lib/sisimai/bite/email/google.rb +19 -29
- data/lib/sisimai/bite/email/gsuite.rb +39 -48
- data/lib/sisimai/bite/email/imailserver.rb +25 -39
- data/lib/sisimai/bite/email/interscanmss.rb +19 -26
- data/lib/sisimai/bite/email/kddi.rb +20 -33
- data/lib/sisimai/bite/email/mailfoundry.rb +14 -24
- data/lib/sisimai/bite/email/mailmarshalsmtp.rb +15 -24
- data/lib/sisimai/bite/email/mailru.rb +40 -59
- data/lib/sisimai/bite/email/mcafee.rb +21 -35
- data/lib/sisimai/bite/email/messagelabs.rb +23 -38
- data/lib/sisimai/bite/email/messagingserver.rb +15 -27
- data/lib/sisimai/bite/email/mfilter.rb +19 -28
- data/lib/sisimai/bite/email/mxlogic.rb +31 -49
- data/lib/sisimai/bite/email/notes.rb +16 -24
- data/lib/sisimai/bite/email/office365.rb +29 -38
- data/lib/sisimai/bite/email/opensmtpd.rb +50 -67
- data/lib/sisimai/bite/email/outlook.rb +24 -36
- data/lib/sisimai/bite/email/postfix.rb +33 -42
- data/lib/sisimai/bite/email/qmail.rb +44 -59
- data/lib/sisimai/bite/email/receivingses.rb +28 -36
- data/lib/sisimai/bite/email/sendgrid.rb +28 -37
- data/lib/sisimai/bite/email/sendmail.rb +35 -51
- data/lib/sisimai/bite/email/surfcontrol.rb +17 -25
- data/lib/sisimai/bite/email/userdefined.rb +17 -28
- data/lib/sisimai/bite/email/v5sendmail.rb +32 -41
- data/lib/sisimai/bite/email/verizon.rb +31 -56
- data/lib/sisimai/bite/email/x1.rb +11 -18
- data/lib/sisimai/bite/email/x2.rb +11 -23
- data/lib/sisimai/bite/email/x3.rb +10 -19
- data/lib/sisimai/bite/email/x4.rb +46 -65
- data/lib/sisimai/bite/email/x5.rb +26 -37
- data/lib/sisimai/bite/email/yahoo.rb +11 -19
- data/lib/sisimai/bite/email/yandex.rb +19 -30
- data/lib/sisimai/bite/email/zoho.rb +21 -30
- data/lib/sisimai/bite/json.rb +1 -2
- data/lib/sisimai/bite/json/amazonses.rb +20 -25
- data/lib/sisimai/bite/json/sendgrid.rb +1 -1
- data/lib/sisimai/data.rb +36 -55
- data/lib/sisimai/data/json.rb +3 -3
- data/lib/sisimai/data/yaml.rb +1 -1
- data/lib/sisimai/datetime.rb +5 -21
- data/lib/sisimai/mail.rb +4 -6
- data/lib/sisimai/mail/maildir.rb +1 -1
- data/lib/sisimai/mda.rb +41 -44
- data/lib/sisimai/message.rb +2 -3
- data/lib/sisimai/message/email.rb +42 -52
- data/lib/sisimai/message/json.rb +7 -7
- data/lib/sisimai/mime.rb +25 -23
- data/lib/sisimai/order/email.rb +2 -2
- data/lib/sisimai/order/json.rb +2 -7
- data/lib/sisimai/reason.rb +41 -46
- data/lib/sisimai/reason/blocked.rb +60 -71
- data/lib/sisimai/reason/contenterror.rb +4 -8
- data/lib/sisimai/reason/delivered.rb +1 -3
- data/lib/sisimai/reason/exceedlimit.rb +10 -20
- data/lib/sisimai/reason/expired.rb +5 -9
- data/lib/sisimai/reason/feedback.rb +1 -3
- data/lib/sisimai/reason/filtered.rb +19 -38
- data/lib/sisimai/reason/hasmoved.rb +5 -8
- data/lib/sisimai/reason/hostunknown.rb +11 -18
- data/lib/sisimai/reason/mailboxfull.rb +14 -24
- data/lib/sisimai/reason/mailererror.rb +3 -5
- data/lib/sisimai/reason/mesgtoobig.rb +15 -25
- data/lib/sisimai/reason/networkerror.rb +8 -10
- data/lib/sisimai/reason/norelaying.rb +9 -14
- data/lib/sisimai/reason/notaccept.rb +9 -21
- data/lib/sisimai/reason/onhold.rb +3 -8
- data/lib/sisimai/reason/policyviolation.rb +8 -10
- data/lib/sisimai/reason/rejected.rb +36 -49
- data/lib/sisimai/reason/securityerror.rb +11 -13
- data/lib/sisimai/reason/spamdetected.rb +23 -37
- data/lib/sisimai/reason/suspend.rb +9 -10
- data/lib/sisimai/reason/syntaxerror.rb +3 -4
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +2 -4
- data/lib/sisimai/reason/toomanyconn.rb +17 -30
- data/lib/sisimai/reason/undefined.rb +1 -3
- data/lib/sisimai/reason/userunknown.rb +28 -38
- data/lib/sisimai/reason/vacation.rb +4 -6
- data/lib/sisimai/reason/virusdetected.rb +4 -6
- data/lib/sisimai/rfc2606.rb +1 -2
- data/lib/sisimai/rfc3464.rb +87 -101
- data/lib/sisimai/rfc3834.rb +29 -39
- data/lib/sisimai/rfc5322.rb +17 -24
- data/lib/sisimai/rhost.rb +10 -7
- data/lib/sisimai/rhost/exchangeonline.rb +124 -255
- data/lib/sisimai/rhost/franceptt.rb +2 -2
- data/lib/sisimai/rhost/godaddy.rb +12 -25
- data/lib/sisimai/rhost/googleapps.rb +82 -183
- data/lib/sisimai/smtp.rb +4 -4
- data/lib/sisimai/smtp/error.rb +8 -8
- data/lib/sisimai/smtp/reply.rb +1 -1
- data/lib/sisimai/smtp/status.rb +1 -0
- data/lib/sisimai/string.rb +5 -7
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/README.md +1 -1
- data/set-of-emails/maildir/bsd/README.md +50 -50
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +4 -4
- data/lib/sisimai/skeleton.rb +0 -43
@@ -6,55 +6,42 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Exim.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:from => %r/\AMail Delivery System/,
|
14
|
-
:subject => %r{(?:
|
15
|
-
Mail[ ]delivery[ ]failed(:[ ]returning[ ]message[ ]to[ ]sender)?
|
16
|
-
|Warning:[ ]message[ ].+[ ]delayed[ ]+
|
17
|
-
|Delivery[ ]Status[ ]Notification
|
18
|
-
|Mail[ ]failure
|
19
|
-
|Message[ ]frozen
|
20
|
-
|error[(]s[)][ ]in[ ]forwarding[ ]or[ ]filtering
|
21
|
-
)
|
22
|
-
}x,
|
23
|
-
# :'message-id' => %r/\A[<]\w+[-]\w+[-]\w+[@].+\z/,
|
24
|
-
# Message-Id: <E1P1YNN-0003AD-Ga@example.org>
|
9
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
StartingOf = {
|
11
|
+
deliverystatus: ['Content-type: message/delivery-status'],
|
12
|
+
endof: ['__END_OF_EMAIL_MESSAGE__'],
|
25
13
|
}.freeze
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:rfc822 => %r{\A(?:
|
14
|
+
MarkingsOf = {
|
15
|
+
# Error text regular expressions which defined in exim/src/deliver.c
|
16
|
+
#
|
17
|
+
# deliver.c:6292| fprintf(f,
|
18
|
+
# deliver.c:6293|"This message was created automatically by mail delivery software.\n");
|
19
|
+
# deliver.c:6294| if (to_sender)
|
20
|
+
# deliver.c:6295| {
|
21
|
+
# deliver.c:6296| fprintf(f,
|
22
|
+
# deliver.c:6297|"\nA message that you sent could not be delivered to one or more of its\n"
|
23
|
+
# deliver.c:6298|"recipients. This is a permanent error. The following address(es) failed:\n");
|
24
|
+
# deliver.c:6299| }
|
25
|
+
# deliver.c:6300| else
|
26
|
+
# deliver.c:6301| {
|
27
|
+
# deliver.c:6302| fprintf(f,
|
28
|
+
# deliver.c:6303|"\nA message sent by\n\n <%s>\n\n"
|
29
|
+
# deliver.c:6304|"could not be delivered to one or more of its recipients. The following\n"
|
30
|
+
# deliver.c:6305|"address(es) failed:\n", sender_address);
|
31
|
+
# deliver.c:6306| }
|
32
|
+
#
|
33
|
+
# deliver.c:6423| if (bounce_return_body) fprintf(f,
|
34
|
+
# deliver.c:6424|"------ This is a copy of the message, including all the headers. ------\n");
|
35
|
+
# deliver.c:6425| else fprintf(f,
|
36
|
+
# deliver.c:6426|"------ This is a copy of the message's headers. ------\n");
|
37
|
+
alias: %r/\A([ ]+an undisclosed address)\z/,
|
38
|
+
frozen: %r/\AMessage .+ (?:has been frozen|was frozen on arrival)/,
|
39
|
+
rfc822: %r{\A(?:
|
53
40
|
[-]+[ ]This[ ]is[ ]a[ ]copy[ ]of[ ](?:the|your)[ ]message.+headers[.][ ][-]+
|
54
41
|
|Content-Type:[ ]*message/rfc822
|
55
42
|
)\z
|
56
43
|
}x,
|
57
|
-
:
|
44
|
+
message: %r{\A(?>
|
58
45
|
This[ ]message[ ]was[ ]created[ ]automatically[ ]by[ ]mail[ ]delivery[ ]software[.]
|
59
46
|
|A[ ]message[ ]that[ ]you[ ]sent[ ]was[ ]rejected[ ]by[ ]the[ ]local[ ]scanning[ ]code
|
60
47
|
|A[ ]message[ ]that[ ]you[ ]sent[ ]contained[ ]one[ ]or[ ]more[ ]recipient[ ]addresses[ ]
|
@@ -62,11 +49,9 @@ module Sisimai::Bite::Email
|
|
62
49
|
|The[ ].+[ ]router[ ]encountered[ ]the[ ]following[ ]error[(]s[)]:
|
63
50
|
)
|
64
51
|
}x,
|
65
|
-
:deliverystatus => %r|\AContent-type: message/delivery-status|,
|
66
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
67
52
|
}.freeze
|
68
53
|
|
69
|
-
|
54
|
+
ReCommands = [
|
70
55
|
# transports/smtp.c:564| *message = US string_sprintf("SMTP error from remote mail server after %s%s: "
|
71
56
|
# transports/smtp.c:837| string_sprintf("SMTP error from remote mail server after RCPT TO:<%s>: "
|
72
57
|
%r/SMTP error from remote (?:mail server|mailer) after ([A-Za-z]{4})/,
|
@@ -74,11 +59,10 @@ module Sisimai::Bite::Email
|
|
74
59
|
%r/LMTP error after ([A-Za-z]{4})/,
|
75
60
|
%r/LMTP error after end of ([A-Za-z]{4})/,
|
76
61
|
].freeze
|
77
|
-
|
78
|
-
|
79
|
-
ReFailure = {
|
62
|
+
ReFailures = {
|
63
|
+
# find exim/ -type f -exec grep 'message = US' {} /dev/null \;
|
80
64
|
# route.c:1158| DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n");
|
81
|
-
userunknown: %r/user
|
65
|
+
userunknown: %r/user not found/,
|
82
66
|
# transports/smtp.c:3524| addr->message = US"all host address lookups failed permanently";
|
83
67
|
# routers/dnslookup.c:331| addr->message = US"all relevant MX records point to non-existent hosts";
|
84
68
|
# route.c:1826| uschar *message = US"Unrouteable address";
|
@@ -93,7 +77,7 @@ module Sisimai::Bite::Email
|
|
93
77
|
# transports/appendfile.c:2567| addr->user_message = US"mailbox is full";
|
94
78
|
# transports/appendfile.c:3049| addr->message = string_sprintf("mailbox is full "
|
95
79
|
# transports/appendfile.c:3050| "(quota exceeded while writing to file %s)", filename);
|
96
|
-
mailboxfull: %r/(?:mailbox
|
80
|
+
mailboxfull: %r/(?:mailbox is full:?|error: quota exceed)/,
|
97
81
|
# routers/dnslookup.c:328| addr->message = US"an MX or SRV record indicated no SMTP service";
|
98
82
|
# transports/smtp.c:3502| addr->message = US"no host found for existing SMTP connection";
|
99
83
|
notaccept: %r{(?:
|
@@ -122,7 +106,7 @@ module Sisimai::Bite::Email
|
|
122
106
|
)
|
123
107
|
}x,
|
124
108
|
# deliver.c:5425| new->message = US"Too many \"Received\" headers - suspected mail loop";
|
125
|
-
contenterror: %r/Too
|
109
|
+
contenterror: %r/Too many ["]Received["] headers/,
|
126
110
|
}.freeze
|
127
111
|
|
128
112
|
# retry.c:902| addr->message = (addr->message == NULL)? US"retry timeout exceeded" :
|
@@ -134,7 +118,7 @@ module Sisimai::Bite::Email
|
|
134
118
|
# deliver.c:7586| "Message %s has been frozen%s.\nThe sender is <%s>.\n", message_id,
|
135
119
|
# receive.c:4021| moan_tell_someone(freeze_tell, NULL, US"Message frozen on arrival",
|
136
120
|
# receive.c:4022| "Message %s was frozen on arrival by %s.\nThe sender is <%s>.\n",
|
137
|
-
|
121
|
+
ReDelaying = %r{(?:
|
138
122
|
retry[ ]timeout[ ]exceeded
|
139
123
|
|No[ ]action[ ]is[ ]required[ ]on[ ]your[ ]part
|
140
124
|
|retry[ ]time[ ]not[ ]reached[ ]for[ ]any[ ]host[ ]after[ ]a[ ]long[ ]failure[ ]period
|
@@ -143,12 +127,10 @@ module Sisimai::Bite::Email
|
|
143
127
|
|Message[ ].+[ ](?:has[ ]been[ ]frozen|was[ ]frozen[ ]on[ ]arrival[ ]by[ ])
|
144
128
|
)
|
145
129
|
}x
|
146
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
147
130
|
|
148
131
|
def description; return 'Exim'; end
|
149
132
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
150
133
|
def headerlist; return ['X-Failed-Recipients']; end
|
151
|
-
def pattern; return Re0; end
|
152
134
|
|
153
135
|
# Parse bounce messages from Exim
|
154
136
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -164,9 +146,19 @@ module Sisimai::Bite::Email
|
|
164
146
|
def scan(mhead, mbody)
|
165
147
|
return nil unless mhead
|
166
148
|
return nil unless mbody
|
167
|
-
|
168
|
-
|
169
|
-
return nil
|
149
|
+
|
150
|
+
# :'message-id' => %r/\A[<]\w+[-]\w+[-]\w+[@].+\z/,
|
151
|
+
return nil if mhead['from'] =~ /[@].+[.]mail[.]ru[>]?/
|
152
|
+
return nil unless mhead['from'].start_with?('Mail Delivery System')
|
153
|
+
return nil unless mhead['subject'] =~ %r{(?:
|
154
|
+
Mail[ ]delivery[ ]failed(:[ ]returning[ ]message[ ]to[ ]sender)?
|
155
|
+
|Warning:[ ]message[ ].+[ ]delayed[ ]+
|
156
|
+
|Delivery[ ]Status[ ]Notification
|
157
|
+
|Mail[ ]failure
|
158
|
+
|Message[ ]frozen
|
159
|
+
|error[(]s[)][ ]in[ ]forwarding[ ]or[ ]filtering
|
160
|
+
)
|
161
|
+
}x
|
170
162
|
|
171
163
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
172
164
|
hasdivided = mbody.split("\n")
|
@@ -188,20 +180,20 @@ module Sisimai::Bite::Email
|
|
188
180
|
boundary00 = Sisimai::MIME.boundary(mhead['content-type']) || ''
|
189
181
|
end
|
190
182
|
|
191
|
-
hasdivided.
|
192
|
-
break if e
|
183
|
+
while e = hasdivided.shift do
|
184
|
+
break if e == StartingOf[:endof][0]
|
193
185
|
|
194
186
|
if readcursor.zero?
|
195
187
|
# Beginning of the bounce message or delivery status part
|
196
|
-
if e =~
|
188
|
+
if e =~ MarkingsOf[:message]
|
197
189
|
readcursor |= Indicators[:deliverystatus]
|
198
|
-
next unless e =~
|
190
|
+
next unless e =~ MarkingsOf[:frozen]
|
199
191
|
end
|
200
192
|
end
|
201
193
|
|
202
194
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
203
195
|
# Beginning of the original message part
|
204
|
-
if e =~
|
196
|
+
if e =~ MarkingsOf[:rfc822]
|
205
197
|
readcursor |= Indicators[:'message-rfc822']
|
206
198
|
next
|
207
199
|
end
|
@@ -215,7 +207,6 @@ module Sisimai::Bite::Email
|
|
215
207
|
next
|
216
208
|
end
|
217
209
|
rfc822list << e
|
218
|
-
|
219
210
|
else
|
220
211
|
# Before "message/rfc822"
|
221
212
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -233,7 +224,7 @@ module Sisimai::Bite::Email
|
|
233
224
|
|
234
225
|
if cv = e.match(/\A[ \t]{2}([^ \t]+[@][^ \t]+[.]?[a-zA-Z]+)(:.+)?\z/) ||
|
235
226
|
e.match(/\A[ \t]{2}[^ \t]+[@][^ \t]+[.][a-zA-Z]+[ ]<(.+?[@].+?)>:.+\z/) ||
|
236
|
-
e.match(
|
227
|
+
e.match(MarkingsOf[:alias])
|
237
228
|
# kijitora@example.jp
|
238
229
|
# sabineko@example.jp: forced freeze
|
239
230
|
# mikeneko@example.jp <nekochan@example.org>: ...
|
@@ -271,49 +262,46 @@ module Sisimai::Bite::Email
|
|
271
262
|
# pipe to |/bin/echo "Some pipe output"
|
272
263
|
# generated by userx@myhost.test.ex
|
273
264
|
v['alias'] = cv[1]
|
274
|
-
|
275
265
|
else
|
276
266
|
next if e.empty?
|
277
267
|
|
278
|
-
if e =~
|
268
|
+
if e =~ MarkingsOf[:frozen]
|
279
269
|
# Message *** has been frozen by the system filter.
|
280
270
|
# Message *** was frozen on arrival by ACL.
|
281
271
|
v['alterrors'] ||= ''
|
282
|
-
v['alterrors']
|
283
|
-
|
272
|
+
v['alterrors'] << e + ' '
|
284
273
|
else
|
285
274
|
if boundary00.size > 0
|
286
275
|
# --NNNNNNNNNN-eximdsn-MMMMMMMMMM
|
287
276
|
# Content-type: message/delivery-status
|
288
277
|
# ...
|
289
|
-
if cv = e.match(/\
|
278
|
+
if cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
290
279
|
# Reporting-MTA: dns; mx.example.jp
|
291
280
|
v['lhost'] = cv[1]
|
292
281
|
|
293
|
-
elsif cv = e.match(/\
|
282
|
+
elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
|
294
283
|
# Action: failed
|
295
284
|
v['action'] = cv[1].downcase
|
296
285
|
|
297
|
-
elsif cv = e.match(/\
|
286
|
+
elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
|
298
287
|
# Status: 5.0.0
|
299
288
|
v['status'] = cv[1]
|
300
289
|
|
301
|
-
elsif cv = e.match(/\
|
290
|
+
elsif cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
|
302
291
|
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
303
292
|
v['spec'] = cv[1].upcase
|
304
293
|
v['diagnosis'] = cv[2]
|
305
294
|
|
306
|
-
elsif cv = e.match(/\
|
295
|
+
elsif cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*(.+)\z/)
|
307
296
|
# Final-Recipient: rfc822;|/bin/echo "Some pipe output"
|
308
|
-
v['spec'] ||= cv[1]
|
309
|
-
|
297
|
+
v['spec'] ||= cv[1].include?('@') ? 'SMTP' : 'X-UNIX'
|
310
298
|
else
|
311
299
|
# Error message ?
|
312
300
|
if havepassed[:deliverystatus].zero?
|
313
301
|
# Content-type: message/delivery-status
|
314
|
-
havepassed[:deliverystatus] = 1 if e
|
302
|
+
havepassed[:deliverystatus] = 1 if e.start_with?(StartingOf[:deliverystatus][0])
|
315
303
|
v['alterrors'] ||= ''
|
316
|
-
v['alterrors']
|
304
|
+
v['alterrors'] << e + ' ' if e.start_with?(' ')
|
317
305
|
end
|
318
306
|
end
|
319
307
|
else
|
@@ -321,8 +309,7 @@ module Sisimai::Bite::Email
|
|
321
309
|
# Error message
|
322
310
|
next unless e.size
|
323
311
|
v['diagnosis'] ||= ''
|
324
|
-
v['diagnosis']
|
325
|
-
|
312
|
+
v['diagnosis'] << e + ' '
|
326
313
|
else
|
327
314
|
# Error message when email address above does not include '@'
|
328
315
|
# and domain part.
|
@@ -331,9 +318,9 @@ module Sisimai::Bite::Email
|
|
331
318
|
# generated by kijitora@example.com
|
332
319
|
v['diagnosis'] = e
|
333
320
|
else
|
334
|
-
next unless e
|
321
|
+
next unless e.start_with?(' ')
|
335
322
|
v['alterrors'] ||= ''
|
336
|
-
v['alterrors']
|
323
|
+
v['alterrors'] << e + ' '
|
337
324
|
end
|
338
325
|
|
339
326
|
end
|
@@ -349,12 +336,11 @@ module Sisimai::Bite::Email
|
|
349
336
|
# Replace the recipient address with the value of "alias"
|
350
337
|
next unless q['alias']
|
351
338
|
next unless q['alias'].size > 0
|
352
|
-
if q['recipient'].empty? || q['recipient']
|
339
|
+
if q['recipient'].empty? || q['recipient'].include?('@') == false
|
353
340
|
# The value of "recipient" is empty or does not include "@"
|
354
341
|
q['recipient'] = q['alias']
|
355
342
|
end
|
356
343
|
end
|
357
|
-
|
358
344
|
else
|
359
345
|
# Fallback for getting recipient addresses
|
360
346
|
if mhead['x-failed-recipients']
|
@@ -367,7 +353,7 @@ module Sisimai::Bite::Email
|
|
367
353
|
end
|
368
354
|
recipients = rcptinhead.size
|
369
355
|
|
370
|
-
rcptinhead.
|
356
|
+
while e = rcptinhead.shift do
|
371
357
|
# Insert each recipient address into dscontents
|
372
358
|
dscontents[-1]['recipient'] = e
|
373
359
|
next if dscontents.size == recipients
|
@@ -388,7 +374,6 @@ module Sisimai::Bite::Email
|
|
388
374
|
require 'sisimai/string'
|
389
375
|
require 'sisimai/smtp/reply'
|
390
376
|
require 'sisimai/smtp/status'
|
391
|
-
|
392
377
|
dscontents.map do |e|
|
393
378
|
# Set default values if each value is empty.
|
394
379
|
e['agent'] = self.smtpagent
|
@@ -412,33 +397,30 @@ module Sisimai::Bite::Email
|
|
412
397
|
e['diagnosis'] = dscontents[0]['diagnosis'] || ''
|
413
398
|
e['spec'] ||= dscontents[0]['spec']
|
414
399
|
|
415
|
-
if dscontents[0]['alterrors']
|
400
|
+
if dscontents[0]['alterrors'].to_s.size > 0
|
416
401
|
# The value of "alterrors" is also copied
|
417
402
|
e['alterrors'] = dscontents[0]['alterrors']
|
418
403
|
end
|
419
404
|
end
|
420
405
|
end
|
421
406
|
|
422
|
-
if e['alterrors']
|
407
|
+
if e['alterrors'].to_s.size > 0
|
423
408
|
# Copy alternative error message
|
424
409
|
if e['diagnosis'].nil? || e['diagnosis'].empty?
|
425
410
|
e['diagnosis'] = e['alterrors']
|
426
411
|
end
|
427
412
|
|
428
|
-
if e['diagnosis']
|
413
|
+
if e['diagnosis'].start_with?('-') || e['diagnosis'].end_with?('__')
|
429
414
|
# Override the value of diagnostic code message
|
430
415
|
e['diagnosis'] = e['alterrors'] if e['alterrors'].size > 0
|
431
|
-
|
432
416
|
else
|
433
417
|
# Check the both value and try to match
|
434
418
|
if e['diagnosis'].size < e['alterrors'].size
|
435
419
|
# Check the value of alterrors
|
436
420
|
rxdiagnosis = %r/e['diagnosis']/i
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
e['diagnosis'] = e['alterrors']
|
441
|
-
end
|
421
|
+
# Override the value of diagnostic code message because
|
422
|
+
# the value of alterrors includes the value of diagnosis.
|
423
|
+
e['diagnosis'] = e['alterrors'] if e['alterrors'] =~ rxdiagnosis
|
442
424
|
end
|
443
425
|
end
|
444
426
|
e.delete('alterrors')
|
@@ -454,16 +436,14 @@ module Sisimai::Bite::Email
|
|
454
436
|
end
|
455
437
|
|
456
438
|
unless e['rhost']
|
457
|
-
|
458
|
-
|
459
|
-
e['rhost'] = Sisimai::RFC5322.received(mhead['received'][-1]).pop
|
460
|
-
end
|
439
|
+
# Get localhost and remote host name from Received header.
|
440
|
+
e['rhost'] = Sisimai::RFC5322.received(mhead['received'][-1]).pop if mhead['received'].size > 0
|
461
441
|
end
|
462
442
|
end
|
463
443
|
|
464
444
|
unless e['command']
|
465
445
|
# Get the SMTP command name for the session
|
466
|
-
|
446
|
+
ReCommands.each do |r|
|
467
447
|
# Verify each regular expression of SMTP commands
|
468
448
|
if cv = e['diagnosis'].match(r)
|
469
449
|
e['command'] = cv[1].upcase
|
@@ -472,26 +452,25 @@ module Sisimai::Bite::Email
|
|
472
452
|
end
|
473
453
|
|
474
454
|
# Detect the reason of bounce
|
475
|
-
if e['command']
|
455
|
+
if %w[HELO EHLO].index(e['command'])
|
476
456
|
# HELO | Connected to 192.0.2.135 but my name was rejected.
|
477
457
|
e['reason'] = 'blocked'
|
478
458
|
|
479
459
|
elsif e['command'] == 'MAIL'
|
480
460
|
# MAIL | Connected to 192.0.2.135 but sender was rejected.
|
481
461
|
e['reason'] = 'onhold'
|
482
|
-
|
483
462
|
else
|
484
463
|
# Verify each regular expression of session errors
|
485
|
-
|
464
|
+
ReFailures.each_key do |r|
|
486
465
|
# Check each regular expression
|
487
|
-
next unless e['diagnosis'] =~
|
466
|
+
next unless e['diagnosis'] =~ ReFailures[r]
|
488
467
|
e['reason'] = r.to_s
|
489
468
|
break
|
490
469
|
end
|
491
470
|
|
492
471
|
unless e['reason']
|
493
472
|
# The reason "expired"
|
494
|
-
e['reason'] = 'expired' if e['diagnosis'] =~
|
473
|
+
e['reason'] = 'expired' if e['diagnosis'] =~ ReDelaying
|
495
474
|
end
|
496
475
|
end
|
497
476
|
end
|
@@ -511,25 +490,27 @@ module Sisimai::Bite::Email
|
|
511
490
|
r1 = 0 # First character of SMTP reply code as integer
|
512
491
|
|
513
492
|
# "Status:" field did not exist in the bounce message
|
514
|
-
|
493
|
+
while true
|
494
|
+
break unless sv.empty?
|
495
|
+
break if rv.empty?
|
496
|
+
|
515
497
|
# Check SMTP reply code
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
sv = Sisimai::SMTP::Status.code(e['reason'], false)
|
526
|
-
end
|
498
|
+
# Generate pseudo DSN code from SMTP reply code
|
499
|
+
r1 = rv[0, 1].to_i
|
500
|
+
if r1 == 4
|
501
|
+
# Get the internal DSN(temporary error)
|
502
|
+
sv = Sisimai::SMTP::Status.code(e['reason'], true)
|
503
|
+
|
504
|
+
elsif r1 == 5
|
505
|
+
# Get the internal DSN(permanent error)
|
506
|
+
sv = Sisimai::SMTP::Status.code(e['reason'], false)
|
527
507
|
end
|
508
|
+
break
|
528
509
|
end
|
529
510
|
|
530
511
|
s1 = sv[0, 1].to_i if sv.size > 0
|
531
512
|
v1 = s1 + r1
|
532
|
-
v1
|
513
|
+
v1 << e['status'][0, 1].to_i if e['status']
|
533
514
|
|
534
515
|
if v1 > 0
|
535
516
|
# Status or SMTP reply code exists
|
@@ -537,7 +518,7 @@ module Sisimai::Bite::Email
|
|
537
518
|
e['status'] = sv if r1 > 0
|
538
519
|
else
|
539
520
|
# Neither Status nor SMTP reply code exist
|
540
|
-
sv = if e['reason']
|
521
|
+
sv = if %w[expired mailboxfull].include?(e['reason'])
|
541
522
|
# Set pseudo DSN (temporary error)
|
542
523
|
Sisimai::SMTP::Status.code(e['reason'], true)
|
543
524
|
else
|