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
@@ -8,10 +8,8 @@ module Sisimai::Lhost
|
|
8
8
|
require 'sisimai/lhost'
|
9
9
|
|
10
10
|
Indicators = Sisimai::Lhost.INDICATORS
|
11
|
-
|
12
|
-
|
13
|
-
rfc822: ['Content-Type: message/rfc822'],
|
14
|
-
}.freeze
|
11
|
+
ReBackbone = %r|^Content-Type: message/rfc822|.freeze
|
12
|
+
StartingOf = { message: ['This is an automatically generated Delivery Status Notification'] }.freeze
|
15
13
|
MessagesOf = {
|
16
14
|
'hostunknown' => ['The mail could not be delivered to the recipient because the domain is not reachable'],
|
17
15
|
'userunknown' => ['Requested action not taken: mailbox unavailable'],
|
@@ -49,89 +47,66 @@ module Sisimai::Lhost
|
|
49
47
|
permessage = {} # (Hash) Store values of each Per-Message field
|
50
48
|
|
51
49
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
blanklines = 0 # (Integer) The number of blank lines
|
50
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
51
|
+
bodyslices = emailsteak[0].split("\n")
|
52
|
+
readslices = ['']
|
56
53
|
readcursor = 0 # (Integer) Points the current cursor position
|
57
54
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
58
55
|
v = nil
|
59
56
|
|
60
|
-
while e =
|
61
|
-
#
|
62
|
-
|
63
|
-
|
57
|
+
while e = bodyslices.shift do
|
58
|
+
# Read error messages and delivery status lines from the head of the email
|
59
|
+
# to the previous line of the beginning of the original message.
|
60
|
+
readslices << e # Save the current line for the next loop
|
64
61
|
|
65
62
|
if readcursor == 0
|
66
63
|
# Beginning of the bounce message or message/delivery-status part
|
67
|
-
if e.start_with?(StartingOf[:message][0])
|
68
|
-
|
69
|
-
next
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
if (readcursor & Indicators[:'message-rfc822']) == 0
|
74
|
-
# Beginning of the original message part(message/rfc822)
|
75
|
-
if e == StartingOf[:rfc822][0]
|
76
|
-
readcursor |= Indicators[:'message-rfc822']
|
77
|
-
next
|
78
|
-
end
|
64
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
65
|
+
next
|
79
66
|
end
|
80
|
-
|
81
|
-
if
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
next if e.empty?
|
93
|
-
|
94
|
-
if f = Sisimai::RFC1894.match(e)
|
95
|
-
# "e" matched with any field defined in RFC3464
|
96
|
-
next unless o = Sisimai::RFC1894.field(e)
|
97
|
-
v = dscontents[-1]
|
98
|
-
|
99
|
-
if o[-1] == 'addr'
|
67
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
68
|
+
next if e.empty?
|
69
|
+
|
70
|
+
if f = Sisimai::RFC1894.match(e)
|
71
|
+
# "e" matched with any field defined in RFC3464
|
72
|
+
next unless o = Sisimai::RFC1894.field(e)
|
73
|
+
v = dscontents[-1]
|
74
|
+
|
75
|
+
if o[-1] == 'addr'
|
76
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
77
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
78
|
+
if o[0] == 'final-recipient'
|
100
79
|
# Final-Recipient: rfc822; kijitora@example.jp
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
# There are multiple recipient addresses in the message body.
|
106
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
107
|
-
v = dscontents[-1]
|
108
|
-
end
|
109
|
-
v['recipient'] = o[2]
|
110
|
-
recipients += 1
|
111
|
-
else
|
112
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
113
|
-
v['alias'] = o[2]
|
80
|
+
if v['recipient']
|
81
|
+
# There are multiple recipient addresses in the message body.
|
82
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
83
|
+
v = dscontents[-1]
|
114
84
|
end
|
115
|
-
|
116
|
-
|
117
|
-
v['spec'] = o[1]
|
118
|
-
v['diagnosis'] = o[2]
|
85
|
+
v['recipient'] = o[2]
|
86
|
+
recipients += 1
|
119
87
|
else
|
120
|
-
#
|
121
|
-
|
122
|
-
v[fieldtable[o[0]]] = o[2]
|
123
|
-
|
124
|
-
next unless f == 1
|
125
|
-
permessage[fieldtable[o[0]]] = o[2]
|
88
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
89
|
+
v['alias'] = o[2]
|
126
90
|
end
|
91
|
+
elsif o[-1] == 'code'
|
92
|
+
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
93
|
+
v['spec'] = o[1]
|
94
|
+
v['diagnosis'] = o[2]
|
127
95
|
else
|
128
|
-
#
|
129
|
-
next unless
|
130
|
-
|
131
|
-
|
132
|
-
|
96
|
+
# Other DSN fields defined in RFC3464
|
97
|
+
next unless fieldtable[o[0]]
|
98
|
+
v[fieldtable[o[0]]] = o[2]
|
99
|
+
|
100
|
+
next unless f == 1
|
101
|
+
permessage[fieldtable[o[0]]] = o[2]
|
133
102
|
end
|
134
|
-
|
103
|
+
else
|
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
|
109
|
+
end
|
135
110
|
end
|
136
111
|
return nil unless recipients > 0
|
137
112
|
|
@@ -163,8 +138,7 @@ module Sisimai::Lhost
|
|
163
138
|
end
|
164
139
|
end
|
165
140
|
|
166
|
-
|
167
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
141
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
168
142
|
end
|
169
143
|
|
170
144
|
end
|
@@ -8,7 +8,7 @@ module Sisimai::Lhost
|
|
8
8
|
|
9
9
|
# Postfix manual - bounce(5) - http://www.postfix.org/bounce.5.html
|
10
10
|
Indicators = Sisimai::Lhost.INDICATORS
|
11
|
-
|
11
|
+
ReBackbone = %r<^Content-Type:[ ](?:message/rfc822|text/rfc822-headers)>.freeze
|
12
12
|
MarkingsOf = {
|
13
13
|
message: %r{\A(?>
|
14
14
|
[ ]+The[ ](?:
|
@@ -28,6 +28,7 @@ module Sisimai::Lhost
|
|
28
28
|
)
|
29
29
|
)
|
30
30
|
}x,
|
31
|
+
# :from => %r/ [(]Mail Delivery System[)]\z/,
|
31
32
|
}.freeze
|
32
33
|
|
33
34
|
def description; return 'Postfix'; end
|
@@ -46,155 +47,154 @@ module Sisimai::Lhost
|
|
46
47
|
# part or nil if it failed to parse or
|
47
48
|
# the arguments are missing
|
48
49
|
def make(mhead, mbody)
|
49
|
-
# :from => %r/ [(]Mail Delivery System[)]\z/,
|
50
50
|
return nil unless mhead['subject'] == 'Undelivered Mail Returned to Sender'
|
51
51
|
|
52
52
|
require 'sisimai/rfc1894'
|
53
|
+
require 'sisimai/address'
|
53
54
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
54
55
|
permessage = {} # (Hash) Store values of each Per-Message field
|
55
56
|
|
56
57
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
blanklines = 0 # (Integer) The number of blank lines
|
58
|
+
emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
|
59
|
+
bodyslices = emailsteak[0].split("\n")
|
60
|
+
readslices = ['']
|
61
61
|
readcursor = 0 # (Integer) Points the current cursor position
|
62
62
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
63
|
+
nomessages = false # (Boolean) Delivery report unavailable
|
63
64
|
commandset = [] # (Array) ``in reply to * command'' list
|
64
65
|
anotherset = {} # Another error information
|
65
66
|
v = nil
|
66
67
|
|
67
|
-
while e =
|
68
|
-
#
|
69
|
-
|
70
|
-
|
68
|
+
while e = bodyslices.shift do
|
69
|
+
# Read error messages and delivery status lines from the head of the email
|
70
|
+
# to the previous line of the beginning of the original message.
|
71
|
+
readslices << e # Save the current line for the next loop
|
71
72
|
|
72
73
|
if readcursor == 0
|
73
74
|
# Beginning of the bounce message or message/delivery-status part
|
74
|
-
if e =~ MarkingsOf[:message]
|
75
|
-
|
76
|
-
next
|
77
|
-
end
|
75
|
+
readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
|
76
|
+
next
|
78
77
|
end
|
78
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
79
|
+
next if e.empty?
|
79
80
|
|
80
|
-
if
|
81
|
-
#
|
82
|
-
|
83
|
-
|
84
|
-
next
|
85
|
-
end
|
86
|
-
end
|
81
|
+
if f = Sisimai::RFC1894.match(e)
|
82
|
+
# "e" matched with any field defined in RFC3464
|
83
|
+
next unless o = Sisimai::RFC1894.field(e)
|
84
|
+
v = dscontents[-1]
|
87
85
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
break if blanklines > 1
|
93
|
-
next
|
94
|
-
end
|
95
|
-
rfc822list << e
|
96
|
-
else
|
97
|
-
# message/delivery-status part
|
98
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
99
|
-
next if e.empty?
|
100
|
-
|
101
|
-
if f = Sisimai::RFC1894.match(e)
|
102
|
-
# "e" matched with any field defined in RFC3464
|
103
|
-
next unless o = Sisimai::RFC1894.field(e)
|
104
|
-
v = dscontents[-1]
|
105
|
-
|
106
|
-
if o[-1] == 'addr'
|
86
|
+
if o[-1] == 'addr'
|
87
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
88
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
89
|
+
if o[0] == 'final-recipient'
|
107
90
|
# Final-Recipient: rfc822; kijitora@example.jp
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# There are multiple recipient addresses in the message body.
|
113
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
114
|
-
v = dscontents[-1]
|
115
|
-
end
|
116
|
-
v['recipient'] = o[2]
|
117
|
-
recipients += 1
|
118
|
-
else
|
119
|
-
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
120
|
-
v['alias'] = o[2]
|
91
|
+
if v['recipient']
|
92
|
+
# There are multiple recipient addresses in the message body.
|
93
|
+
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
94
|
+
v = dscontents[-1]
|
121
95
|
end
|
122
|
-
|
123
|
-
|
124
|
-
v['spec'] = o[1]
|
125
|
-
v['spec'] = 'SMTP' if v['spec'] == 'X-POSTFIX'
|
126
|
-
v['diagnosis'] = o[2]
|
96
|
+
v['recipient'] = o[2]
|
97
|
+
recipients += 1
|
127
98
|
else
|
128
|
-
#
|
129
|
-
|
130
|
-
v[fieldtable[o[0]]] = o[2]
|
131
|
-
|
132
|
-
next unless f == 1
|
133
|
-
permessage[fieldtable[o[0]]] = o[2]
|
99
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
100
|
+
v['alias'] = o[2]
|
134
101
|
end
|
102
|
+
elsif o[-1] == 'code'
|
103
|
+
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
104
|
+
v['spec'] = o[1]
|
105
|
+
v['spec'] = 'SMTP' if v['spec'] == 'X-POSTFIX'
|
106
|
+
v['diagnosis'] = o[2]
|
107
|
+
else
|
108
|
+
# Other DSN fields defined in RFC3464
|
109
|
+
next unless fieldtable[o[0]]
|
110
|
+
v[fieldtable[o[0]]] = o[2]
|
111
|
+
|
112
|
+
next unless f == 1
|
113
|
+
permessage[fieldtable[o[0]]] = o[2]
|
114
|
+
end
|
115
|
+
else
|
116
|
+
# If you do so, please include this problem report. You can
|
117
|
+
# delete your own text from the attached returned message.
|
118
|
+
#
|
119
|
+
# The mail system
|
120
|
+
#
|
121
|
+
# <userunknown@example.co.jp>: host mx.example.co.jp[192.0.2.153] said: 550
|
122
|
+
# 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
|
123
|
+
# command)
|
124
|
+
if readslices[-2].start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
|
125
|
+
# Continued line of the value of Diagnostic-Code header
|
126
|
+
v['diagnosis'] << ' ' << cv[1]
|
127
|
+
readslices[-1] = 'Diagnostic-Code: ' << e
|
128
|
+
|
129
|
+
elsif cv = e.match(/\A(X-Postfix-Sender):[ ]*rfc822;[ ]*(.+)\z/)
|
130
|
+
# X-Postfix-Sender: rfc822; shironeko@example.org
|
131
|
+
emailsteak[1] << cv[1] << ': ' << cv[2] << "\n"
|
132
|
+
|
135
133
|
else
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
# <userunknown@example.co.jp>: host mx.example.co.jp[192.0.2.153] said: 550
|
142
|
-
# 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
|
143
|
-
# command)
|
144
|
-
if p.start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
|
145
|
-
# Continued line of the value of Diagnostic-Code header
|
146
|
-
v['diagnosis'] << ' ' << cv[1]
|
147
|
-
havepassed[-1] = 'Diagnostic-Code: ' << e
|
134
|
+
if cv = e.match(/[ \t][(]in reply to ([A-Z]{4}).*/)
|
135
|
+
# 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
|
136
|
+
commandset << cv[1]
|
137
|
+
anotherset['diagnosis'] ||= ''
|
138
|
+
anotherset['diagnosis'] << ' ' << e
|
148
139
|
|
149
|
-
elsif cv = e.match(
|
150
|
-
#
|
151
|
-
|
140
|
+
elsif cv = e.match(/([A-Z]{4})[ \t]*.*command[)]\z/)
|
141
|
+
# to MAIL command)
|
142
|
+
commandset << cv[1]
|
143
|
+
anotherset['diagnosis'] ||= ''
|
144
|
+
anotherset['diagnosis'] << ' ' << e
|
152
145
|
|
153
146
|
else
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
anotherset['
|
158
|
-
anotherset['
|
147
|
+
# Alternative error message and recipient
|
148
|
+
if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>] [(]expanded from [<](.+)[>][)]:[ \t]*(.+)\z/)
|
149
|
+
# <r@example.ne.jp> (expanded from <kijitora@example.org>): user ...
|
150
|
+
anotherset['recipient'] = cv[1]
|
151
|
+
anotherset['alias'] = cv[2]
|
152
|
+
anotherset['diagnosis'] = cv[3]
|
159
153
|
|
160
|
-
elsif cv = e.match(
|
161
|
-
#
|
162
|
-
|
163
|
-
anotherset['diagnosis']
|
164
|
-
anotherset['diagnosis'] << ' ' << e
|
154
|
+
elsif cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]:(.*)\z/)
|
155
|
+
# <kijitora@exmaple.jp>: ...
|
156
|
+
anotherset['recipient'] = cv[1]
|
157
|
+
anotherset['diagnosis'] = cv[2]
|
165
158
|
|
159
|
+
elsif e.include?('--- Delivery report unavailable ---')
|
160
|
+
# postfix-3.1.4/src/bounce/bounce_notify_util.c
|
161
|
+
# bounce_notify_util.c:602|if (bounce_info->log_handle == 0
|
162
|
+
# bounce_notify_util.c:602||| bounce_log_rewind(bounce_info->log_handle)) {
|
163
|
+
# bounce_notify_util.c:602|if (IS_FAILURE_TEMPLATE(bounce_info->template)) {
|
164
|
+
# bounce_notify_util.c:602| post_mail_fputs(bounce, "");
|
165
|
+
# bounce_notify_util.c:602| post_mail_fputs(bounce, "\t--- delivery report unavailable ---");
|
166
|
+
# bounce_notify_util.c:602| count = 1; /* xxx don't abort */
|
167
|
+
# bounce_notify_util.c:602|}
|
168
|
+
# bounce_notify_util.c:602|} else {
|
169
|
+
nomessages = true
|
166
170
|
else
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
anotherset['diagnosis'] = cv[3]
|
173
|
-
|
174
|
-
elsif cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]:(.*)\z/)
|
175
|
-
# <kijitora@exmaple.jp>: ...
|
176
|
-
anotherset['recipient'] = cv[1]
|
177
|
-
anotherset['diagnosis'] = cv[2]
|
178
|
-
else
|
179
|
-
# Get error message continued from the previous line
|
180
|
-
next unless anotherset['diagnosis']
|
181
|
-
if e =~ /\A[ \t]{4}(.+)\z/
|
182
|
-
# host mx.example.jp said:...
|
183
|
-
anotherset['diagnosis'] << ' ' << e
|
184
|
-
end
|
185
|
-
end
|
171
|
+
# Get error message continued from the previous line
|
172
|
+
next unless anotherset['diagnosis']
|
173
|
+
if e =~ /\A[ \t]{4}(.+)\z/
|
174
|
+
# host mx.example.jp said:...
|
175
|
+
anotherset['diagnosis'] << ' ' << e
|
186
176
|
end
|
177
|
+
end
|
187
178
|
end
|
188
179
|
end
|
189
|
-
end
|
180
|
+
end
|
190
181
|
end
|
191
182
|
|
192
183
|
unless recipients > 0
|
193
|
-
# Fallback:
|
194
|
-
|
195
|
-
# Set recipient address
|
184
|
+
# Fallback: get a recipient address from error messages
|
185
|
+
if anotherset['recipient'].to_s.size > 0
|
186
|
+
# Set a recipient address
|
196
187
|
dscontents[-1]['recipient'] = anotherset['recipient']
|
197
188
|
recipients += 1
|
189
|
+
else
|
190
|
+
# Get a recipient address from message/rfc822 part if the delivery
|
191
|
+
# report was unavailable: '--- Delivery report unavailable ---'
|
192
|
+
if nomessages && cv = emailsteak[1].match(/^To:[ ]*(.+)$/)
|
193
|
+
# Try to get a recipient address from To: field in the original
|
194
|
+
# message at message/rfc822 part
|
195
|
+
dscontents[-1]['recipient'] = Sisimai::Address.s3s4(cv[1])
|
196
|
+
recipients += 1
|
197
|
+
end
|
198
198
|
end
|
199
199
|
end
|
200
200
|
return nil unless recipients > 0
|
@@ -204,9 +204,6 @@ module Sisimai::Lhost
|
|
204
204
|
e['lhost'] ||= permessage['rhost']
|
205
205
|
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
206
206
|
|
207
|
-
e['agent'] = self.smtpagent
|
208
|
-
e['command'] = commandset.shift || ''
|
209
|
-
|
210
207
|
if anotherset['diagnosis']
|
211
208
|
# Copy alternative error message
|
212
209
|
e['diagnosis'] = anotherset['diagnosis'] unless e['diagnosis']
|
@@ -247,12 +244,14 @@ module Sisimai::Lhost
|
|
247
244
|
end
|
248
245
|
|
249
246
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
247
|
+
e['command'] = commandset.shift || nil
|
248
|
+
e['command'] ||= 'HELO' if e['diagnosis'] =~ /refused to talk to me:/
|
250
249
|
e['spec'] ||= 'SMTP' if e['diagnosis'] =~ /host .+ said:/
|
250
|
+
e['agent'] = self.smtpagent
|
251
251
|
e.each_key { |a| e[a] ||= '' }
|
252
252
|
end
|
253
253
|
|
254
|
-
|
255
|
-
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
254
|
+
return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
|
256
255
|
end
|
257
256
|
|
258
257
|
end
|