sisimai 4.25.4-java → 4.25.5-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 +5 -5
- 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 +27 -21
- 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/notes.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: ['------- Returned Message '],
|
13
|
-
}.freeze
|
10
|
+
ReBackbone = %r|^-------[ ]Returned[ ]Message[ ]--------|.freeze
|
11
|
+
StartingOf = { message: ['------- Failure Reasons '] }.freeze
|
14
12
|
MessagesOf = {
|
15
13
|
'userunknown' => [
|
16
14
|
'User not listed in public Name & Address Book',
|
@@ -38,9 +36,8 @@ module Sisimai::Lhost
|
|
38
36
|
return nil unless mhead['subject'].start_with?('Undeliverable message')
|
39
37
|
|
40
38
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
41
|
-
|
42
|
-
|
43
|
-
blanklines = 0 # (Integer) The number of blank lines
|
39
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
40
|
+
bodyslices = emailsteak[0].split("\n")
|
44
41
|
readcursor = 0 # (Integer) Points the current cursor position
|
45
42
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
46
43
|
characters = '' # (String) Character set name of the bounce mail
|
@@ -48,96 +45,71 @@ module Sisimai::Lhost
|
|
48
45
|
encodedmsg = ''
|
49
46
|
v = nil
|
50
47
|
|
51
|
-
|
48
|
+
if cv = mhead['content-type'].match(/\A.+;[ ]*charset=(.+)\z/)
|
49
|
+
# Get character set name
|
50
|
+
# Content-Type: text/plain; charset=ISO-2022-JP
|
51
|
+
characters = cv[1].downcase
|
52
|
+
end
|
53
|
+
|
54
|
+
while e = bodyslices.shift do
|
55
|
+
# Read error messages and delivery status lines from the head of the email
|
56
|
+
# to the previous line of the beginning of the original message.
|
52
57
|
if readcursor == 0
|
53
58
|
# Beginning of the bounce message or delivery status part
|
54
|
-
if e.start_with?(StartingOf[:message][0])
|
55
|
-
|
56
|
-
next
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
if (readcursor & Indicators[:'message-rfc822']) == 0
|
61
|
-
# Beginning of the original message part
|
62
|
-
if e.start_with?(StartingOf[:rfc822][0])
|
63
|
-
readcursor |= Indicators[:'message-rfc822']
|
64
|
-
next
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
if characters.empty?
|
69
|
-
# Get character set name
|
70
|
-
if cv = mhead['content-type'].match(/\A.+;[ ]*charset=(.+)\z/)
|
71
|
-
# Content-Type: text/plain; charset=ISO-2022-JP
|
72
|
-
characters = cv[1].downcase
|
73
|
-
end
|
59
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
60
|
+
next
|
74
61
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
62
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
63
|
+
|
64
|
+
# ------- Failure Reasons --------
|
65
|
+
#
|
66
|
+
# User not listed in public Name & Address Book
|
67
|
+
# kijitora@notes.example.jp
|
68
|
+
#
|
69
|
+
# ------- Returned Message --------
|
70
|
+
v = dscontents[-1]
|
71
|
+
if e =~ /\A[^ ]+[@][^ ]+/
|
72
|
+
# kijitora@notes.example.jp
|
73
|
+
if v['recipient']
|
74
|
+
# There are multiple recipient addresses in the message body.
|
75
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
76
|
+
v = dscontents[-1]
|
82
77
|
end
|
83
|
-
|
78
|
+
v['recipient'] ||= e
|
79
|
+
recipients += 1
|
84
80
|
else
|
85
|
-
|
86
|
-
next if (
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
# kijitora@notes.example.jp
|
97
|
-
if v['recipient']
|
98
|
-
# There are multiple recipient addresses in the message body.
|
99
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
100
|
-
v = dscontents[-1]
|
101
|
-
end
|
102
|
-
v['recipient'] ||= e
|
103
|
-
recipients += 1
|
104
|
-
else
|
105
|
-
next if e.empty?
|
106
|
-
next if e.start_with?('-')
|
107
|
-
|
108
|
-
if e =~ /[^\x20-\x7e]/
|
109
|
-
# Error message is not ISO-8859-1
|
110
|
-
if characters.size > 0
|
111
|
-
# Try to convert string
|
112
|
-
begin
|
113
|
-
encodedmsg = e.encode('UTF-8', characters)
|
114
|
-
rescue
|
115
|
-
# Failed to convert
|
116
|
-
encodedmsg = removedmsg
|
117
|
-
end
|
118
|
-
else
|
119
|
-
# No character set in Content-Type header
|
81
|
+
next if e.empty?
|
82
|
+
next if e.start_with?('-')
|
83
|
+
|
84
|
+
if e =~ /[^\x20-\x7e]/
|
85
|
+
# Error message is not ISO-8859-1
|
86
|
+
if characters.size > 0
|
87
|
+
# Try to convert string
|
88
|
+
begin
|
89
|
+
encodedmsg = e.encode('UTF-8', characters)
|
90
|
+
rescue
|
91
|
+
# Failed to convert
|
120
92
|
encodedmsg = removedmsg
|
121
93
|
end
|
122
|
-
v['diagnosis'] ||= ''
|
123
|
-
v['diagnosis'] << encodedmsg
|
124
94
|
else
|
125
|
-
#
|
126
|
-
|
127
|
-
v['diagnosis'] << e
|
95
|
+
# No character set in Content-Type header
|
96
|
+
encodedmsg = removedmsg
|
128
97
|
end
|
98
|
+
v['diagnosis'] ||= ''
|
99
|
+
v['diagnosis'] << encodedmsg
|
100
|
+
else
|
101
|
+
# Error message does not include multi-byte character
|
102
|
+
v['diagnosis'] ||= ''
|
103
|
+
v['diagnosis'] << e
|
129
104
|
end
|
130
105
|
end
|
131
106
|
end
|
132
107
|
|
133
108
|
unless recipients > 0
|
134
109
|
# Fallback: Get the recpient address from RFC822 part
|
135
|
-
|
136
|
-
next unless cv = e.match(/^To:[ ]*(.+)$/m)
|
137
|
-
|
110
|
+
if cv = emailsteak[1].match(/^To:[ ]*(.+)$/)
|
138
111
|
v['recipient'] = Sisimai::Address.s3s4(cv[1])
|
139
112
|
recipients += 1 unless v['recipient'].empty?
|
140
|
-
break
|
141
113
|
end
|
142
114
|
end
|
143
115
|
return nil unless recipients > 0
|
@@ -157,8 +129,7 @@ module Sisimai::Lhost
|
|
157
129
|
e.each_key { |a| e[a] ||= '' }
|
158
130
|
end
|
159
131
|
|
160
|
-
|
161
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
132
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
162
133
|
end
|
163
134
|
|
164
135
|
end
|
@@ -8,8 +8,8 @@ module Sisimai::Lhost
|
|
8
8
|
require 'sisimai/lhost'
|
9
9
|
|
10
10
|
Indicators = Sisimai::Lhost.INDICATORS
|
11
|
+
ReBackbone = %r|^Content-Type:[ ]message/rfc822|.freeze
|
11
12
|
StartingOf = {
|
12
|
-
rfc822: ['Content-Type: message/rfc822'],
|
13
13
|
error: ['Diagnostic information for administrators:'],
|
14
14
|
eoerr: ['Original message headers:'],
|
15
15
|
}.freeze
|
@@ -20,6 +20,15 @@ module Sisimai::Lhost
|
|
20
20
|
)
|
21
21
|
}x,
|
22
22
|
}.freeze
|
23
|
+
Headers365 = %w[
|
24
|
+
x-ms-exchange-message-is-ndr
|
25
|
+
x-microsoft-antispam-prvs
|
26
|
+
x-exchange-antispam-report-test
|
27
|
+
x-exchange-antispam-report-cfa-test
|
28
|
+
x-ms-exchange-crosstenant-originalarrivaltime
|
29
|
+
x-ms-exchange-crosstenant-fromentityheader
|
30
|
+
x-ms-exchange-transport-crosstenantheadersstamped
|
31
|
+
]
|
23
32
|
StatusList = {
|
24
33
|
# https://support.office.com/en-us/article/Email-non-delivery-reports-in-Office-365-51daa6b9-2e35-49c4-a0c9-df85bf8533c3
|
25
34
|
%r/\A4[.]4[.]7\z/ => 'expired',
|
@@ -56,7 +65,6 @@ module Sisimai::Lhost
|
|
56
65
|
|
57
66
|
def description; return 'Microsoft Office 365: https://office.microsoft.com/'; end
|
58
67
|
def smtpagent; return Sisimai::Lhost.smtpagent(self); end
|
59
|
-
|
60
68
|
def headerlist
|
61
69
|
# X-MS-Exchange-Message-Is-Ndr:
|
62
70
|
# X-Microsoft-Antispam-PRVS: <....@...outlook.com>
|
@@ -92,13 +100,11 @@ module Sisimai::Lhost
|
|
92
100
|
tryto = %r/.+[.](?:outbound[.]protection|prod)[.]outlook[.]com\b/
|
93
101
|
match = 0
|
94
102
|
match += 1 if mhead['subject'].include?('Undeliverable:')
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
match += 1 if mhead['x-ms-exchange-crosstenant-fromentityheader']
|
101
|
-
match += 1 if mhead['x-ms-exchange-transport-crosstenantheadersstamped']
|
103
|
+
Headers365.each do |e|
|
104
|
+
next if mhead[e].nil?
|
105
|
+
next if mhead[e].empty?
|
106
|
+
match += 1
|
107
|
+
end
|
102
108
|
match += 1 if mhead['received'].any? { |a| a =~ tryto }
|
103
109
|
if mhead['message-id']
|
104
110
|
# Message-ID: <00000000-0000-0000-0000-000000000000@*.*.prod.outlook.com>
|
@@ -111,9 +117,8 @@ module Sisimai::Lhost
|
|
111
117
|
permessage = {} # (Hash) Store values of each Per-Message field
|
112
118
|
|
113
119
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
114
|
-
|
115
|
-
|
116
|
-
blanklines = 0 # (Integer) The number of blank lines
|
120
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
121
|
+
bodyslices = emailsteak[0].split("\n")
|
117
122
|
readcursor = 0 # (Integer) Points the current cursor position
|
118
123
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
119
124
|
connheader = {}
|
@@ -121,85 +126,64 @@ module Sisimai::Lhost
|
|
121
126
|
htmlbegins = false # (Boolean) Flag for HTML part
|
122
127
|
v = nil
|
123
128
|
|
124
|
-
while e =
|
129
|
+
while e = bodyslices.shift do
|
130
|
+
# Read error messages and delivery status lines from the head of the email
|
131
|
+
# to the previous line of the beginning of the original message.
|
125
132
|
if readcursor == 0
|
126
133
|
# Beginning of the bounce message or delivery status part
|
127
|
-
if e =~ MarkingsOf[:message]
|
128
|
-
|
129
|
-
next
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
if (readcursor & Indicators[:'message-rfc822']) == 0
|
134
|
-
# Beginning of the original message part
|
135
|
-
if e == StartingOf[:rfc822][0]
|
136
|
-
readcursor |= Indicators[:'message-rfc822']
|
137
|
-
next
|
138
|
-
end
|
134
|
+
readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
|
135
|
+
next
|
139
136
|
end
|
137
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
138
|
+
next if e.empty?
|
140
139
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
next
|
147
|
-
end
|
148
|
-
rfc822list << e
|
149
|
-
else
|
150
|
-
# Error message part
|
151
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
152
|
-
next if e.empty?
|
140
|
+
# kijitora@example.com<mailto:kijitora@example.com>
|
141
|
+
# The email address wasn't found at the destination domain. It might
|
142
|
+
# be misspelled or it might not exist any longer. Try retyping the
|
143
|
+
# address and resending the message.
|
144
|
+
v = dscontents[-1]
|
153
145
|
|
146
|
+
if cv = e.match(/\A.+[@].+[<]mailto:(.+[@].+)[>]\z/)
|
154
147
|
# kijitora@example.com<mailto:kijitora@example.com>
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
if v['recipient']
|
163
|
-
# There are multiple recipient addresses in the message body.
|
164
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
165
|
-
v = dscontents[-1]
|
166
|
-
end
|
167
|
-
v['recipient'] = cv[1]
|
168
|
-
recipients += 1
|
148
|
+
if v['recipient']
|
149
|
+
# There are multiple recipient addresses in the message body.
|
150
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
151
|
+
v = dscontents[-1]
|
152
|
+
end
|
153
|
+
v['recipient'] = cv[1]
|
154
|
+
recipients += 1
|
169
155
|
|
170
|
-
|
171
|
-
|
172
|
-
|
156
|
+
elsif cv = e.match(/\AGenerating server: (.+)\z/)
|
157
|
+
# Generating server: FFFFFFFFFFFF.e0.prod.outlook.com
|
158
|
+
connheader['lhost'] = cv[1].downcase
|
159
|
+
else
|
160
|
+
if endoferror
|
161
|
+
# After "Original message headers:"
|
162
|
+
next unless f = Sisimai::RFC1894.match(e)
|
163
|
+
next unless o = Sisimai::RFC1894.field(e)
|
164
|
+
next unless fieldtable[o[0]]
|
165
|
+
next if o[0] =~ /\A(?:diagnostic-code|final-recipient)\z/
|
166
|
+
v[fieldtable[o[0]]] = o[2]
|
167
|
+
|
168
|
+
next unless f == 1
|
169
|
+
permessage[fieldtable[o[0]]] = o[2]
|
173
170
|
else
|
174
|
-
if
|
175
|
-
#
|
176
|
-
|
177
|
-
next unless o = Sisimai::RFC1894.field(e)
|
178
|
-
next unless fieldtable.key?(o[0])
|
179
|
-
next if o[0] =~ /\A(?:diagnostic-code|final-recipient)\z/
|
180
|
-
v[fieldtable[o[0]]] = o[2]
|
181
|
-
|
182
|
-
next unless f == 1
|
183
|
-
permessage[fieldtable[o[0]]] = o[2]
|
171
|
+
if e == StartingOf[:error][0]
|
172
|
+
# Diagnostic information for administrators:
|
173
|
+
v['diagnosis'] = e
|
184
174
|
else
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
#
|
191
|
-
|
192
|
-
next
|
193
|
-
if e == StartingOf[:eoerr][0]
|
194
|
-
# Original message headers:
|
195
|
-
endoferror = true
|
196
|
-
next
|
197
|
-
end
|
198
|
-
v['diagnosis'] << ' ' << e
|
175
|
+
# kijitora@example.com
|
176
|
+
# Remote Server returned '550 5.1.10 RESOLVER.ADR.RecipientNotFound; Recipien=
|
177
|
+
# t not found by SMTP address lookup'
|
178
|
+
next unless v['diagnosis']
|
179
|
+
if e == StartingOf[:eoerr][0]
|
180
|
+
# Original message headers:
|
181
|
+
endoferror = true
|
182
|
+
next
|
199
183
|
end
|
184
|
+
v['diagnosis'] << ' ' << e
|
200
185
|
end
|
201
186
|
end
|
202
|
-
|
203
187
|
end
|
204
188
|
end
|
205
189
|
return nil unless recipients > 0
|
@@ -233,8 +217,7 @@ module Sisimai::Lhost
|
|
233
217
|
end
|
234
218
|
end
|
235
219
|
|
236
|
-
|
237
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
220
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
238
221
|
end
|
239
222
|
|
240
223
|
end
|
@@ -7,6 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
require 'sisimai/lhost'
|
8
8
|
|
9
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
+
ReBackbone = %r|^[ ]+Below is a copy of the original message:|.freeze
|
10
11
|
StartingOf = {
|
11
12
|
# http://www.openbsd.org/cgi-bin/man.cgi?query=smtpd&sektion=8
|
12
13
|
# opensmtpd-5.4.2p1/smtpd/
|
@@ -34,7 +35,6 @@ module Sisimai::Lhost
|
|
34
35
|
# bounce.c/338: " Your message was relayed to these recipients.\n\n";
|
35
36
|
# bounce.c/339:
|
36
37
|
message: [' This is the MAILER-DAEMON, please DO NOT REPLY to this '],
|
37
|
-
rfc822: [' Below is a copy of the original message:'],
|
38
38
|
}.freeze
|
39
39
|
MessagesOf = {
|
40
40
|
# smtpd/queue.c:221| envelope_set_errormsg(&evp, "Envelope expired");
|
@@ -86,66 +86,45 @@ module Sisimai::Lhost
|
|
86
86
|
return nil unless mhead['received'].any? { |a| a.include?(' (OpenSMTPD) with ') }
|
87
87
|
|
88
88
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
89
|
-
|
90
|
-
|
91
|
-
blanklines = 0 # (Integer) The number of blank lines
|
89
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
90
|
+
bodyslices = emailsteak[0].split("\n")
|
92
91
|
readcursor = 0 # (Integer) Points the current cursor position
|
93
92
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
94
93
|
v = nil
|
95
94
|
|
96
|
-
while e =
|
95
|
+
while e = bodyslices.shift do
|
96
|
+
# Read error messages and delivery status lines from the head of the email
|
97
|
+
# to the previous line of the beginning of the original message.
|
97
98
|
if readcursor == 0
|
98
99
|
# Beginning of the bounce message or delivery status part
|
99
|
-
if e.start_with?(StartingOf[:message][0])
|
100
|
-
|
101
|
-
next
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
if (readcursor & Indicators[:'message-rfc822']) == 0
|
106
|
-
# Beginning of the original message part
|
107
|
-
if e.start_with?(StartingOf[:rfc822][0])
|
108
|
-
readcursor |= Indicators[:'message-rfc822']
|
109
|
-
next
|
110
|
-
end
|
100
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
101
|
+
next
|
111
102
|
end
|
103
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
104
|
+
next if e.empty?
|
112
105
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
next if e.empty?
|
106
|
+
# Hi!
|
107
|
+
#
|
108
|
+
# This is the MAILER-DAEMON, please DO NOT REPLY to this e-mail.
|
109
|
+
#
|
110
|
+
# An error has occurred while attempting to deliver a message for
|
111
|
+
# the following list of recipients:
|
112
|
+
#
|
113
|
+
# kijitora@example.jp: 550 5.2.2 <kijitora@example>... Mailbox Full
|
114
|
+
#
|
115
|
+
# Below is a copy of the original message:
|
116
|
+
v = dscontents[-1]
|
125
117
|
|
126
|
-
|
127
|
-
#
|
128
|
-
# This is the MAILER-DAEMON, please DO NOT REPLY to this e-mail.
|
129
|
-
#
|
130
|
-
# An error has occurred while attempting to deliver a message for
|
131
|
-
# the following list of recipients:
|
132
|
-
#
|
118
|
+
if cv = e.match(/\A([^ ]+?[@][^ ]+?):?[ ](.+)\z/)
|
133
119
|
# kijitora@example.jp: 550 5.2.2 <kijitora@example>... Mailbox Full
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
if cv = e.match(/\A([^ ]+?[@][^ ]+?):?[ ](.+)\z/)
|
139
|
-
# kijitora@example.jp: 550 5.2.2 <kijitora@example>... Mailbox Full
|
140
|
-
if v['recipient']
|
141
|
-
# There are multiple recipient addresses in the message body.
|
142
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
143
|
-
v = dscontents[-1]
|
144
|
-
end
|
145
|
-
v['recipient'] = cv[1]
|
146
|
-
v['diagnosis'] = cv[2]
|
147
|
-
recipients += 1
|
120
|
+
if v['recipient']
|
121
|
+
# There are multiple recipient addresses in the message body.
|
122
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
123
|
+
v = dscontents[-1]
|
148
124
|
end
|
125
|
+
v['recipient'] = cv[1]
|
126
|
+
v['diagnosis'] = cv[2]
|
127
|
+
recipients += 1
|
149
128
|
end
|
150
129
|
end
|
151
130
|
return nil unless recipients > 0
|
@@ -163,8 +142,7 @@ module Sisimai::Lhost
|
|
163
142
|
e.each_key { |a| e[a] ||= '' }
|
164
143
|
end
|
165
144
|
|
166
|
-
|
167
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
145
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
168
146
|
end
|
169
147
|
|
170
148
|
end
|