sisimai 5.2.1-java → 5.4.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rake-test.yml +1 -1
- data/ChangeLog.md +24 -0
- data/Makefile +3 -2
- data/README-JA.md +4 -4
- data/README.md +8 -8
- data/lib/sisimai/address.rb +45 -56
- data/lib/sisimai/arf.rb +11 -16
- data/lib/sisimai/datetime.rb +16 -50
- data/lib/sisimai/fact/json.rb +5 -5
- data/lib/sisimai/fact/yaml.rb +3 -3
- data/lib/sisimai/fact.rb +21 -12
- data/lib/sisimai/lda.rb +3 -3
- data/lib/sisimai/lhost/activehunter.rb +4 -6
- data/lib/sisimai/lhost/amazonses.rb +5 -6
- data/lib/sisimai/lhost/apachejames.rb +7 -9
- data/lib/sisimai/lhost/biglobe.rb +3 -5
- data/lib/sisimai/lhost/courier.rb +4 -6
- data/lib/sisimai/lhost/domino.rb +4 -5
- data/lib/sisimai/lhost/dragonfly.rb +3 -5
- data/lib/sisimai/lhost/einsundeins.rb +6 -8
- data/lib/sisimai/lhost/exchange2003.rb +10 -12
- data/lib/sisimai/lhost/exchange2007.rb +4 -5
- data/lib/sisimai/lhost/exim.rb +6 -8
- data/lib/sisimai/lhost/ezweb.rb +10 -12
- data/lib/sisimai/lhost/fml.rb +2 -3
- data/lib/sisimai/lhost/gmail.rb +4 -6
- data/lib/sisimai/lhost/gmx.rb +6 -8
- data/lib/sisimai/lhost/googlegroups.rb +1 -2
- data/lib/sisimai/lhost/googleworkspace.rb +3 -4
- data/lib/sisimai/lhost/imailserver.rb +6 -7
- data/lib/sisimai/lhost/interscanmss.rb +1 -2
- data/lib/sisimai/lhost/kddi.rb +5 -8
- data/lib/sisimai/lhost/mailfoundry.rb +4 -7
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +4 -6
- data/lib/sisimai/lhost/messagingserver.rb +5 -7
- data/lib/sisimai/lhost/mfilter.rb +4 -6
- data/lib/sisimai/lhost/notes.rb +7 -9
- data/lib/sisimai/lhost/opensmtpd.rb +2 -4
- data/lib/sisimai/lhost/postfix.rb +8 -11
- data/lib/sisimai/lhost/qmail.rb +5 -8
- data/lib/sisimai/lhost/sendmail.rb +7 -10
- data/lib/sisimai/lhost/v5sendmail.rb +15 -17
- data/lib/sisimai/lhost/verizon.rb +9 -14
- data/lib/sisimai/lhost/x1.rb +4 -6
- data/lib/sisimai/lhost/x2.rb +5 -7
- data/lib/sisimai/lhost/x3.rb +3 -4
- data/lib/sisimai/lhost/x6.rb +4 -6
- data/lib/sisimai/lhost/zoho.rb +6 -8
- data/lib/sisimai/lhost.rb +1 -1
- data/lib/sisimai/mail/mbox.rb +1 -1
- data/lib/sisimai/mail/memory.rb +1 -1
- data/lib/sisimai/mail.rb +8 -8
- data/lib/sisimai/message.rb +11 -13
- data/lib/sisimai/order.rb +12 -11
- data/lib/sisimai/reason/authfailure.rb +10 -10
- data/lib/sisimai/reason/badreputation.rb +4 -6
- data/lib/sisimai/reason/blocked.rb +6 -8
- data/lib/sisimai/reason/contenterror.rb +5 -6
- data/lib/sisimai/reason/delivered.rb +2 -2
- data/lib/sisimai/reason/exceedlimit.rb +7 -8
- data/lib/sisimai/reason/expired.rb +6 -7
- data/lib/sisimai/reason/failedstarttls.rb +5 -7
- data/lib/sisimai/reason/feedback.rb +2 -2
- data/lib/sisimai/reason/filtered.rb +7 -10
- data/lib/sisimai/reason/hasmoved.rb +4 -5
- data/lib/sisimai/reason/hostunknown.rb +6 -7
- data/lib/sisimai/reason/mailboxfull.rb +7 -8
- data/lib/sisimai/reason/mailererror.rb +5 -8
- data/lib/sisimai/reason/mesgtoobig.rb +5 -6
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +4 -5
- data/lib/sisimai/reason/notaccept.rb +5 -8
- data/lib/sisimai/reason/notcompliantrfc.rb +5 -6
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +6 -9
- data/lib/sisimai/reason/rejected.rb +5 -6
- data/lib/sisimai/reason/requireptr.rb +6 -7
- data/lib/sisimai/reason/securityerror.rb +6 -9
- data/lib/sisimai/reason/spamdetected.rb +8 -9
- data/lib/sisimai/reason/speeding.rb +6 -7
- data/lib/sisimai/reason/suppressed.rb +3 -7
- data/lib/sisimai/reason/suspend.rb +5 -7
- data/lib/sisimai/reason/syntaxerror.rb +3 -5
- data/lib/sisimai/reason/systemerror.rb +6 -9
- data/lib/sisimai/reason/systemfull.rb +5 -8
- data/lib/sisimai/reason/toomanyconn.rb +5 -6
- data/lib/sisimai/reason/undefined.rb +2 -2
- data/lib/sisimai/reason/userunknown.rb +8 -9
- data/lib/sisimai/reason/vacation.rb +4 -5
- data/lib/sisimai/reason/virusdetected.rb +4 -5
- data/lib/sisimai/reason.rb +13 -13
- data/lib/sisimai/rfc1123.rb +4 -8
- data/lib/sisimai/rfc1894.rb +5 -6
- data/lib/sisimai/rfc2045.rb +27 -31
- data/lib/sisimai/rfc3464/thirdparty.rb +1 -1
- data/lib/sisimai/rfc3464.rb +7 -9
- data/lib/sisimai/rfc3834.rb +5 -9
- data/lib/sisimai/rfc5322.rb +8 -26
- data/lib/sisimai/rfc791.rb +6 -4
- data/lib/sisimai/rhost/google.rb +8 -0
- data/lib/sisimai/rhost/microsoft.rb +17 -5
- data/lib/sisimai/rhost.rb +2 -2
- data/lib/sisimai/smtp/command.rb +1 -1
- data/lib/sisimai/smtp/failure.rb +5 -12
- data/lib/sisimai/smtp/reply.rb +33 -12
- data/lib/sisimai/smtp/status.rb +21 -22
- data/lib/sisimai/smtp/transcript.rb +1 -10
- data/lib/sisimai/string.rb +20 -30
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +11 -11
- data/set-of-emails/maildir/bsd/rhost-microsoft-06.eml +45 -0
- metadata +8 -10
@@ -22,13 +22,12 @@ module Sisimai::Lhost
|
|
22
22
|
return nil unless mhead['x-mailer'].to_s == 'm-FILTER'
|
23
23
|
return nil unless mhead['subject'] == 'failure notice'
|
24
24
|
|
25
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
25
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
26
26
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
27
27
|
bodyslices = emailparts[0].split("\n")
|
28
28
|
readcursor = 0 # (Integer) Points the current cursor position
|
29
29
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
30
|
-
markingset = {
|
31
|
-
v = nil
|
30
|
+
markingset = {'diagnosis' => false, 'command' => false}
|
32
31
|
|
33
32
|
while e = bodyslices.shift do
|
34
33
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -39,8 +38,7 @@ module Sisimai::Lhost
|
|
39
38
|
readcursor |= Indicators[:deliverystatus]
|
40
39
|
end
|
41
40
|
end
|
42
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
43
|
-
next if e.empty?
|
41
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
44
42
|
|
45
43
|
# このメールは「m-FILTER」が自動的に生成して送信しています。
|
46
44
|
# メールサーバーとの通信中、下記の理由により
|
@@ -111,7 +109,7 @@ module Sisimai::Lhost
|
|
111
109
|
e['rhost'] = ee
|
112
110
|
end
|
113
111
|
end
|
114
|
-
return {
|
112
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
115
113
|
end
|
116
114
|
def description; return 'Digital Arts m-FILTER'; end
|
117
115
|
end
|
data/lib/sisimai/lhost/notes.rb
CHANGED
@@ -7,7 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
9
9
|
Boundaries = ['------- Returned Message --------'].freeze
|
10
|
-
StartingOf = {
|
10
|
+
StartingOf = {message: ['------- Failure Reasons ']}.freeze
|
11
11
|
MessagesOf = {
|
12
12
|
'userunknown' => [
|
13
13
|
'User not listed in public Name & Address Book',
|
@@ -24,7 +24,7 @@ module Sisimai::Lhost
|
|
24
24
|
def inquire(mhead, mbody)
|
25
25
|
return nil unless mhead['subject'].start_with?('Undeliverable message')
|
26
26
|
|
27
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
27
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
28
28
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
29
29
|
bodyslices = emailparts[0].split("\n")
|
30
30
|
readcursor = 0 # (Integer) Points the current cursor position
|
@@ -32,7 +32,6 @@ module Sisimai::Lhost
|
|
32
32
|
characters = '' # (String) Character set name of the bounce mail
|
33
33
|
removedmsg = 'MULTIBYTE CHARACTERS HAVE BEEN REMOVED'
|
34
34
|
encodedmsg = ''
|
35
|
-
v = nil
|
36
35
|
|
37
36
|
if mhead['content-type'].include?('charset=')
|
38
37
|
# Get character set name, Content-Type: text/plain; charset=ISO-2022-JP
|
@@ -66,8 +65,7 @@ module Sisimai::Lhost
|
|
66
65
|
v["recipient"] = e if v["recipient"].empty?
|
67
66
|
recipients += 1
|
68
67
|
else
|
69
|
-
next if e.empty?
|
70
|
-
next if e.start_with?('-')
|
68
|
+
next if e.empty? || e.start_with?('-')
|
71
69
|
|
72
70
|
if e =~ /[^\x20-\x7e]/
|
73
71
|
# Error message is not ISO-8859-1
|
@@ -83,10 +81,10 @@ module Sisimai::Lhost
|
|
83
81
|
# No character set in Content-Type header
|
84
82
|
encodedmsg = removedmsg
|
85
83
|
end
|
86
|
-
v['diagnosis']
|
84
|
+
v['diagnosis'] += encodedmsg
|
87
85
|
else
|
88
86
|
# Error message does not include multi-byte character
|
89
|
-
v['diagnosis']
|
87
|
+
v['diagnosis'] += e
|
90
88
|
end
|
91
89
|
end
|
92
90
|
end
|
@@ -96,7 +94,7 @@ module Sisimai::Lhost
|
|
96
94
|
p1 = emailparts[1].index("\nTo: ") || -1
|
97
95
|
p2 = emailparts[1].index("\n", p1 + 6) || -1
|
98
96
|
if p1 > 0
|
99
|
-
v['recipient'] = Sisimai::Address.s3s4(emailparts[1][p1 + 5, p2 - p1 - 5])
|
97
|
+
v['recipient'] = Sisimai::Address.s3s4(emailparts[1][p1 + 5, p2 - p1 - 5])
|
100
98
|
recipients += 1 unless v['recipient'].empty?
|
101
99
|
end
|
102
100
|
end
|
@@ -115,7 +113,7 @@ module Sisimai::Lhost
|
|
115
113
|
end
|
116
114
|
end
|
117
115
|
|
118
|
-
return {
|
116
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
119
117
|
end
|
120
118
|
def description; return 'Lotus Notes'; end
|
121
119
|
end
|
@@ -76,12 +76,11 @@ module Sisimai::Lhost
|
|
76
76
|
return nil unless mhead['from'].start_with?('Mailer Daemon <')
|
77
77
|
return nil unless mhead['received'].any? { |a| a.include?(' (OpenSMTPD) with ') }
|
78
78
|
|
79
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
79
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
80
80
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
81
81
|
bodyslices = emailparts[0].split("\n")
|
82
82
|
readcursor = 0 # (Integer) Points the current cursor position
|
83
83
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
84
|
-
v = nil
|
85
84
|
|
86
85
|
while e = bodyslices.shift do
|
87
86
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -91,8 +90,7 @@ module Sisimai::Lhost
|
|
91
90
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
92
91
|
next
|
93
92
|
end
|
94
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
95
|
-
next if e.empty?
|
93
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
96
94
|
|
97
95
|
# Hi!
|
98
96
|
#
|
@@ -38,11 +38,10 @@ module Sisimai::Lhost
|
|
38
38
|
# Subject: Undelivered Mail Returned to Sender
|
39
39
|
match = 1 if mhead['subject'] == 'Undelivered Mail Returned to Sender'
|
40
40
|
end
|
41
|
-
return nil if match == 0
|
42
|
-
return nil if mhead['x-aol-ip']
|
41
|
+
return nil if match == 0 || mhead['x-aol-ip']
|
43
42
|
|
44
43
|
permessage = {} # (Hash) Store values of each Per-Message field
|
45
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
44
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
46
45
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
47
46
|
bodyslices = emailparts[0].split("\n")
|
48
47
|
readslices = ['']
|
@@ -50,7 +49,6 @@ module Sisimai::Lhost
|
|
50
49
|
nomessages = false # (Boolean) Delivery report unavailable
|
51
50
|
commandset = [] # (Array) ``in reply to * command'' list
|
52
51
|
anotherset = {} # Another error information
|
53
|
-
v = nil
|
54
52
|
|
55
53
|
if match == 2
|
56
54
|
# The message body starts with 'Transcript of session follows.'
|
@@ -104,8 +102,7 @@ module Sisimai::Lhost
|
|
104
102
|
readcursor |= Indicators[:deliverystatus] if StartingOf[:message].any? { |a| Sisimai::String.aligned(e, a) }
|
105
103
|
next
|
106
104
|
end
|
107
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
108
|
-
next if e.empty?
|
105
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
109
106
|
|
110
107
|
f = Sisimai::RFC1894.match(e)
|
111
108
|
if f > 0
|
@@ -153,12 +150,12 @@ module Sisimai::Lhost
|
|
153
150
|
# 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO command)
|
154
151
|
if readslices[-2].start_with?('Diagnostic-Code:') && e.include?(' ')
|
155
152
|
# Continued line of the value of Diagnostic-Code header
|
156
|
-
v['diagnosis']
|
157
|
-
readslices[-1]
|
153
|
+
v['diagnosis'] += " #{Sisimai::String.sweep(e)}"
|
154
|
+
readslices[-1] = "Diagnostic-Code: #{e}"
|
158
155
|
|
159
156
|
elsif Sisimai::String.aligned(e, ['X-Postfix-Sender:', 'rfc822;', '@'])
|
160
157
|
# X-Postfix-Sender: rfc822; shironeko@example.org
|
161
|
-
emailparts[1]
|
158
|
+
emailparts[1] += "X-Postfix-Sender: #{Sisimai::Address.s3s4(e[e.index(';') + 1, e.size])}\n"
|
162
159
|
|
163
160
|
else
|
164
161
|
# Alternative error message and recipient
|
@@ -166,7 +163,7 @@ module Sisimai::Lhost
|
|
166
163
|
# 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
|
167
164
|
cv = Sisimai::SMTP::Command.find(e) || ""; commandset << cv unless cv.empty?
|
168
165
|
anotherset['diagnosis'] ||= ''
|
169
|
-
anotherset['diagnosis']
|
166
|
+
anotherset['diagnosis'] += " #{e}"
|
170
167
|
|
171
168
|
elsif Sisimai::String.aligned(e, ['<', '@', '>', '(expanded from<', '):'])
|
172
169
|
# <r@example.ne.jp> (expanded from <kijitora@example.org>): user ...
|
@@ -198,7 +195,7 @@ module Sisimai::Lhost
|
|
198
195
|
next unless anotherset['diagnosis']
|
199
196
|
if e.start_with?(' ')
|
200
197
|
# host mx.example.jp said:...
|
201
|
-
anotherset['diagnosis']
|
198
|
+
anotherset['diagnosis'] += " #{e[4, e.size]}"
|
202
199
|
end
|
203
200
|
end
|
204
201
|
end
|
data/lib/sisimai/lhost/qmail.rb
CHANGED
@@ -17,7 +17,6 @@ module Sisimai::Lhost
|
|
17
17
|
"Content-Type: message/rfc822",
|
18
18
|
"Original message follows.",
|
19
19
|
].freeze
|
20
|
-
RelayedVia = [["(qmail ", "invoked for bounce)"], ["(qmail ", "invoked from ", "network)"]].freeze
|
21
20
|
EmailTitle = [
|
22
21
|
"failure notice", # qmail-send.c:Subject: failure notice\n\
|
23
22
|
"Failure Notice", # Yahoo
|
@@ -138,17 +137,16 @@ module Sisimai::Lhost
|
|
138
137
|
mhead["received"].each do |e|
|
139
138
|
# Received: (qmail 2222 invoked for bounce);29 Apr 2017 23:34:45 +0900
|
140
139
|
# Received: (qmail 2202 invoked from network); 29 Apr 2018 00:00:00 +0900
|
141
|
-
proceedsto = true if
|
140
|
+
proceedsto = true if Sisimai::String.aligned(e, ["(qmail", " invoked "])
|
142
141
|
end
|
143
142
|
return nil if proceedsto == false
|
144
143
|
|
145
144
|
require "sisimai/smtp/command"
|
146
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
145
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
147
146
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
148
147
|
bodyslices = emailparts[0].split("\n")
|
149
148
|
readcursor = 0 # (Integer) Points the current cursor position
|
150
149
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
151
|
-
v = nil
|
152
150
|
|
153
151
|
while e = bodyslices.shift do
|
154
152
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -158,8 +156,7 @@ module Sisimai::Lhost
|
|
158
156
|
readcursor |= Indicators[:deliverystatus] if StartingOf["message"].any? { |a| e.include?(a) }
|
159
157
|
next
|
160
158
|
end
|
161
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
162
|
-
next if e.empty?
|
159
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
163
160
|
|
164
161
|
# <kijitora@example.jp>:
|
165
162
|
# 192.0.2.153 does not like recipient.
|
@@ -179,8 +176,8 @@ module Sisimai::Lhost
|
|
179
176
|
|
180
177
|
elsif dscontents.size == recipients
|
181
178
|
# Append error message
|
182
|
-
v["diagnosis"]
|
183
|
-
v["alterrors"]
|
179
|
+
v["diagnosis"] += "#{e} "
|
180
|
+
v["alterrors"] = e if e.start_with?(StartingOf["error"][0])
|
184
181
|
|
185
182
|
next if v["rhost"] != ""
|
186
183
|
StartingOf["rhost"].each do |r|
|
@@ -38,7 +38,7 @@ module Sisimai::Lhost
|
|
38
38
|
|
39
39
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
40
40
|
permessage = {} # (Hash) Store values of each Per-Message field
|
41
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
41
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
42
42
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
43
43
|
bodyslices = emailparts[0].split("\n")
|
44
44
|
readslices = ['']
|
@@ -48,7 +48,6 @@ module Sisimai::Lhost
|
|
48
48
|
esmtpreply = [] # (Array) Reply from remote server on SMTP session
|
49
49
|
sessionerr = false # (Boolean) Flag, "true" if it is SMTP session error
|
50
50
|
anotherset = {} # Another error information
|
51
|
-
v = nil
|
52
51
|
|
53
52
|
while e = bodyslices.shift do
|
54
53
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -60,8 +59,7 @@ module Sisimai::Lhost
|
|
60
59
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
61
60
|
next
|
62
61
|
end
|
63
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
64
|
-
next if e.empty?
|
62
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
65
63
|
|
66
64
|
f = Sisimai::RFC1894.match(e)
|
67
65
|
if f > 0
|
@@ -147,13 +145,13 @@ module Sisimai::Lhost
|
|
147
145
|
# 554 5.3.0 unknown mailer error 255
|
148
146
|
anotherset['status'] = cs
|
149
147
|
anotherset['diagnosis'] ||= ''
|
150
|
-
anotherset['diagnosis']
|
148
|
+
anotherset['diagnosis'] += " #{e}"
|
151
149
|
|
152
150
|
elsif e.start_with?('Message ', 'Warning: ')
|
153
151
|
# Message could not be delivered for too long
|
154
152
|
# Warning: message still undelivered after 4 hours
|
155
153
|
anotherset['diagnosis'] ||= ''
|
156
|
-
anotherset['diagnosis']
|
154
|
+
anotherset['diagnosis'] += " #{e}"
|
157
155
|
end
|
158
156
|
end
|
159
157
|
end
|
@@ -161,8 +159,8 @@ module Sisimai::Lhost
|
|
161
159
|
# Continued line of the value of Diagnostic-Code field
|
162
160
|
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
163
161
|
next unless e.start_with?(' ')
|
164
|
-
v['diagnosis']
|
165
|
-
readslices[-1]
|
162
|
+
v['diagnosis'] += " #{Sisimai::String.sweep(e)}"
|
163
|
+
readslices[-1] = "Diagnostic-Code: #{e}"
|
166
164
|
end
|
167
165
|
end
|
168
166
|
end # End of message/delivery-status
|
@@ -182,8 +180,7 @@ module Sisimai::Lhost
|
|
182
180
|
while true
|
183
181
|
# Replace or append the error message in "diagnosis" with the ESMTP Reply Code when the
|
184
182
|
# following conditions have matched
|
185
|
-
break if esmtpreply.empty?
|
186
|
-
break if recipients != 1
|
183
|
+
break if esmtpreply.empty? || recipients != 1
|
187
184
|
|
188
185
|
e['diagnosis'] = sprintf("%s %s", esmtpreply.join(' '), e['diagnosis'])
|
189
186
|
break
|
@@ -43,14 +43,13 @@ module Sisimai::Lhost
|
|
43
43
|
|
44
44
|
require 'sisimai/rfc1123'
|
45
45
|
require 'sisimai/smtp/command'
|
46
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
46
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
47
47
|
bodyslices = emailparts[0].split("\n")
|
48
48
|
readcursor = 0 # (Integer) Points the current cursor position
|
49
49
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
50
50
|
anotherone = {} # (Hash) Another error information
|
51
51
|
remotehost = "" # The last remote hostname
|
52
|
-
|
53
|
-
v = nil
|
52
|
+
curcommand = "" # The last SMTP command
|
54
53
|
|
55
54
|
while e = bodyslices.shift do
|
56
55
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -60,8 +59,7 @@ module Sisimai::Lhost
|
|
60
59
|
readcursor |= Indicators[:deliverystatus] if e.include?(StartingOf[:message][0])
|
61
60
|
next
|
62
61
|
end
|
63
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
64
|
-
next if e.empty?
|
62
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
65
63
|
|
66
64
|
# ----- Transcript of session follows -----
|
67
65
|
# While talking to smtp.example.com:
|
@@ -82,7 +80,7 @@ module Sisimai::Lhost
|
|
82
80
|
|
83
81
|
if remotehost == ""
|
84
82
|
# Keep error messages before "While talking to ..." line
|
85
|
-
anotherone[recipients] ||= ""; anotherone[recipients]
|
83
|
+
anotherone[recipients] ||= ""; anotherone[recipients] += " #{e}"
|
86
84
|
next
|
87
85
|
end
|
88
86
|
|
@@ -90,9 +88,9 @@ module Sisimai::Lhost
|
|
90
88
|
# The recipient address is the same address with the last appeared address
|
91
89
|
# like "550 <mikeneko@example.co.jp>... User unknown"
|
92
90
|
# Append this line to the string which is keeping error messages
|
93
|
-
v["diagnosis"]
|
94
|
-
v["replycode"]
|
95
|
-
curcommand
|
91
|
+
v["diagnosis"] += " #{e}"
|
92
|
+
v["replycode"] = Sisimai::SMTP::Reply.find(e)
|
93
|
+
curcommand = ""
|
96
94
|
else
|
97
95
|
# The recipient address in this line differs from the last appeared address
|
98
96
|
# or is the first recipient address in this bounce message
|
@@ -101,12 +99,12 @@ module Sisimai::Lhost
|
|
101
99
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
102
100
|
v = dscontents[-1]
|
103
101
|
end
|
104
|
-
recipients
|
105
|
-
v["recipient"]
|
106
|
-
v["rhost"]
|
107
|
-
v["replycode"]
|
108
|
-
v["diagnosis"]
|
109
|
-
v["command"]
|
102
|
+
recipients += 1
|
103
|
+
v["recipient"] = cv
|
104
|
+
v["rhost"] = remotehost
|
105
|
+
v["replycode"] = Sisimai::SMTP::Reply.find(e)
|
106
|
+
v["diagnosis"] += " #{e}"
|
107
|
+
v["command"] = curcommand if v["command"].empty?
|
110
108
|
end
|
111
109
|
else
|
112
110
|
# This line does not include a recipient address
|
@@ -122,10 +120,10 @@ module Sisimai::Lhost
|
|
122
120
|
# >>> QUIT
|
123
121
|
# <<< 421 dns.example.org Sorry, unable to contact destination SMTP daemon.
|
124
122
|
# <<< 550 Requested User Mailbox not found. No such user here.
|
125
|
-
v["diagnosis"]
|
123
|
+
v["diagnosis"] += " #{e}"
|
126
124
|
else
|
127
125
|
# 421 Other error message
|
128
|
-
anotherone[recipients] ||= ""; anotherone[recipients]
|
126
|
+
anotherone[recipients] ||= ""; anotherone[recipients] += " #{e}"
|
129
127
|
end
|
130
128
|
end
|
131
129
|
end
|
@@ -24,20 +24,17 @@ module Sisimai::Lhost
|
|
24
24
|
return nil if match < 0
|
25
25
|
|
26
26
|
boundaries = []
|
27
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
27
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
28
28
|
emailparts = []
|
29
29
|
readcursor = 0 # (Integer) Points the current cursor position
|
30
30
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
31
31
|
senderaddr = '' # (String) Sender address in the message body
|
32
32
|
subjecttxt = '' # (String) Subject of the original message
|
33
|
-
markingsof = {} # (Hash) Delimiter patterns
|
34
|
-
startingof = {} # (Hash) Delimiter strings
|
35
33
|
messagesof = {} # (Hash) Error message patterns
|
36
|
-
v = nil
|
37
34
|
|
38
35
|
if match == 1
|
39
36
|
# vtext.com
|
40
|
-
markingsof = {
|
37
|
+
markingsof = {message: ['Error: ']}
|
41
38
|
messagesof = {
|
42
39
|
# The attempted recipient address does not exist.
|
43
40
|
'userunknown' => ['550 - Requested action not taken: no such user here'],
|
@@ -54,8 +51,7 @@ module Sisimai::Lhost
|
|
54
51
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(markingsof[:message][0])
|
55
52
|
next
|
56
53
|
end
|
57
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
58
|
-
next if e.empty?
|
54
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
59
55
|
|
60
56
|
# Message details:
|
61
57
|
# Subject: Test message
|
@@ -88,8 +84,8 @@ module Sisimai::Lhost
|
|
88
84
|
end
|
89
85
|
else
|
90
86
|
# vzwpix.com
|
91
|
-
startingof = {
|
92
|
-
messagesof = {
|
87
|
+
startingof = {message: ['Message could not be delivered to mobile']}
|
88
|
+
messagesof = {'userunknown' => ['No valid recipients for this MM']}
|
93
89
|
boundaries = [Sisimai::RFC2045.boundary(mhead['content-type'], 1)]
|
94
90
|
emailparts = Sisimai::RFC5322.part(mbody, boundaries)
|
95
91
|
bodyslices = emailparts[0].split("\n")
|
@@ -102,8 +98,7 @@ module Sisimai::Lhost
|
|
102
98
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(startingof[:message][0])
|
103
99
|
next
|
104
100
|
end
|
105
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
106
|
-
next if e.empty?
|
101
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
107
102
|
|
108
103
|
# Original Message:
|
109
104
|
# From: kijitora <kijitora@example.jp>
|
@@ -138,8 +133,8 @@ module Sisimai::Lhost
|
|
138
133
|
return nil unless recipients > 0
|
139
134
|
|
140
135
|
# Set the value of "MAIL FROM:" and "From:"
|
141
|
-
emailparts[1]
|
142
|
-
emailparts[1]
|
136
|
+
emailparts[1] += "From: #{senderaddr}\n" if emailparts[1].include?("\nFrom: ") == false
|
137
|
+
emailparts[1] += "Subject: #{subjecttxt}\n" if emailparts[1].include?("\nSubject: ") == false
|
143
138
|
|
144
139
|
dscontents.each do |e|
|
145
140
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
@@ -151,7 +146,7 @@ module Sisimai::Lhost
|
|
151
146
|
end
|
152
147
|
end
|
153
148
|
|
154
|
-
return {
|
149
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
155
150
|
end
|
156
151
|
def description; return 'Verizon Wireless: https://www.verizonwireless.com'; end
|
157
152
|
end
|
data/lib/sisimai/lhost/x1.rb
CHANGED
@@ -7,7 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
9
9
|
Boundaries = ['Received: from '].freeze
|
10
|
-
MarkingsOf = {
|
10
|
+
MarkingsOf = {message: ['The original message was received at ']}.freeze
|
11
11
|
|
12
12
|
# @abstract Decodes the bounce message from Unknown MTA #1
|
13
13
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -18,13 +18,12 @@ module Sisimai::Lhost
|
|
18
18
|
return nil unless mhead['subject'].start_with?('Returned Mail: ')
|
19
19
|
return nil unless mhead['from'].start_with?('"Mail Deliver System" ')
|
20
20
|
|
21
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
21
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
22
22
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
23
23
|
bodyslices = emailparts[0].split("\n")
|
24
24
|
readcursor = 0 # (Integer) Points the current cursor position
|
25
25
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
26
26
|
datestring = '' # (String) Date string
|
27
|
-
v = nil
|
28
27
|
|
29
28
|
while e = bodyslices.shift do
|
30
29
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -34,8 +33,7 @@ module Sisimai::Lhost
|
|
34
33
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(MarkingsOf[:message][0])
|
35
34
|
next
|
36
35
|
end
|
37
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
38
|
-
next if e.empty?
|
36
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
39
37
|
|
40
38
|
# The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
|
41
39
|
# from shironeko@example.jp
|
@@ -70,7 +68,7 @@ module Sisimai::Lhost
|
|
70
68
|
e['date'] = datestring || ''
|
71
69
|
end
|
72
70
|
|
73
|
-
return {
|
71
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
74
72
|
end
|
75
73
|
def description; return 'Unknown MTA #1'; end
|
76
74
|
end
|
data/lib/sisimai/lhost/x2.rb
CHANGED
@@ -7,7 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
9
9
|
Boundaries = ['--- Original message follows.'].freeze
|
10
|
-
StartingOf = {
|
10
|
+
StartingOf = {message: ['Unable to deliver message to the following address']}.freeze
|
11
11
|
|
12
12
|
# @abstract Decodes the bounce message from Unknown MTA #2
|
13
13
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -22,12 +22,11 @@ module Sisimai::Lhost
|
|
22
22
|
match ||= 1 if mhead['subject'].start_with?('failed delivery')
|
23
23
|
return nil unless match
|
24
24
|
|
25
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
25
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
26
26
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
27
27
|
bodyslices = emailparts[0].split("\n")
|
28
28
|
readcursor = 0 # (Integer) Points the current cursor position
|
29
29
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
30
|
-
v = nil
|
31
30
|
|
32
31
|
while e = bodyslices.shift do
|
33
32
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -37,8 +36,7 @@ module Sisimai::Lhost
|
|
37
36
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
38
37
|
next
|
39
38
|
end
|
40
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
41
|
-
next if e.empty?
|
39
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
42
40
|
|
43
41
|
# Message from example.com.
|
44
42
|
# Unable to deliver message to the following address(es).
|
@@ -58,13 +56,13 @@ module Sisimai::Lhost
|
|
58
56
|
recipients += 1
|
59
57
|
else
|
60
58
|
# This user doesn't have a example.com account (kijitora@example.com) [0]
|
61
|
-
v['diagnosis']
|
59
|
+
v['diagnosis'] += " #{e}"
|
62
60
|
end
|
63
61
|
end
|
64
62
|
return nil unless recipients > 0
|
65
63
|
|
66
64
|
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
67
|
-
return {
|
65
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
68
66
|
end
|
69
67
|
def description; return 'Unknown MTA #2'; end
|
70
68
|
end
|
data/lib/sisimai/lhost/x3.rb
CHANGED
@@ -7,7 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
9
9
|
Boundaries = ['Content-Type: message/rfc822'].freeze
|
10
|
-
StartingOf = {
|
10
|
+
StartingOf = {message: [' This is an automatically generated Delivery Status Notification.']}.freeze
|
11
11
|
|
12
12
|
# @abstract Decodes the bounce message from Unknown MTA #3
|
13
13
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -34,8 +34,7 @@ module Sisimai::Lhost
|
|
34
34
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
35
35
|
next
|
36
36
|
end
|
37
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
38
|
-
next if e.empty?
|
37
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
39
38
|
|
40
39
|
# ============================================================================
|
41
40
|
# This is an automatically generated Delivery Status Notification.
|
@@ -87,7 +86,7 @@ module Sisimai::Lhost
|
|
87
86
|
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
88
87
|
end
|
89
88
|
|
90
|
-
return {
|
89
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
91
90
|
end
|
92
91
|
def description; return 'Unknown MTA #3'; end
|
93
92
|
end
|
data/lib/sisimai/lhost/x6.rb
CHANGED
@@ -7,7 +7,7 @@ module Sisimai::Lhost
|
|
7
7
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
9
9
|
Boundaries = ['The attachment contains the original mail headers'].freeze
|
10
|
-
StartingOf = {
|
10
|
+
StartingOf = {message: ['We had trouble delivering your message. Full details follow:']}.freeze
|
11
11
|
|
12
12
|
# @abstract Decodes the bounce message from Unknown MTA #6
|
13
13
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -18,12 +18,11 @@ module Sisimai::Lhost
|
|
18
18
|
def inquire(mhead, mbody)
|
19
19
|
return nil unless mhead['subject'].start_with?('There was an error sending your mail')
|
20
20
|
|
21
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
21
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
22
22
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
23
23
|
bodyslices = emailparts[0].split("\n")
|
24
24
|
readcursor = 0 # (Integer) Points the current cursor position
|
25
25
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
26
|
-
v = nil
|
27
26
|
|
28
27
|
while e = bodyslices.shift do
|
29
28
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -33,8 +32,7 @@ module Sisimai::Lhost
|
|
33
32
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
34
33
|
next
|
35
34
|
end
|
36
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
37
|
-
next if e.empty?
|
35
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
38
36
|
|
39
37
|
# We had trouble delivering your message. Full details follow:
|
40
38
|
#
|
@@ -89,7 +87,7 @@ module Sisimai::Lhost
|
|
89
87
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
90
88
|
end
|
91
89
|
|
92
|
-
return {
|
90
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
93
91
|
end
|
94
92
|
def description; return 'Unknown MTA #6'; end
|
95
93
|
end
|