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/x2.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: ['--- Original message follows'],
|
13
|
-
}.freeze
|
10
|
+
ReBackbone = %r|^--- Original message follows[.]|.freeze
|
11
|
+
StartingOf = { message: ['Unable to deliver message to the following address'] }.freeze
|
14
12
|
|
15
13
|
def description; return 'Unknown MTA #2'; end
|
16
14
|
def smtpagent; return Sisimai::Lhost.smtpagent(self); end
|
@@ -32,64 +30,43 @@ module Sisimai::Lhost
|
|
32
30
|
return nil unless mhead['subject'] =~ %r/\A(?>Delivery failure|fail(?:ure|ed) delivery)/
|
33
31
|
|
34
32
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
35
|
-
|
36
|
-
|
37
|
-
blanklines = 0 # (Integer) The number of blank lines
|
33
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
34
|
+
bodyslices = emailsteak[0].split("\n")
|
38
35
|
readcursor = 0 # (Integer) Points the current cursor position
|
39
36
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
40
37
|
v = nil
|
41
38
|
|
42
|
-
while e =
|
39
|
+
while e = bodyslices.shift do
|
40
|
+
# Read error messages and delivery status lines from the head of the email
|
41
|
+
# to the previous line of the beginning of the original message.
|
43
42
|
if readcursor == 0
|
44
43
|
# Beginning of the bounce message or delivery status part
|
45
|
-
if e.start_with?(StartingOf[:message][0])
|
46
|
-
|
47
|
-
next
|
48
|
-
end
|
44
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
45
|
+
next
|
49
46
|
end
|
47
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
48
|
+
next if e.empty?
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
50
|
+
# Message from example.com.
|
51
|
+
# Unable to deliver message to the following address(es).
|
52
|
+
#
|
53
|
+
# <kijitora@example.com>:
|
54
|
+
# This user doesn't have a example.com account (kijitora@example.com) [0]
|
55
|
+
v = dscontents[-1]
|
58
56
|
|
59
|
-
if
|
60
|
-
#
|
61
|
-
if
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]:\z/)
|
58
|
+
# <kijitora@example.com>:
|
59
|
+
if v['recipient']
|
60
|
+
# There are multiple recipient addresses in the message body.
|
61
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
62
|
+
v = dscontents[-1]
|
65
63
|
end
|
66
|
-
|
64
|
+
v['recipient'] = cv[1]
|
65
|
+
recipients += 1
|
67
66
|
else
|
68
|
-
# Error message part
|
69
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
70
|
-
next if e.empty?
|
71
|
-
|
72
|
-
# Message from example.com.
|
73
|
-
# Unable to deliver message to the following address(es).
|
74
|
-
#
|
75
|
-
# <kijitora@example.com>:
|
76
67
|
# This user doesn't have a example.com account (kijitora@example.com) [0]
|
77
|
-
v
|
78
|
-
|
79
|
-
if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]:\z/)
|
80
|
-
# <kijitora@example.com>:
|
81
|
-
if v['recipient']
|
82
|
-
# There are multiple recipient addresses in the message body.
|
83
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
84
|
-
v = dscontents[-1]
|
85
|
-
end
|
86
|
-
v['recipient'] = cv[1]
|
87
|
-
recipients += 1
|
88
|
-
else
|
89
|
-
# This user doesn't have a example.com account (kijitora@example.com) [0]
|
90
|
-
v['diagnosis'] ||= ''
|
91
|
-
v['diagnosis'] << ' ' << e
|
92
|
-
end
|
68
|
+
v['diagnosis'] ||= ''
|
69
|
+
v['diagnosis'] << ' ' << e
|
93
70
|
end
|
94
71
|
end
|
95
72
|
return nil unless recipients > 0
|
@@ -100,8 +77,7 @@ module Sisimai::Lhost
|
|
100
77
|
e.each_key { |a| e[a] ||= '' }
|
101
78
|
end
|
102
79
|
|
103
|
-
|
104
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
80
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
105
81
|
end
|
106
82
|
|
107
83
|
end
|
data/lib/sisimai/lhost/x3.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: ['Content-Type: message/rfc822'],
|
13
|
-
}.freeze
|
10
|
+
ReBackbone = %r|^Content-Type:[ ]message/rfc822|.freeze
|
11
|
+
StartingOf = { message: [' This is an automatically generated Delivery Status Notification.'] }.freeze
|
14
12
|
|
15
13
|
def description; return 'Unknown MTA #3'; end
|
16
14
|
def smtpagent; return Sisimai::Lhost.smtpagent(self); end
|
@@ -32,80 +30,59 @@ module Sisimai::Lhost
|
|
32
30
|
return nil unless mhead['from'].start_with?('Mail Delivery System')
|
33
31
|
|
34
32
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
35
|
-
|
36
|
-
|
37
|
-
blanklines = 0 # (Integer) The number of blank lines
|
33
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
34
|
+
bodyslices = emailsteak[0].split("\n")
|
38
35
|
readcursor = 0 # (Integer) Points the current cursor position
|
39
36
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
40
37
|
v = nil
|
41
38
|
|
42
|
-
while e =
|
39
|
+
while e = bodyslices.shift do
|
40
|
+
# Read error messages and delivery status lines from the head of the email
|
41
|
+
# to the previous line of the beginning of the original message.
|
43
42
|
if readcursor == 0
|
44
43
|
# Beginning of the bounce message or delivery status part
|
45
|
-
if e.start_with?(StartingOf[:message][0])
|
46
|
-
|
47
|
-
next
|
48
|
-
end
|
44
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
45
|
+
next
|
49
46
|
end
|
47
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
48
|
+
next if e.empty?
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
# ============================================================================
|
51
|
+
# This is an automatically generated Delivery Status Notification.
|
52
|
+
#
|
53
|
+
# Delivery to the following recipients failed permanently:
|
54
|
+
#
|
55
|
+
# * kijitora@example.com
|
56
|
+
#
|
57
|
+
#
|
58
|
+
# ============================================================================
|
59
|
+
# Technical details:
|
60
|
+
#
|
61
|
+
# SMTP:RCPT host 192.0.2.8: 553 5.3.0 <kijitora@example.com>... No such user here
|
62
|
+
#
|
63
|
+
#
|
64
|
+
# ============================================================================
|
65
|
+
v = dscontents[-1]
|
58
66
|
|
59
|
-
if
|
60
|
-
#
|
61
|
-
if
|
62
|
-
|
63
|
-
|
64
|
-
|
67
|
+
if cv = e.match(/\A[ \t]+[*][ ]([^ ]+[@][^ ]+)\z/)
|
68
|
+
# * kijitora@example.com
|
69
|
+
if v['recipient']
|
70
|
+
# There are multiple recipient addresses in the message body.
|
71
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
72
|
+
v = dscontents[-1]
|
65
73
|
end
|
66
|
-
|
74
|
+
v['recipient'] = cv[1]
|
75
|
+
recipients += 1
|
67
76
|
else
|
68
|
-
#
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# This is an automatically generated Delivery Status Notification.
|
74
|
-
#
|
75
|
-
# Delivery to the following recipients failed permanently:
|
76
|
-
#
|
77
|
-
# * kijitora@example.com
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# ============================================================================
|
81
|
-
# Technical details:
|
82
|
-
#
|
83
|
-
# SMTP:RCPT host 192.0.2.8: 553 5.3.0 <kijitora@example.com>... No such user here
|
84
|
-
#
|
85
|
-
#
|
86
|
-
# ============================================================================
|
87
|
-
v = dscontents[-1]
|
88
|
-
|
89
|
-
if cv = e.match(/\A[ \t]+[*][ ]([^ ]+[@][^ ]+)\z/)
|
90
|
-
# * kijitora@example.com
|
91
|
-
if v['recipient']
|
92
|
-
# There are multiple recipient addresses in the message body.
|
93
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
94
|
-
v = dscontents[-1]
|
95
|
-
end
|
96
|
-
v['recipient'] = cv[1]
|
97
|
-
recipients += 1
|
98
|
-
else
|
99
|
-
# Detect error message
|
100
|
-
if cv = e.match(/\ASMTP:([^ ]+)[ ](.+)\z/)
|
101
|
-
# SMTP:RCPT host 192.0.2.8: 553 5.3.0 <kijitora@example.com>... No such user here
|
102
|
-
v['command'] = cv[1].upcase
|
103
|
-
v['diagnosis'] = cv[2]
|
77
|
+
# Detect error message
|
78
|
+
if cv = e.match(/\ASMTP:([^ ]+)[ ](.+)\z/)
|
79
|
+
# SMTP:RCPT host 192.0.2.8: 553 5.3.0 <kijitora@example.com>... No such user here
|
80
|
+
v['command'] = cv[1].upcase
|
81
|
+
v['diagnosis'] = cv[2]
|
104
82
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
end
|
83
|
+
elsif cv = e.match(/\ARouting: (.+)/)
|
84
|
+
# Routing: Could not find a gateway for kijitora@example.co.jp
|
85
|
+
v['diagnosis'] = cv[1]
|
109
86
|
end
|
110
87
|
end
|
111
88
|
end
|
@@ -118,8 +95,7 @@ module Sisimai::Lhost
|
|
118
95
|
e.each_key { |a| e[a] ||= '' }
|
119
96
|
end
|
120
97
|
|
121
|
-
|
122
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
98
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
123
99
|
end
|
124
100
|
|
125
101
|
end
|
data/lib/sisimai/lhost/x4.rb
CHANGED
@@ -8,10 +8,8 @@ module Sisimai::Lhost
|
|
8
8
|
require 'sisimai/lhost'
|
9
9
|
|
10
10
|
Indicators = Sisimai::Lhost.INDICATORS
|
11
|
-
|
12
|
-
|
13
|
-
rfc822: ['--- Below this line is a copy of the message.', '--- Original message follows.'],
|
14
|
-
}.freeze
|
11
|
+
ReBackbone = %r/^---[ ](?:Below this line is a copy of the message|Original message follows)[.]/.freeze
|
12
|
+
StartingOf = { error: ['Remote host said:'] }.freeze
|
15
13
|
MarkingsOf = {
|
16
14
|
# qmail-remote.c:248| if (code >= 500) {
|
17
15
|
# qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
|
@@ -146,70 +144,49 @@ module Sisimai::Lhost
|
|
146
144
|
return nil unless match > 0
|
147
145
|
|
148
146
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
149
|
-
|
150
|
-
|
151
|
-
blanklines = 0 # (Integer) The number of blank lines
|
147
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
148
|
+
bodyslices = emailsteak[0].split("\n")
|
152
149
|
readcursor = 0 # (Integer) Points the current cursor position
|
153
150
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
154
151
|
v = nil
|
155
152
|
|
156
|
-
while e =
|
153
|
+
while e = bodyslices.shift do
|
154
|
+
# Read error messages and delivery status lines from the head of the email
|
155
|
+
# to the previous line of the beginning of the original message.
|
157
156
|
if readcursor == 0
|
158
157
|
# Beginning of the bounce message or delivery status part
|
159
|
-
if e =~ MarkingsOf[:message]
|
160
|
-
|
161
|
-
next
|
162
|
-
end
|
158
|
+
readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
|
159
|
+
next
|
163
160
|
end
|
161
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
162
|
+
next if e.empty?
|
164
163
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
if readcursor & Indicators[:'message-rfc822'] > 0
|
174
|
-
# Inside of the original message part
|
175
|
-
if e.empty?
|
176
|
-
blanklines += 1
|
177
|
-
break if blanklines > 1
|
178
|
-
next
|
179
|
-
end
|
180
|
-
rfc822list << e
|
181
|
-
else
|
182
|
-
# Error message part
|
183
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
184
|
-
next if e.empty?
|
164
|
+
# <kijitora@example.jp>:
|
165
|
+
# 192.0.2.153 does not like recipient.
|
166
|
+
# Remote host said: 550 5.1.1 <kijitora@example.jp>... User Unknown
|
167
|
+
# Giving up on 192.0.2.153.
|
168
|
+
v = dscontents[-1]
|
185
169
|
|
170
|
+
if cv = e.match(/\A(?:To[ ]*:)?[<](.+[@].+)[>]:[ ]*\z/)
|
186
171
|
# <kijitora@example.jp>:
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
if v['recipient']
|
195
|
-
# There are multiple recipient addresses in the message body.
|
196
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
197
|
-
v = dscontents[-1]
|
198
|
-
end
|
199
|
-
v['recipient'] = cv[1]
|
200
|
-
recipients += 1
|
172
|
+
if v['recipient']
|
173
|
+
# There are multiple recipient addresses in the message body.
|
174
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
175
|
+
v = dscontents[-1]
|
176
|
+
end
|
177
|
+
v['recipient'] = cv[1]
|
178
|
+
recipients += 1
|
201
179
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
180
|
+
elsif dscontents.size == recipients
|
181
|
+
# Append error message
|
182
|
+
next if e.empty?
|
183
|
+
v['diagnosis'] ||= ''
|
184
|
+
v['diagnosis'] << e + ' '
|
185
|
+
v['alterrors'] = e if e.start_with?(StartingOf[:error][0])
|
208
186
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
end
|
187
|
+
next if v['rhost']
|
188
|
+
next unless cv = e.match(ReHost)
|
189
|
+
v['rhost'] = cv[1]
|
213
190
|
end
|
214
191
|
end
|
215
192
|
return nil unless recipients > 0
|
@@ -280,8 +257,7 @@ module Sisimai::Lhost
|
|
280
257
|
e.each_key { |a| e[a] ||= '' }
|
281
258
|
end
|
282
259
|
|
283
|
-
|
284
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
260
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
285
261
|
end
|
286
262
|
|
287
263
|
end
|
data/lib/sisimai/lhost/x5.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: ['Content-Type: message/rfc822'],
|
13
|
-
}.freeze
|
10
|
+
ReBackbone = %r|^Content-Type:[ ]message/rfc822|.freeze
|
11
|
+
StartingOf = { message: ['Content-Type: message/delivery-status'] }.freeze
|
14
12
|
|
15
13
|
def description; return 'Unknown MTA #5'; end
|
16
14
|
def smtpagent; return Sisimai::Lhost.smtpagent(self); end
|
@@ -51,88 +49,63 @@ module Sisimai::Lhost
|
|
51
49
|
require 'sisimai/rfc1894'
|
52
50
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
53
51
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
blanklines = 0 # (Integer) The number of blank lines
|
52
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
53
|
+
bodyslices = emailsteak[0].split("\n")
|
54
|
+
readslices = ['']
|
58
55
|
readcursor = 0 # (Integer) Points the current cursor position
|
59
56
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
60
57
|
v = nil
|
61
58
|
|
62
|
-
while e =
|
63
|
-
#
|
64
|
-
|
65
|
-
|
59
|
+
while e = bodyslices.shift do
|
60
|
+
# Read error messages and delivery status lines from the head of the email
|
61
|
+
# to the previous line of the beginning of the original message.
|
62
|
+
readslices << e # Save the current line for the next loop
|
66
63
|
|
67
64
|
if readcursor == 0
|
68
65
|
# Beginning of the bounce message or message/delivery-status part
|
69
|
-
if e.start_with?(StartingOf[:message][0])
|
70
|
-
|
71
|
-
next
|
72
|
-
end
|
66
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
67
|
+
next
|
73
68
|
end
|
69
|
+
next if (readcursor & Indicators['deliverystatus']) == 0
|
70
|
+
next if e.empty?
|
74
71
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
next
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
if readcursor & Indicators[:'message-rfc822'] > 0
|
84
|
-
# message/delivery-status part
|
85
|
-
next if e.empty?
|
72
|
+
v = dscontents[-1]
|
73
|
+
if f = Sisimai::RFC1894.match(e)
|
74
|
+
# "e" matched with any field defined in RFC3464
|
75
|
+
next unless o = Sisimai::RFC1894.field(e)
|
86
76
|
v = dscontents[-1]
|
87
77
|
|
88
|
-
if
|
89
|
-
#
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
if o[-1] == 'addr'
|
78
|
+
if o[-1] == 'addr'
|
79
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
80
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
81
|
+
if o[0] == 'final-recipient'
|
94
82
|
# Final-Recipient: rfc822; kijitora@example.jp
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
# There are multiple recipient addresses in the message body.
|
100
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
101
|
-
v = dscontents[-1]
|
102
|
-
end
|
103
|
-
v['recipient'] = o[2]
|
104
|
-
recipients += 1
|
105
|
-
else
|
106
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
107
|
-
v['alias'] = o[2]
|
83
|
+
if v['recipient']
|
84
|
+
# There are multiple recipient addresses in the message body.
|
85
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
86
|
+
v = dscontents[-1]
|
108
87
|
end
|
109
|
-
|
110
|
-
|
111
|
-
v['spec'] = o[1]
|
112
|
-
v['diagnosis'] = o[2]
|
88
|
+
v['recipient'] = o[2]
|
89
|
+
recipients += 1
|
113
90
|
else
|
114
|
-
#
|
115
|
-
|
116
|
-
v[fieldtable[o[0]]] = o[2]
|
91
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
92
|
+
v['alias'] = o[2]
|
117
93
|
end
|
94
|
+
elsif o[-1] == 'code'
|
95
|
+
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
96
|
+
v['spec'] = o[1]
|
97
|
+
v['diagnosis'] = o[2]
|
118
98
|
else
|
119
|
-
#
|
120
|
-
next unless
|
121
|
-
|
122
|
-
v['diagnosis'] << ' ' << cv[1]
|
123
|
-
havepassed[-1] = 'Diagnostic-Code: ' << e
|
99
|
+
# Other DSN fields defined in RFC3464
|
100
|
+
next unless fieldtable[o[0]]
|
101
|
+
v[fieldtable[o[0]]] = o[2]
|
124
102
|
end
|
125
103
|
else
|
126
|
-
#
|
127
|
-
next unless
|
128
|
-
next
|
129
|
-
|
130
|
-
|
131
|
-
blanklines += 1
|
132
|
-
break if blanklines > 1
|
133
|
-
next
|
134
|
-
end
|
135
|
-
rfc822list << e
|
104
|
+
# Continued line of the value of Diagnostic-Code field
|
105
|
+
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
106
|
+
next unless cv = e.match(/\A[ \t]+(.+)\z/)
|
107
|
+
v['diagnosis'] << ' ' << cv[1]
|
108
|
+
readslices[-1] = 'Diagnostic-Code: ' << e
|
136
109
|
end
|
137
110
|
end
|
138
111
|
return nil unless recipients > 0
|
@@ -143,8 +116,7 @@ module Sisimai::Lhost
|
|
143
116
|
e.each_key { |a| e[a] ||= '' }
|
144
117
|
end
|
145
118
|
|
146
|
-
|
147
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
119
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
148
120
|
end
|
149
121
|
|
150
122
|
end
|