sisimai 4.25.4 → 4.25.5
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 +2 -2
- data/ChangeLog.md +50 -0
- data/README-JA.md +10 -37
- data/README.md +10 -37
- data/lib/sisimai.rb +15 -64
- data/lib/sisimai/address.rb +13 -17
- data/lib/sisimai/arf.rb +4 -4
- data/lib/sisimai/data.rb +3 -5
- data/lib/sisimai/lhost.rb +0 -14
- data/lib/sisimai/lhost/activehunter.rb +31 -55
- data/lib/sisimai/lhost/amavis.rb +41 -66
- data/lib/sisimai/lhost/amazonses.rb +189 -235
- data/lib/sisimai/lhost/amazonworkmail.rb +48 -71
- data/lib/sisimai/lhost/aol.rb +49 -75
- data/lib/sisimai/lhost/apachejames.rb +60 -83
- data/lib/sisimai/lhost/bigfoot.rb +61 -85
- data/lib/sisimai/lhost/biglobe.rb +40 -62
- data/lib/sisimai/lhost/courier.rb +60 -82
- data/lib/sisimai/lhost/domino.rb +50 -76
- data/lib/sisimai/lhost/einsundeins.rb +57 -55
- data/lib/sisimai/lhost/exchange2003.rb +79 -101
- data/lib/sisimai/lhost/exchange2007.rb +66 -74
- data/lib/sisimai/lhost/exim.rb +119 -142
- data/lib/sisimai/lhost/ezweb.rb +53 -73
- data/lib/sisimai/lhost/facebook.rb +49 -75
- data/lib/sisimai/lhost/fml.rb +25 -50
- data/lib/sisimai/lhost/gmx.rb +55 -79
- data/lib/sisimai/lhost/google.rb +39 -66
- data/lib/sisimai/lhost/gsuite.rb +74 -94
- data/lib/sisimai/lhost/imailserver.rb +34 -67
- data/lib/sisimai/lhost/interscanmss.rb +33 -67
- data/lib/sisimai/lhost/kddi.rb +30 -52
- data/lib/sisimai/lhost/mailfoundry.rb +35 -57
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +66 -89
- data/lib/sisimai/lhost/mailru.rb +51 -76
- data/lib/sisimai/lhost/mcafee.rb +53 -79
- data/lib/sisimai/lhost/messagelabs.rb +49 -75
- data/lib/sisimai/lhost/messagingserver.rb +91 -113
- data/lib/sisimai/lhost/mfilter.rb +50 -70
- data/lib/sisimai/lhost/mxlogic.rb +38 -63
- data/lib/sisimai/lhost/notes.rb +53 -82
- data/lib/sisimai/lhost/office365.rb +64 -81
- data/lib/sisimai/lhost/opensmtpd.rb +30 -52
- data/lib/sisimai/lhost/outlook.rb +49 -75
- data/lib/sisimai/lhost/postfix.rb +116 -117
- data/lib/sisimai/lhost/qmail.rb +33 -55
- data/lib/sisimai/lhost/receivingses.rb +49 -75
- data/lib/sisimai/lhost/sendgrid.rb +68 -203
- data/lib/sisimai/lhost/sendmail.rb +101 -125
- data/lib/sisimai/lhost/surfcontrol.rb +53 -79
- data/lib/sisimai/lhost/userdefined.rb +15 -35
- data/lib/sisimai/lhost/v5sendmail.rb +59 -89
- data/lib/sisimai/lhost/verizon.rb +75 -124
- data/lib/sisimai/lhost/x1.rb +30 -54
- data/lib/sisimai/lhost/x2.rb +28 -52
- data/lib/sisimai/lhost/x3.rb +44 -68
- data/lib/sisimai/lhost/x4.rb +34 -58
- data/lib/sisimai/lhost/x5.rb +42 -70
- data/lib/sisimai/lhost/yahoo.rb +44 -68
- data/lib/sisimai/lhost/yandex.rb +59 -85
- data/lib/sisimai/lhost/zoho.rb +54 -78
- data/lib/sisimai/mail.rb +5 -9
- data/lib/sisimai/mail/maildir.rb +10 -14
- data/lib/sisimai/mail/mbox.rb +8 -12
- data/lib/sisimai/mail/memory.rb +5 -9
- data/lib/sisimai/mail/stdin.rb +7 -11
- data/lib/sisimai/mda.rb +2 -2
- data/lib/sisimai/message.rb +51 -154
- data/lib/sisimai/mime.rb +2 -2
- data/lib/sisimai/order.rb +2 -27
- data/lib/sisimai/reason.rb +3 -5
- data/lib/sisimai/rfc1894.rb +1 -1
- data/lib/sisimai/rfc3464.rb +29 -29
- data/lib/sisimai/rfc3834.rb +7 -6
- data/lib/sisimai/rfc5322.rb +20 -31
- data/lib/sisimai/rhost/franceptt.rb +120 -24
- data/lib/sisimai/rhost/iua.rb +1 -1
- data/lib/sisimai/smtp/error.rb +7 -7
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/email-einsundeins-03.eml +66 -0
- data/set-of-emails/maildir/bsd/email-exchange2007-05.eml +1469 -0
- data/set-of-emails/maildir/bsd/email-exchange2007-06.eml +764 -0
- data/set-of-emails/maildir/bsd/email-postfix-64.eml +96 -0
- data/set-of-emails/maildir/bsd/rfc3834-03.eml +26 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-04.eml +66 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-05.eml +96 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-06.eml +100 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-07.eml +97 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-08.eml +78 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-10.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-11.eml +96 -0
- metadata +14 -9
- data/lib/sisimai/bite.rb +0 -42
- data/lib/sisimai/bite/email.rb +0 -18
- data/lib/sisimai/bite/json.rb +0 -16
- data/lib/sisimai/message/email.rb +0 -26
- data/lib/sisimai/message/json.rb +0 -24
- data/lib/sisimai/order/email.rb +0 -20
- data/lib/sisimai/order/json.rb +0 -16
data/lib/sisimai/lhost/ezweb.rb
CHANGED
@@ -7,6 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
require 'sisimai/lhost'
|
8
8
|
|
9
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
+
ReBackbone = %r<^(?:[-]{50}|Content-Type:[ ]*message/rfc822)>.freeze
|
10
11
|
MarkingsOf = {
|
11
12
|
message: %r{\A(?:
|
12
13
|
The[ ]user[(]s[)][ ]
|
@@ -15,7 +16,6 @@ module Sisimai::Lhost
|
|
15
16
|
|[<][^ ]+[@][^ ]+[>]\z
|
16
17
|
)
|
17
18
|
}x,
|
18
|
-
rfc822: %r#\A(?:[-]{50}|Content-Type:[ ]*message/rfc822)#,
|
19
19
|
}.freeze
|
20
20
|
ReFailures = {
|
21
21
|
# notaccept: [ %r/The following recipients did not receive this message:/ ],
|
@@ -68,9 +68,8 @@ module Sisimai::Lhost
|
|
68
68
|
require 'sisimai/rfc1894'
|
69
69
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
70
70
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
71
|
-
|
72
|
-
|
73
|
-
blanklines = 0 # (Integer) The number of blank lines
|
71
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
72
|
+
bodyslices = emailsteak[0].split("\n")
|
74
73
|
readcursor = 0 # (Integer) Points the current cursor position
|
75
74
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
76
75
|
rxboundary = %r/\A__SISIMAI_PSEUDO_BOUNDARY__\z/
|
@@ -85,83 +84,65 @@ module Sisimai::Lhost
|
|
85
84
|
rxmessages = []
|
86
85
|
ReFailures.each_value { |a| rxmessages << a }
|
87
86
|
|
88
|
-
while e =
|
87
|
+
while e = bodyslices.shift do
|
88
|
+
# Read error messages and delivery status lines from the head of the email
|
89
|
+
# to the previous line of the beginning of the original message.
|
89
90
|
if readcursor == 0
|
90
91
|
# Beginning of the bounce message or delivery status part
|
91
92
|
readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
|
92
93
|
end
|
93
|
-
|
94
|
-
if
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
94
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
95
|
+
next if e.empty?
|
96
|
+
|
97
|
+
# The user(s) account is disabled.
|
98
|
+
#
|
99
|
+
# <***@ezweb.ne.jp>: 550 user unknown (in reply to RCPT TO command)
|
100
|
+
#
|
101
|
+
# -- OR --
|
102
|
+
# Each of the following recipients was rejected by a remote
|
103
|
+
# mail server.
|
104
|
+
#
|
105
|
+
# Recipient: <******@ezweb.ne.jp>
|
106
|
+
# >>> RCPT TO:<******@ezweb.ne.jp>
|
107
|
+
# <<< 550 <******@ezweb.ne.jp>: User unknown
|
108
|
+
v = dscontents[-1]
|
109
|
+
|
110
|
+
if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]\z/) ||
|
111
|
+
e.match(/\A[<]([^ ]+[@][^ ]+)[>]:?(.*)\z/) ||
|
112
|
+
e.match(/\A[ \t]+Recipient: [<]([^ ]+[@][^ ]+)[>]/)
|
113
|
+
|
114
|
+
if v['recipient']
|
115
|
+
# There are multiple recipient addresses in the message body.
|
116
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
117
|
+
v = dscontents[-1]
|
108
118
|
end
|
109
|
-
rfc822list << e
|
110
|
-
else
|
111
|
-
# Error message part
|
112
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
113
|
-
next if e.empty?
|
114
|
-
|
115
|
-
# The user(s) account is disabled.
|
116
|
-
#
|
117
|
-
# <***@ezweb.ne.jp>: 550 user unknown (in reply to RCPT TO command)
|
118
|
-
#
|
119
|
-
# -- OR --
|
120
|
-
# Each of the following recipients was rejected by a remote
|
121
|
-
# mail server.
|
122
|
-
#
|
123
|
-
# Recipient: <******@ezweb.ne.jp>
|
124
|
-
# >>> RCPT TO:<******@ezweb.ne.jp>
|
125
|
-
# <<< 550 <******@ezweb.ne.jp>: User unknown
|
126
|
-
v = dscontents[-1]
|
127
|
-
|
128
|
-
if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]\z/) ||
|
129
|
-
e.match(/\A[<]([^ ]+[@][^ ]+)[>]:?(.*)\z/) ||
|
130
|
-
e.match(/\A[ \t]+Recipient: [<]([^ ]+[@][^ ]+)[>]/)
|
131
|
-
|
132
|
-
if v['recipient']
|
133
|
-
# There are multiple recipient addresses in the message body.
|
134
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
135
|
-
v = dscontents[-1]
|
136
|
-
end
|
137
119
|
|
138
|
-
|
139
|
-
|
140
|
-
|
120
|
+
r = Sisimai::Address.s3s4(cv[1])
|
121
|
+
v['recipient'] = r
|
122
|
+
recipients += 1
|
141
123
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
124
|
+
elsif f = Sisimai::RFC1894.match(e)
|
125
|
+
# "e" matched with any field defined in RFC3464
|
126
|
+
next unless o = Sisimai::RFC1894.field(e)
|
127
|
+
next unless fieldtable[o[0]]
|
128
|
+
v[fieldtable[o[0]]] = o[2]
|
147
129
|
|
130
|
+
else
|
131
|
+
# The line does not begin with a DSN field defined in RFC3464
|
132
|
+
next if Sisimai::String.is_8bit(e)
|
133
|
+
if cv = e.match(/\A[ \t]+[>]{3}[ \t]+([A-Z]{4})/)
|
134
|
+
# >>> RCPT TO:<******@ezweb.ne.jp>
|
135
|
+
v['command'] = cv[1]
|
148
136
|
else
|
149
|
-
#
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
v['
|
137
|
+
# Check error message
|
138
|
+
if rxmessages.any? { |a| e =~ a }
|
139
|
+
# Check with regular expressions of each error
|
140
|
+
v['diagnosis'] ||= ''
|
141
|
+
v['diagnosis'] << ' ' << e
|
154
142
|
else
|
155
|
-
#
|
156
|
-
|
157
|
-
|
158
|
-
v['diagnosis'] ||= ''
|
159
|
-
v['diagnosis'] << ' ' << e
|
160
|
-
else
|
161
|
-
# >>> 550
|
162
|
-
v['alterrors'] ||= ''
|
163
|
-
v['alterrors'] << ' ' << e
|
164
|
-
end
|
143
|
+
# >>> 550
|
144
|
+
v['alterrors'] ||= ''
|
145
|
+
v['alterrors'] << ' ' << e
|
165
146
|
end
|
166
147
|
end
|
167
148
|
end
|
@@ -212,8 +193,7 @@ module Sisimai::Lhost
|
|
212
193
|
e['reason'] = 'userunknown'
|
213
194
|
end
|
214
195
|
|
215
|
-
|
216
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
196
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
217
197
|
end
|
218
198
|
|
219
199
|
end
|
@@ -7,10 +7,8 @@ module Sisimai::Lhost
|
|
7
7
|
require 'sisimai/lhost'
|
8
8
|
|
9
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
-
|
11
|
-
|
12
|
-
rfc822: ['Content-Disposition: inline'],
|
13
|
-
}.freeze
|
10
|
+
ReBackbone = %r|^Content-Disposition:[ ]inline|.freeze
|
11
|
+
StartingOf = { message: ['This message was created automatically by Facebook.'] }.freeze
|
14
12
|
ReFailures = {
|
15
13
|
# http://postmaster.facebook.com/response_codes
|
16
14
|
# NOT TESTD EXCEPT RCP-P2
|
@@ -95,90 +93,67 @@ module Sisimai::Lhost
|
|
95
93
|
permessage = {} # (Hash) Store values of each Per-Message field
|
96
94
|
|
97
95
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
blanklines = 0 # (Integer) The number of blank lines
|
96
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
97
|
+
bodyslices = emailsteak[0].split("\n")
|
98
|
+
readslices = ['']
|
102
99
|
readcursor = 0 # (Integer) Points the current cursor position
|
103
100
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
104
101
|
fbresponse = '' # (String) Response code from Facebook
|
105
102
|
v = nil
|
106
103
|
|
107
|
-
while e =
|
108
|
-
#
|
109
|
-
|
110
|
-
|
104
|
+
while e = bodyslices.shift do
|
105
|
+
# Read error messages and delivery status lines from the head of the email
|
106
|
+
# to the previous line of the beginning of the original message.
|
107
|
+
readslices << e # Save the current line for the next loop
|
111
108
|
|
112
109
|
if readcursor == 0
|
113
110
|
# Beginning of the bounce message or message/delivery-status part
|
114
|
-
if e == StartingOf[:message][0]
|
115
|
-
|
116
|
-
next
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
if (readcursor & Indicators[:'message-rfc822']) == 0
|
121
|
-
# Beginning of the original message part(message/rfc822)
|
122
|
-
if e == StartingOf[:rfc822][0]
|
123
|
-
readcursor |= Indicators[:'message-rfc822']
|
124
|
-
next
|
125
|
-
end
|
111
|
+
readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
|
112
|
+
next
|
126
113
|
end
|
127
|
-
|
128
|
-
if
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
next if e.empty?
|
140
|
-
|
141
|
-
if f = Sisimai::RFC1894.match(e)
|
142
|
-
# "e" matched with any field defined in RFC3464
|
143
|
-
o = Sisimai::RFC1894.field(e) || next
|
144
|
-
v = dscontents[-1]
|
145
|
-
|
146
|
-
if o[-1] == 'addr'
|
114
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
115
|
+
next if e.empty?
|
116
|
+
|
117
|
+
if f = Sisimai::RFC1894.match(e)
|
118
|
+
# "e" matched with any field defined in RFC3464
|
119
|
+
o = Sisimai::RFC1894.field(e) || next
|
120
|
+
v = dscontents[-1]
|
121
|
+
|
122
|
+
if o[-1] == 'addr'
|
123
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
124
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
125
|
+
if o[0] == 'final-recipient'
|
147
126
|
# Final-Recipient: rfc822; kijitora@example.jp
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
# There are multiple recipient addresses in the message body.
|
153
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
154
|
-
v = dscontents[-1]
|
155
|
-
end
|
156
|
-
v['recipient'] = o[2]
|
157
|
-
recipients += 1
|
158
|
-
else
|
159
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
160
|
-
v['alias'] = o[2]
|
127
|
+
if v['recipient']
|
128
|
+
# There are multiple recipient addresses in the message body.
|
129
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
130
|
+
v = dscontents[-1]
|
161
131
|
end
|
162
|
-
|
163
|
-
|
164
|
-
v['spec'] = o[1]
|
165
|
-
v['diagnosis'] = o[2]
|
132
|
+
v['recipient'] = o[2]
|
133
|
+
recipients += 1
|
166
134
|
else
|
167
|
-
#
|
168
|
-
|
169
|
-
v[fieldtable[o[0]]] = o[2]
|
170
|
-
|
171
|
-
next unless f == 1
|
172
|
-
permessage[fieldtable[o[0]]] = o[2]
|
135
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
136
|
+
v['alias'] = o[2]
|
173
137
|
end
|
138
|
+
elsif o[-1] == 'code'
|
139
|
+
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
140
|
+
v['spec'] = o[1]
|
141
|
+
v['diagnosis'] = o[2]
|
174
142
|
else
|
175
|
-
#
|
176
|
-
next unless
|
177
|
-
|
178
|
-
|
179
|
-
|
143
|
+
# Other DSN fields defined in RFC3464
|
144
|
+
next unless fieldtable[o[0]]
|
145
|
+
v[fieldtable[o[0]]] = o[2]
|
146
|
+
|
147
|
+
next unless f == 1
|
148
|
+
permessage[fieldtable[o[0]]] = o[2]
|
180
149
|
end
|
181
|
-
|
150
|
+
else
|
151
|
+
# Continued line of the value of Diagnostic-Code field
|
152
|
+
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
153
|
+
next unless cv = e.match(/\A[ \t]+(.+)\z/)
|
154
|
+
v['diagnosis'] << ' ' << cv[1]
|
155
|
+
readslices[-1] = 'Diagnostic-Code: ' << e
|
156
|
+
end
|
182
157
|
end
|
183
158
|
return nil unless recipients > 0
|
184
159
|
|
@@ -224,8 +199,7 @@ module Sisimai::Lhost
|
|
224
199
|
e['reason'] = 'systemerror'
|
225
200
|
end
|
226
201
|
|
227
|
-
|
228
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
202
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
229
203
|
end
|
230
204
|
|
231
205
|
end
|
data/lib/sisimai/lhost/fml.rb
CHANGED
@@ -7,7 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
require 'sisimai/lhost'
|
8
8
|
|
9
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
-
|
10
|
+
ReBackbone = %r|^Original[ ]mail[ ]as[ ]follows:|.freeze
|
11
11
|
ErrorTitle = {
|
12
12
|
'rejected' => %r{(?>
|
13
13
|
(?:Ignored[ ])*NOT[ ]MEMBER[ ]article[ ]from[ ]
|
@@ -66,61 +66,37 @@ module Sisimai::Lhost
|
|
66
66
|
return nil unless mhead['message-id'] =~ /\A[<]\d+[.]FML.+[@].+[>]\z/
|
67
67
|
|
68
68
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
69
|
-
|
70
|
-
|
71
|
-
blanklines = 0 # (Integer) The number of blank lines
|
69
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
70
|
+
bodyslices = emailsteak[0].split("\n")
|
72
71
|
readcursor = 0 # (Integer) Points the current cursor position
|
73
72
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
74
73
|
v = nil
|
75
74
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
readcursor |= Indicators[:'message-rfc822']
|
82
|
-
next
|
83
|
-
end
|
84
|
-
end
|
75
|
+
while e = bodyslices.shift do
|
76
|
+
# Read error messages and delivery status lines from the head of the email
|
77
|
+
# to the previous line of the beginning of the original message.
|
78
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
79
|
+
next if e.empty?
|
85
80
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
# From owner-2ndml@example.com Mon Nov 20 18:10:11 2017
|
90
|
-
# Return-Path: <owner-2ndml@example.com>
|
91
|
-
# ...
|
92
|
-
#
|
93
|
-
if e.empty?
|
94
|
-
blanklines += 1
|
95
|
-
break if blanklines > 1
|
96
|
-
next
|
97
|
-
end
|
98
|
-
rfc822list << e.lstrip
|
99
|
-
else
|
100
|
-
# Error message part
|
101
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
102
|
-
next if e.empty?
|
81
|
+
# Duplicated Message-ID in <2ndml@example.com>.
|
82
|
+
# Original mail as follows:
|
83
|
+
v = dscontents[-1]
|
103
84
|
|
85
|
+
if cv = e.match(/[<]([^ ]+?[@][^ ]+?)[>][.]\z/)
|
104
86
|
# Duplicated Message-ID in <2ndml@example.com>.
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
# Duplicated Message-ID in <2ndml@example.com>.
|
110
|
-
if v['recipient']
|
111
|
-
# There are multiple recipient addresses in the message body.
|
112
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
113
|
-
v = dscontents[-1]
|
114
|
-
end
|
115
|
-
v['recipient'] = cv[1]
|
116
|
-
v['diagnosis'] = e
|
117
|
-
recipients += 1
|
118
|
-
else
|
119
|
-
# If you know the general guide of this list, please send mail with
|
120
|
-
# the mail body
|
121
|
-
v['diagnosis'] ||= ''
|
122
|
-
v['diagnosis'] << e
|
87
|
+
if v['recipient']
|
88
|
+
# There are multiple recipient addresses in the message body.
|
89
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
90
|
+
v = dscontents[-1]
|
123
91
|
end
|
92
|
+
v['recipient'] = cv[1]
|
93
|
+
v['diagnosis'] = e
|
94
|
+
recipients += 1
|
95
|
+
else
|
96
|
+
# If you know the general guide of this list, please send mail with
|
97
|
+
# the mail body
|
98
|
+
v['diagnosis'] ||= ''
|
99
|
+
v['diagnosis'] << e
|
124
100
|
end
|
125
101
|
end
|
126
102
|
return nil unless recipients > 0
|
@@ -148,8 +124,7 @@ module Sisimai::Lhost
|
|
148
124
|
end
|
149
125
|
end
|
150
126
|
|
151
|
-
|
152
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
127
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
153
128
|
end
|
154
129
|
|
155
130
|
end
|
data/lib/sisimai/lhost/gmx.rb
CHANGED
@@ -7,10 +7,8 @@ module Sisimai::Lhost
|
|
7
7
|
require 'sisimai/lhost'
|
8
8
|
|
9
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
-
|
11
|
-
|
12
|
-
rfc822: ['--- The header of the original message is following'],
|
13
|
-
}.freeze
|
10
|
+
ReBackbone = %r|^---[ ]The[ ]header[ ]of[ ]the[ ]original[ ]message[ ]is[ ]following[.][ ]---|.freeze
|
11
|
+
StartingOf = { message: ['This message was created automatically by mail delivery software'] }.freeze
|
14
12
|
MessagesOf = { 'expired' => ['delivery retry timeout exceeded'] }.freeze
|
15
13
|
|
16
14
|
def description; return 'GMX: https://www.gmx.net'; end
|
@@ -39,91 +37,70 @@ module Sisimai::Lhost
|
|
39
37
|
return nil unless mhead['x-gmx-antispam']
|
40
38
|
|
41
39
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
42
|
-
|
43
|
-
|
44
|
-
blanklines = 0 # (Integer) The number of blank lines
|
40
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
41
|
+
bodyslices = emailsteak[0].split("\n")
|
45
42
|
readcursor = 0 # (Integer) Points the current cursor position
|
46
43
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
47
44
|
v = nil
|
48
45
|
|
49
|
-
while e =
|
46
|
+
while e = bodyslices.shift do
|
47
|
+
# Read error messages and delivery status lines from the head of the email
|
48
|
+
# to the previous line of the beginning of the original message.
|
50
49
|
if readcursor == 0
|
51
50
|
# Beginning of the bounce message or delivery status part
|
52
|
-
if e.start_with?(StartingOf[:message][0])
|
53
|
-
|
54
|
-
next
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
if (readcursor & Indicators[:'message-rfc822']) == 0
|
59
|
-
# Beginning of the original message part
|
60
|
-
if e.start_with?(StartingOf[:rfc822][0])
|
61
|
-
readcursor |= Indicators[:'message-rfc822']
|
62
|
-
next
|
63
|
-
end
|
51
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
52
|
+
next
|
64
53
|
end
|
65
|
-
|
66
|
-
if
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
54
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
55
|
+
next if e.empty?
|
56
|
+
|
57
|
+
# This message was created automatically by mail delivery software.
|
58
|
+
#
|
59
|
+
# A message that you sent could not be delivered to one or more of
|
60
|
+
# its recipients. This is a permanent error. The following address
|
61
|
+
# failed:
|
62
|
+
#
|
63
|
+
# "shironeko@example.jp":
|
64
|
+
# SMTP error from remote server after RCPT command:
|
65
|
+
# host: mx.example.jp
|
66
|
+
# 5.1.1 <shironeko@example.jp>... User Unknown
|
67
|
+
v = dscontents[-1]
|
68
|
+
|
69
|
+
if cv = e.match(/\A["]([^ ]+[@][^ ]+)["]:\z/) || e.match(/\A[<]([^ ]+[@][^ ]+)[>]\z/)
|
70
|
+
# "shironeko@example.jp":
|
71
|
+
# ---- OR ----
|
72
|
+
# <kijitora@6jo.example.co.jp>
|
73
|
+
#
|
74
|
+
# Reason:
|
75
|
+
# delivery retry timeout exceeded
|
76
|
+
if v['recipient']
|
77
|
+
# There are multiple recipient addresses in the message body.
|
78
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
79
|
+
v = dscontents[-1]
|
72
80
|
end
|
73
|
-
|
74
|
-
|
75
|
-
# Error message part
|
76
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
77
|
-
next if e.empty?
|
81
|
+
v['recipient'] = cv[1]
|
82
|
+
recipients += 1
|
78
83
|
|
79
|
-
|
80
|
-
#
|
81
|
-
# A message that you sent could not be delivered to one or more of
|
82
|
-
# its recipients. This is a permanent error. The following address
|
83
|
-
# failed:
|
84
|
-
#
|
85
|
-
# "shironeko@example.jp":
|
84
|
+
elsif cv = e.match(/\ASMTP error .+ ([A-Z]{4}) command:\z/)
|
86
85
|
# SMTP error from remote server after RCPT command:
|
87
|
-
|
88
|
-
# 5.1.1 <shironeko@example.jp>... User Unknown
|
89
|
-
v = dscontents[-1]
|
90
|
-
|
91
|
-
if cv = e.match(/\A["]([^ ]+[@][^ ]+)["]:\z/) || e.match(/\A[<]([^ ]+[@][^ ]+)[>]\z/)
|
92
|
-
# "shironeko@example.jp":
|
93
|
-
# ---- OR ----
|
94
|
-
# <kijitora@6jo.example.co.jp>
|
95
|
-
#
|
96
|
-
# Reason:
|
97
|
-
# delivery retry timeout exceeded
|
98
|
-
if v['recipient']
|
99
|
-
# There are multiple recipient addresses in the message body.
|
100
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
101
|
-
v = dscontents[-1]
|
102
|
-
end
|
103
|
-
v['recipient'] = cv[1]
|
104
|
-
recipients += 1
|
105
|
-
|
106
|
-
elsif cv = e.match(/\ASMTP error .+ ([A-Z]{4}) command:\z/)
|
107
|
-
# SMTP error from remote server after RCPT command:
|
108
|
-
v['command'] = cv[1]
|
86
|
+
v['command'] = cv[1]
|
109
87
|
|
110
|
-
|
111
|
-
|
112
|
-
|
88
|
+
elsif cv = e.match(/\Ahost:[ \t]*(.+)\z/)
|
89
|
+
# host: mx.example.jp
|
90
|
+
v['rhost'] = cv[1]
|
91
|
+
else
|
92
|
+
# Get error message
|
93
|
+
if e =~ /\b[45][.]\d[.]\d\b/ || e =~ /[<][^ ]+[@][^ ]+[>]/ || e =~ /\b[45]\d{2}\b/
|
94
|
+
v['diagnosis'] ||= e
|
113
95
|
else
|
114
|
-
|
115
|
-
if e
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
v['diagnosis'] = e
|
123
|
-
|
124
|
-
elsif v['diagnosis'] == 'Reason:'
|
125
|
-
v['diagnosis'] = e
|
126
|
-
end
|
96
|
+
next if e.empty?
|
97
|
+
if e.start_with?('Reason:')
|
98
|
+
# Reason:
|
99
|
+
# delivery retry timeout exceeded
|
100
|
+
v['diagnosis'] = e
|
101
|
+
|
102
|
+
elsif v['diagnosis'] == 'Reason:'
|
103
|
+
v['diagnosis'] = e
|
127
104
|
end
|
128
105
|
end
|
129
106
|
end
|
@@ -142,8 +119,7 @@ module Sisimai::Lhost
|
|
142
119
|
end
|
143
120
|
end
|
144
121
|
|
145
|
-
|
146
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
122
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
147
123
|
end
|
148
124
|
|
149
125
|
end
|