sisimai 4.24.1-java → 4.25.0-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 +3 -2
- data/ANALYTICAL-PRECISION +16 -25
- data/ChangeLog.md +41 -0
- data/Developers.mk +2 -2
- data/README-JA.md +13 -13
- data/README.md +13 -13
- data/lib/sisimai.rb +3 -7
- data/lib/sisimai/address.rb +25 -41
- data/lib/sisimai/arf.rb +58 -59
- data/lib/sisimai/bite.rb +0 -1
- data/lib/sisimai/bite/email.rb +7 -7
- data/lib/sisimai/bite/email/activehunter.rb +4 -3
- data/lib/sisimai/bite/email/amavis.rb +133 -0
- data/lib/sisimai/bite/email/amazonses.rb +53 -87
- data/lib/sisimai/bite/email/amazonworkmail.rb +51 -57
- data/lib/sisimai/bite/email/aol.rb +50 -76
- data/lib/sisimai/bite/email/apachejames.rb +2 -2
- data/lib/sisimai/bite/email/bigfoot.rb +47 -74
- data/lib/sisimai/bite/email/biglobe.rb +8 -9
- data/lib/sisimai/bite/email/courier.rb +56 -101
- data/lib/sisimai/bite/email/domino.rb +7 -8
- data/lib/sisimai/bite/email/einsundeins.rb +4 -5
- data/lib/sisimai/bite/email/exchange2003.rb +21 -22
- data/lib/sisimai/bite/email/exchange2007.rb +26 -28
- data/lib/sisimai/bite/email/exim.rb +48 -47
- data/lib/sisimai/bite/email/ezweb.rb +24 -36
- data/lib/sisimai/bite/email/facebook.rb +54 -79
- data/lib/sisimai/bite/email/fml.rb +10 -10
- data/lib/sisimai/bite/email/gmx.rb +6 -6
- data/lib/sisimai/bite/email/google.rb +12 -13
- data/lib/sisimai/bite/email/gsuite.rb +80 -108
- data/lib/sisimai/bite/email/imailserver.rb +16 -16
- data/lib/sisimai/bite/email/interscanmss.rb +4 -6
- data/lib/sisimai/bite/email/kddi.rb +9 -11
- data/lib/sisimai/bite/email/mailfoundry.rb +2 -2
- data/lib/sisimai/bite/email/mailmarshalsmtp.rb +2 -2
- data/lib/sisimai/bite/email/mailru.rb +12 -13
- data/lib/sisimai/bite/email/mcafee.rb +31 -25
- data/lib/sisimai/bite/email/messagelabs.rb +48 -87
- data/lib/sisimai/bite/email/messagingserver.rb +9 -10
- data/lib/sisimai/bite/email/mfilter.rb +16 -16
- data/lib/sisimai/bite/email/mxlogic.rb +11 -11
- data/lib/sisimai/bite/email/notes.rb +5 -6
- data/lib/sisimai/bite/email/office365.rb +25 -42
- data/lib/sisimai/bite/email/opensmtpd.rb +8 -8
- data/lib/sisimai/bite/email/outlook.rb +49 -67
- data/lib/sisimai/bite/email/postfix.rb +78 -112
- data/lib/sisimai/bite/email/qmail.rb +23 -23
- data/lib/sisimai/bite/email/receivingses.rb +53 -86
- data/lib/sisimai/bite/email/sendgrid.rb +65 -84
- data/lib/sisimai/bite/email/sendmail.rb +89 -117
- data/lib/sisimai/bite/email/surfcontrol.rb +15 -18
- data/lib/sisimai/bite/email/userdefined.rb +1 -1
- data/lib/sisimai/bite/email/v5sendmail.rb +3 -4
- data/lib/sisimai/bite/email/verizon.rb +7 -8
- data/lib/sisimai/bite/email/x1.rb +2 -2
- data/lib/sisimai/bite/email/x2.rb +2 -2
- data/lib/sisimai/bite/email/x3.rb +3 -3
- data/lib/sisimai/bite/email/x4.rb +22 -22
- data/lib/sisimai/bite/email/x5.rb +40 -49
- data/lib/sisimai/bite/email/yahoo.rb +3 -3
- data/lib/sisimai/bite/email/yandex.rb +54 -82
- data/lib/sisimai/bite/email/zoho.rb +6 -6
- data/lib/sisimai/bite/json/amazonses.rb +20 -20
- data/lib/sisimai/bite/json/sendgrid.rb +2 -2
- data/lib/sisimai/data.rb +27 -40
- data/lib/sisimai/datetime.rb +146 -162
- data/lib/sisimai/mda.rb +30 -31
- data/lib/sisimai/message/email.rb +83 -123
- data/lib/sisimai/message/json.rb +2 -4
- data/lib/sisimai/mime.rb +31 -34
- data/lib/sisimai/order/email.rb +23 -22
- data/lib/sisimai/reason.rb +61 -61
- data/lib/sisimai/reason/blocked.rb +139 -135
- data/lib/sisimai/reason/contenterror.rb +11 -10
- data/lib/sisimai/reason/exceedlimit.rb +4 -4
- data/lib/sisimai/reason/expired.rb +20 -20
- data/lib/sisimai/reason/filtered.rb +19 -18
- data/lib/sisimai/reason/hasmoved.rb +3 -3
- data/lib/sisimai/reason/hostunknown.rb +19 -19
- data/lib/sisimai/reason/mailboxfull.rb +49 -49
- data/lib/sisimai/reason/mailererror.rb +16 -16
- data/lib/sisimai/reason/mesgtoobig.rb +17 -17
- data/lib/sisimai/reason/networkerror.rb +19 -19
- data/lib/sisimai/reason/norelaying.rb +16 -16
- data/lib/sisimai/reason/notaccept.rb +9 -10
- data/lib/sisimai/reason/onhold.rb +1 -1
- data/lib/sisimai/reason/policyviolation.rb +21 -20
- data/lib/sisimai/reason/rejected.rb +53 -53
- data/lib/sisimai/reason/securityerror.rb +29 -29
- data/lib/sisimai/reason/spamdetected.rb +127 -127
- data/lib/sisimai/reason/suspend.rb +17 -17
- data/lib/sisimai/reason/systemerror.rb +22 -21
- data/lib/sisimai/reason/systemfull.rb +6 -6
- data/lib/sisimai/reason/toomanyconn.rb +19 -18
- data/lib/sisimai/reason/userunknown.rb +122 -121
- data/lib/sisimai/reason/vacation.rb +8 -8
- data/lib/sisimai/reason/virusdetected.rb +8 -8
- data/lib/sisimai/rfc1894.rb +142 -0
- data/lib/sisimai/rfc3464.rb +70 -70
- data/lib/sisimai/rfc3834.rb +15 -15
- data/lib/sisimai/rfc5322.rb +20 -36
- data/lib/sisimai/rhost.rb +1 -0
- data/lib/sisimai/rhost/exchangeonline.rb +31 -33
- data/lib/sisimai/rhost/franceptt.rb +23 -23
- data/lib/sisimai/rhost/godaddy.rb +28 -28
- data/lib/sisimai/rhost/googleapps.rb +39 -41
- data/lib/sisimai/rhost/kddi.rb +3 -3
- data/lib/sisimai/rhost/tencentqq.rb +51 -0
- data/lib/sisimai/smtp/error.rb +14 -21
- data/lib/sisimai/smtp/reply.rb +14 -13
- data/lib/sisimai/smtp/status.rb +178 -179
- data/lib/sisimai/string.rb +13 -12
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/README.md +1 -5
- data/set-of-emails/maildir/bsd/arf-23.eml +49 -0
- data/set-of-emails/maildir/bsd/email-amavis-01.eml +78 -0
- data/set-of-emails/maildir/bsd/email-amavis-02.eml +78 -0
- data/set-of-emails/maildir/bsd/email-exchange2007-04.eml +146 -0
- data/set-of-emails/maildir/bsd/email-exim-60.eml +94 -0
- data/set-of-emails/maildir/bsd/email-ezweb-08.eml +49 -0
- data/set-of-emails/maildir/bsd/email-google-19.eml +67 -0
- data/set-of-emails/maildir/bsd/email-mcafee-05.eml +74 -0
- data/set-of-emails/maildir/bsd/email-messagingserver-12.eml +99 -0
- data/set-of-emails/maildir/bsd/email-postfix-46.eml +81 -0
- data/set-of-emails/maildir/bsd/email-postfix-47.eml +79 -0
- data/set-of-emails/maildir/bsd/email-postfix-48.eml +79 -0
- data/set-of-emails/maildir/bsd/email-postfix-49.eml +141 -0
- data/set-of-emails/maildir/bsd/email-postfix-50.eml +143 -0
- data/set-of-emails/maildir/bsd/email-postfix-51.eml +73 -0
- data/set-of-emails/maildir/bsd/email-postfix-52.eml +79 -0
- data/set-of-emails/maildir/bsd/email-postfix-53.eml +76 -0
- data/set-of-emails/maildir/bsd/email-postfix-54.eml +73 -0
- data/set-of-emails/maildir/bsd/email-postfix-55.eml +74 -0
- data/set-of-emails/maildir/bsd/email-postfix-56.eml +78 -0
- data/set-of-emails/maildir/bsd/email-qmail-10.eml +50 -0
- data/set-of-emails/maildir/bsd/email-x2-05.eml +38 -0
- data/set-of-emails/maildir/bsd/rhost-google-apps-02.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-tencentqq-01.eml +84 -0
- data/set-of-emails/maildir/bsd/rhost-tencentqq-02.eml +84 -0
- data/set-of-emails/maildir/bsd/rhost-tencentqq-03.eml +81 -0
- data/set-of-emails/maildir/dos/email-amavis-01.eml +78 -0
- data/set-of-emails/maildir/dos/email-apachejames-01.eml +1 -2
- data/set-of-emails/maildir/dos/email-messagelabs-01.eml +67 -50
- data/set-of-emails/maildir/dos/email-x4-01.eml +31 -76
- data/set-of-emails/maildir/dos/rhost-tencentqq-01.eml +84 -0
- data/set-of-emails/maildir/mac/email-amavis-01.eml +1 -4
- data/set-of-emails/maildir/mac/email-apachejames-01.eml +1 -9
- data/set-of-emails/maildir/mac/email-messagelabs-01.eml +1 -9
- data/set-of-emails/maildir/mac/email-x4-01.eml +1 -5
- data/set-of-emails/maildir/mac/rhost-tencentqq-01.eml +1 -4
- metadata +35 -4
- data/set-of-emails/logo/horizontalversions.png +0 -0
- data/set-of-emails/logo/icon.png +0 -0
@@ -12,13 +12,13 @@ module Sisimai::Bite::Email
|
|
12
12
|
rfc822: ['Content-Type: message/delivery-status'],
|
13
13
|
}.freeze
|
14
14
|
MessagesOf = {
|
15
|
-
userunknown
|
15
|
+
'userunknown' => [
|
16
16
|
'not listed in Domino Directory',
|
17
17
|
'not listed in public Name & Address Book',
|
18
18
|
'Domino ディレクトリには見つかりません',
|
19
19
|
],
|
20
|
-
filtered
|
21
|
-
systemerror
|
20
|
+
'filtered' => ['Cannot route mail to user'],
|
21
|
+
'systemerror' => ['Several matches found in Domino Directory'],
|
22
22
|
}.freeze
|
23
23
|
|
24
24
|
def description; return 'IBM Domino Server'; end
|
@@ -68,7 +68,7 @@ module Sisimai::Bite::Email
|
|
68
68
|
end
|
69
69
|
|
70
70
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
71
|
-
#
|
71
|
+
# Inside of the original message part
|
72
72
|
if e.empty?
|
73
73
|
blanklines += 1
|
74
74
|
break if blanklines > 1
|
@@ -76,7 +76,7 @@ module Sisimai::Bite::Email
|
|
76
76
|
end
|
77
77
|
rfc822list << e
|
78
78
|
else
|
79
|
-
#
|
79
|
+
# Error message part
|
80
80
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
81
81
|
|
82
82
|
# Your message
|
@@ -133,9 +133,8 @@ module Sisimai::Bite::Email
|
|
133
133
|
MessagesOf.each_key do |r|
|
134
134
|
# Check each regular expression of Domino error messages
|
135
135
|
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
136
|
-
e['reason'] = r
|
137
|
-
|
138
|
-
e['status'] = pseudostatus unless pseudostatus.empty?
|
136
|
+
e['reason'] = r
|
137
|
+
e['status'] = Sisimai::SMTP::Status.code(r.to_s, false) || ''
|
139
138
|
break
|
140
139
|
end
|
141
140
|
e.each_key { |a| e[a] ||= '' }
|
@@ -12,11 +12,10 @@ module Sisimai::Bite::Email
|
|
12
12
|
error: ['For the following reason:'],
|
13
13
|
rfc822: ['--- The header of the original message is following'],
|
14
14
|
}.freeze
|
15
|
-
MessagesOf = { mesgtoobig
|
15
|
+
MessagesOf = { 'mesgtoobig' => ['Mail size limit exceeded'] }.freeze
|
16
16
|
|
17
17
|
def description; return '1&1: http://www.1and1.de'; end
|
18
18
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
19
|
-
# X-UI-Out-Filterresults: unknown:0;
|
20
19
|
def headerlist; return []; end
|
21
20
|
|
22
21
|
# Parse bounce messages from 1&1
|
@@ -60,7 +59,7 @@ module Sisimai::Bite::Email
|
|
60
59
|
end
|
61
60
|
|
62
61
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
63
|
-
#
|
62
|
+
# Inside of the original message part
|
64
63
|
if e.empty?
|
65
64
|
blanklines += 1
|
66
65
|
break if blanklines > 1
|
@@ -68,7 +67,7 @@ module Sisimai::Bite::Email
|
|
68
67
|
end
|
69
68
|
rfc822list << e
|
70
69
|
else
|
71
|
-
#
|
70
|
+
# Error message part
|
72
71
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
73
72
|
next if e.empty?
|
74
73
|
|
@@ -110,7 +109,7 @@ module Sisimai::Bite::Email
|
|
110
109
|
MessagesOf.each_key do |r|
|
111
110
|
# Verify each regular expression of session errors
|
112
111
|
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
113
|
-
e['reason'] = r
|
112
|
+
e['reason'] = r
|
114
113
|
break
|
115
114
|
end
|
116
115
|
end
|
@@ -14,36 +14,36 @@ module Sisimai::Bite::Email
|
|
14
14
|
rfc822: ['Content-Type: message/rfc822'],
|
15
15
|
}.freeze
|
16
16
|
ErrorCodes = {
|
17
|
-
onhold
|
17
|
+
'onhold' => [
|
18
18
|
'000B099C', # Host Unknown, Message exceeds size limit, ...
|
19
19
|
'000B09AA', # Unable to relay for, Message exceeds size limit,...
|
20
20
|
'000B09B6', # Error messages by remote MTA
|
21
21
|
],
|
22
|
-
userunknown
|
22
|
+
'userunknown' => [
|
23
23
|
'000C05A6', # Unknown Recipient,
|
24
24
|
],
|
25
|
-
systemerror
|
25
|
+
'systemerror' => [
|
26
26
|
'00010256', # Too many recipients.
|
27
27
|
'000D06B5', # No proxy for recipient (non-smtp mail?)
|
28
28
|
],
|
29
|
-
networkerror
|
29
|
+
'networkerror' => [
|
30
30
|
'00120270', # Too Many Hops
|
31
31
|
],
|
32
|
-
contenterr
|
32
|
+
'contenterr' => [
|
33
33
|
'00050311', # Conversion to Internet format failed
|
34
34
|
'000502CC', # Conversion to Internet format failed
|
35
35
|
],
|
36
|
-
securityerr
|
36
|
+
'securityerr' => [
|
37
37
|
'000B0981', # 502 Server does not support AUTH
|
38
38
|
],
|
39
|
-
filtered
|
39
|
+
'filtered' => [
|
40
40
|
'000C0595', # Ambiguous Recipient
|
41
41
|
],
|
42
42
|
}.freeze
|
43
43
|
|
44
44
|
def description; return 'Microsoft Exchange Server 2003'; end
|
45
45
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
46
|
-
def headerlist; return [
|
46
|
+
def headerlist; return %w[x-ms-embedded-report x-mimeole]; end
|
47
47
|
|
48
48
|
# Parse bounce messages from Microsoft Exchange Server 2003
|
49
49
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -124,7 +124,7 @@ module Sisimai::Bite::Email
|
|
124
124
|
end
|
125
125
|
|
126
126
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
127
|
-
#
|
127
|
+
# Inside of the original message part
|
128
128
|
if e.empty?
|
129
129
|
blanklines += 1
|
130
130
|
break if blanklines > 1
|
@@ -132,7 +132,7 @@ module Sisimai::Bite::Email
|
|
132
132
|
end
|
133
133
|
rfc822list << e
|
134
134
|
else
|
135
|
-
#
|
135
|
+
# Error message part
|
136
136
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
137
137
|
next if statuspart
|
138
138
|
|
@@ -214,18 +214,18 @@ module Sisimai::Bite::Email
|
|
214
214
|
return nil unless recipients > 0
|
215
215
|
|
216
216
|
dscontents.each do |e|
|
217
|
+
e['agent'] = self.smtpagent
|
218
|
+
e.delete('msexch')
|
217
219
|
if cv = e['diagnosis'].match(/\AMSEXCH:.+[ \t]*[(]([0-9A-F]{8})[)][ \t]*(.*)\z/)
|
218
220
|
# MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
|
219
221
|
capturedcode = cv[1]
|
220
222
|
errormessage = cv[2]
|
221
|
-
pseudostatus = ''
|
222
223
|
|
223
224
|
ErrorCodes.each_key do |r|
|
224
225
|
# Find captured code from the error code table
|
225
226
|
next unless ErrorCodes[r].index(capturedcode)
|
226
|
-
e['reason'] = r
|
227
|
-
|
228
|
-
e['status'] = pseudostatus unless pseudostatus.empty?
|
227
|
+
e['reason'] = r
|
228
|
+
e['status'] = Sisimai::SMTP::Status.code(r.to_s) || ''
|
229
229
|
break
|
230
230
|
end
|
231
231
|
e['diagnosis'] = errormessage
|
@@ -233,15 +233,14 @@ module Sisimai::Bite::Email
|
|
233
233
|
|
234
234
|
unless e['reason']
|
235
235
|
# Could not detect the reason from the value of "diagnosis".
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
236
|
+
next unless e['alterrors']
|
237
|
+
next if e['alterrors'].empty?
|
238
|
+
|
239
|
+
# Copy alternative error message
|
240
|
+
e['diagnosis'] = e['alterrors'] + ' ' + e['diagnosis']
|
241
|
+
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
242
|
+
e.delete('alterrors')
|
242
243
|
end
|
243
|
-
e['agent'] = self.smtpagent
|
244
|
-
e.delete('msexch')
|
245
244
|
e.each_key { |a| e[a] ||= '' }
|
246
245
|
end
|
247
246
|
|
@@ -10,28 +10,28 @@ module Sisimai::Bite::Email
|
|
10
10
|
Indicators = Sisimai::Bite::Email.INDICATORS
|
11
11
|
StartingOf = { rfc822: ['Original message headers:'] }.freeze
|
12
12
|
MarkingsOf = {
|
13
|
-
message: %r
|
13
|
+
message: %r/\ADiagnostic[ ]information[ ]for[ ]administrators:/,
|
14
14
|
error: %r/ ((?:RESOLVER|QUEUE)[.][A-Za-z]+(?:[.]\w+)?);/,
|
15
15
|
rhost: %r/\AGenerating server:[ ]?(.*)/,
|
16
16
|
}.freeze
|
17
17
|
NDRSubject = {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
18
|
+
'SMTPSEND.DNS.NonExistentDomain' => 'hostunknown', # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
|
19
|
+
'SMTPSEND.DNS.MxLoopback' => 'networkerror', # 554 5.4.4 SMTPSEND.DNS.MxLoopback
|
20
|
+
'RESOLVER.ADR.BadPrimary' => 'systemerror', # 550 5.2.0 RESOLVER.ADR.BadPrimary
|
21
|
+
'RESOLVER.ADR.RecipNotFound' => 'userunknown', # 550 5.1.1 RESOLVER.ADR.RecipNotFound
|
22
|
+
'RESOLVER.ADR.ExRecipNotFound' => 'userunknown', # 550 5.1.1 RESOLVER.ADR.ExRecipNotFound
|
23
|
+
'RESOLVER.ADR.RecipLimit' => 'toomanyconn', # 550 5.5.3 RESOLVER.ADR.RecipLimit
|
24
|
+
'RESOLVER.ADR.InvalidInSmtp' => 'systemerror', # 550 5.1.0 RESOLVER.ADR.InvalidInSmtp
|
25
|
+
'RESOLVER.ADR.Ambiguous' => 'systemerror', # 550 5.1.4 RESOLVER.ADR.Ambiguous, 420 4.2.0 RESOLVER.ADR.Ambiguous
|
26
|
+
'RESOLVER.RST.AuthRequired' => 'securityerror', # 550 5.7.1 RESOLVER.RST.AuthRequired
|
27
|
+
'RESOLVER.RST.NotAuthorized' => 'rejected', # 550 5.7.1 RESOLVER.RST.NotAuthorized
|
28
|
+
'RESOLVER.RST.RecipSizeLimit' => 'mesgtoobig', # 550 5.2.3 RESOLVER.RST.RecipSizeLimit
|
29
|
+
'QUEUE.Expired' => 'expired', # 550 4.4.7 QUEUE.Expired
|
30
30
|
}.freeze
|
31
31
|
|
32
32
|
def description; return 'Microsoft Exchange Server 2007'; end
|
33
33
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
34
|
-
def headerlist; return [
|
34
|
+
def headerlist; return %w[content-language]; end
|
35
35
|
|
36
36
|
# Parse bounce messages from Microsoft Exchange Server 2007
|
37
37
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -79,7 +79,7 @@ module Sisimai::Bite::Email
|
|
79
79
|
end
|
80
80
|
|
81
81
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
82
|
-
#
|
82
|
+
# Inside of the original message part
|
83
83
|
if e.empty?
|
84
84
|
blanklines += 1
|
85
85
|
break if blanklines > 1
|
@@ -87,7 +87,7 @@ module Sisimai::Bite::Email
|
|
87
87
|
end
|
88
88
|
rfc822list << e
|
89
89
|
else
|
90
|
-
#
|
90
|
+
# Error message part
|
91
91
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
92
92
|
|
93
93
|
if connvalues == connheader.keys.size
|
@@ -120,22 +120,20 @@ module Sisimai::Bite::Email
|
|
120
120
|
v['status'] = cv[2]
|
121
121
|
v['diagnosis'] = e
|
122
122
|
else
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
123
|
+
# Continued line of error messages
|
124
|
+
next if v['diagnosis'].to_s.empty?
|
125
|
+
next unless v['diagnosis'].end_with?('=')
|
126
|
+
v['diagnosis'] = v['diagnosis'].chomp('=')
|
127
|
+
v['diagnosis'] << e
|
128
128
|
end
|
129
129
|
else
|
130
130
|
# Diagnostic information for administrators:
|
131
131
|
#
|
132
132
|
# Generating server: mta22.neko.example.org
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
connvalues += 1
|
138
|
-
end
|
133
|
+
next unless cv = e.match(MarkingsOf[:rhost])
|
134
|
+
next unless connheader['rhost'].empty?
|
135
|
+
connheader['rhost'] = cv[1]
|
136
|
+
connvalues += 1
|
139
137
|
end
|
140
138
|
end
|
141
139
|
end
|
@@ -147,7 +145,7 @@ module Sisimai::Bite::Email
|
|
147
145
|
f = cv[1]
|
148
146
|
NDRSubject.each_key do |r|
|
149
147
|
# Try to match with error subject strings
|
150
|
-
next unless f == r
|
148
|
+
next unless f == r
|
151
149
|
e['reason'] = NDRSubject[r]
|
152
150
|
break
|
153
151
|
end
|
@@ -62,11 +62,11 @@ module Sisimai::Bite::Email
|
|
62
62
|
MessagesOf = {
|
63
63
|
# find exim/ -type f -exec grep 'message = US' {} /dev/null \;
|
64
64
|
# route.c:1158| DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n");
|
65
|
-
userunknown
|
65
|
+
'userunknown' => ['user not found'],
|
66
66
|
# transports/smtp.c:3524| addr->message = US"all host address lookups failed permanently";
|
67
67
|
# routers/dnslookup.c:331| addr->message = US"all relevant MX records point to non-existent hosts";
|
68
68
|
# route.c:1826| uschar *message = US"Unrouteable address";
|
69
|
-
hostunknown
|
69
|
+
'hostunknown' => [
|
70
70
|
'all host address lookups failed permanently',
|
71
71
|
'all relevant MX records point to non-existent hosts',
|
72
72
|
'Unrouteable address',
|
@@ -74,10 +74,10 @@ module Sisimai::Bite::Email
|
|
74
74
|
# transports/appendfile.c:2567| addr->user_message = US"mailbox is full";
|
75
75
|
# transports/appendfile.c:3049| addr->message = string_sprintf("mailbox is full "
|
76
76
|
# transports/appendfile.c:3050| "(quota exceeded while writing to file %s)", filename);
|
77
|
-
mailboxfull
|
77
|
+
'mailboxfull' => ['mailbox is full', 'error: quota exceed'],
|
78
78
|
# routers/dnslookup.c:328| addr->message = US"an MX or SRV record indicated no SMTP service";
|
79
79
|
# transports/smtp.c:3502| addr->message = US"no host found for existing SMTP connection";
|
80
|
-
notaccept
|
80
|
+
'notaccept' => [
|
81
81
|
'an MX or SRV record indicated no SMTP service',
|
82
82
|
'no host found for existing SMTP connection',
|
83
83
|
],
|
@@ -85,7 +85,7 @@ module Sisimai::Bite::Email
|
|
85
85
|
# parser.c:701| if(bracket_count++ > 5) FAILED(US"angle-brackets nested too deep");
|
86
86
|
# parser.c:738| FAILED(US"domain missing in source-routed address");
|
87
87
|
# parser.c:747| : string_sprintf("malformed address: %.32s may not follow %.*s",
|
88
|
-
syntaxerror
|
88
|
+
'syntaxerror' => [
|
89
89
|
'angle-brackets nested too deep',
|
90
90
|
'expected word or "<"',
|
91
91
|
'domain missing in source-routed address',
|
@@ -94,14 +94,14 @@ module Sisimai::Bite::Email
|
|
94
94
|
# deliver.c:5614| addr->message = US"delivery to file forbidden";
|
95
95
|
# deliver.c:5624| addr->message = US"delivery to pipe forbidden";
|
96
96
|
# transports/pipe.c:1156| addr->user_message = US"local delivery failed";
|
97
|
-
systemerror
|
97
|
+
'systemerror' => [
|
98
98
|
'delivery to file forbidden',
|
99
99
|
'delivery to pipe forbidden',
|
100
100
|
'local delivery failed',
|
101
101
|
'LMTP error after ',
|
102
102
|
],
|
103
103
|
# deliver.c:5425| new->message = US"Too many \"Received\" headers - suspected mail loop";
|
104
|
-
contenterror
|
104
|
+
'contenterror' => ['Too many "Received" headers'],
|
105
105
|
}.freeze
|
106
106
|
|
107
107
|
# retry.c:902| addr->message = (addr->message == NULL)? US"retry timeout exceeded" :
|
@@ -125,7 +125,7 @@ module Sisimai::Bite::Email
|
|
125
125
|
|
126
126
|
def description; return 'Exim'; end
|
127
127
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
128
|
-
def headerlist; return [
|
128
|
+
def headerlist; return %w[x-failed-recipients]; end
|
129
129
|
|
130
130
|
# Parse bounce messages from Exim
|
131
131
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -152,6 +152,8 @@ module Sisimai::Bite::Email
|
|
152
152
|
)
|
153
153
|
}x
|
154
154
|
|
155
|
+
require 'sisimai/rfc1894'
|
156
|
+
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
155
157
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
156
158
|
hasdivided = mbody.split("\n")
|
157
159
|
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
@@ -175,7 +177,7 @@ module Sisimai::Bite::Email
|
|
175
177
|
break if e == StartingOf[:endof][0]
|
176
178
|
|
177
179
|
if readcursor == 0
|
178
|
-
# Beginning of the bounce message or delivery
|
180
|
+
# Beginning of the bounce message or message/delivery-status part
|
179
181
|
if e =~ MarkingsOf[:message]
|
180
182
|
readcursor |= Indicators[:deliverystatus]
|
181
183
|
next unless e =~ MarkingsOf[:frozen]
|
@@ -183,7 +185,7 @@ module Sisimai::Bite::Email
|
|
183
185
|
end
|
184
186
|
|
185
187
|
if (readcursor & Indicators[:'message-rfc822']) == 0
|
186
|
-
# Beginning of the original message part
|
188
|
+
# Beginning of the original message part(message/rfc822)
|
187
189
|
if e =~ MarkingsOf[:rfc822]
|
188
190
|
readcursor |= Indicators[:'message-rfc822']
|
189
191
|
next
|
@@ -191,7 +193,7 @@ module Sisimai::Bite::Email
|
|
191
193
|
end
|
192
194
|
|
193
195
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
194
|
-
#
|
196
|
+
# message/rfc822 OR text/rfc822-headers part
|
195
197
|
if e.empty?
|
196
198
|
blanklines += 1
|
197
199
|
break if blanklines > 1
|
@@ -199,7 +201,7 @@ module Sisimai::Bite::Email
|
|
199
201
|
end
|
200
202
|
rfc822list << e
|
201
203
|
else
|
202
|
-
#
|
204
|
+
# message/delivery-status part
|
203
205
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
204
206
|
next if e.empty?
|
205
207
|
|
@@ -266,34 +268,34 @@ module Sisimai::Bite::Email
|
|
266
268
|
# --NNNNNNNNNN-eximdsn-MMMMMMMMMM
|
267
269
|
# Content-type: message/delivery-status
|
268
270
|
# ...
|
269
|
-
if
|
270
|
-
#
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
271
|
+
if Sisimai::RFC1894.match(e)
|
272
|
+
# "e" matched with any field defined in RFC3464
|
273
|
+
next unless o = Sisimai::RFC1894.field(e)
|
274
|
+
|
275
|
+
if o[-1] == 'addr'
|
276
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
277
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
278
|
+
next unless o[0] == 'final-recipient'
|
279
|
+
v['spec'] ||= o[2].include?('@') ? 'SMTP' : 'X-UNIX'
|
280
|
+
|
281
|
+
elsif o[-1] == 'code'
|
282
|
+
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
283
|
+
v['spec'] = o[1]
|
284
|
+
v['diagnosis'] = o[2]
|
285
|
+
|
286
|
+
else
|
287
|
+
# Other DSN fields defined in RFC3464
|
288
|
+
next unless fieldtable.key?(o[0])
|
289
|
+
v[fieldtable[o[0]]] = o[2]
|
290
|
+
end
|
289
291
|
else
|
290
292
|
# Error message ?
|
291
|
-
if havepassed[:deliverystatus] ==
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
293
|
+
next if havepassed[:deliverystatus] == 1
|
294
|
+
|
295
|
+
# Content-type: message/delivery-status
|
296
|
+
havepassed[:deliverystatus] = 1 if e.start_with?(StartingOf[:deliverystatus][0])
|
297
|
+
v['alterrors'] ||= ''
|
298
|
+
v['alterrors'] << e + ' ' if e.start_with?(' ')
|
297
299
|
end
|
298
300
|
else
|
299
301
|
if dscontents.size == recipients
|
@@ -313,12 +315,11 @@ module Sisimai::Bite::Email
|
|
313
315
|
v['alterrors'] ||= ''
|
314
316
|
v['alterrors'] << e + ' '
|
315
317
|
end
|
316
|
-
|
317
318
|
end
|
318
319
|
end
|
319
320
|
end
|
320
321
|
end
|
321
|
-
end
|
322
|
+
end # End of message/delivery-status
|
322
323
|
end
|
323
324
|
|
324
325
|
if recipients > 0
|
@@ -448,7 +449,7 @@ module Sisimai::Bite::Email
|
|
448
449
|
MessagesOf.each_key do |r|
|
449
450
|
# Check each regular expression
|
450
451
|
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
451
|
-
e['reason'] = r
|
452
|
+
e['reason'] = r
|
452
453
|
break
|
453
454
|
end
|
454
455
|
|
@@ -473,10 +474,10 @@ module Sisimai::Bite::Email
|
|
473
474
|
s1 = 0 # First character of Status as integer
|
474
475
|
r1 = 0 # First character of SMTP reply code as integer
|
475
476
|
|
476
|
-
# "Status:" field did not exist in the bounce message
|
477
477
|
while true
|
478
|
-
|
479
|
-
break if
|
478
|
+
# "Status:" field did not exist in the bounce message
|
479
|
+
break if sv
|
480
|
+
break unless rv
|
480
481
|
|
481
482
|
# Check SMTP reply code
|
482
483
|
# Generate pseudo DSN code from SMTP reply code
|
@@ -492,8 +493,8 @@ module Sisimai::Bite::Email
|
|
492
493
|
break
|
493
494
|
end
|
494
495
|
|
495
|
-
s1
|
496
|
-
v1
|
496
|
+
s1 = sv[0, 1].to_i if sv
|
497
|
+
v1 = s1 + r1
|
497
498
|
v1 << e['status'][0, 1].to_i if e['status']
|
498
499
|
|
499
500
|
if v1 > 0
|
@@ -510,7 +511,7 @@ module Sisimai::Bite::Email
|
|
510
511
|
Sisimai::SMTP::Status.code(e['reason'], false)
|
511
512
|
end
|
512
513
|
end
|
513
|
-
e['status'] ||= sv
|
514
|
+
e['status'] ||= sv.to_s
|
514
515
|
e.each_key { |a| e[a] ||= '' }
|
515
516
|
end
|
516
517
|
|