sisimai 5.3.0-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/ChangeLog.md +12 -0
- data/Makefile +3 -2
- data/README-JA.md +2 -2
- data/README.md +6 -6
- 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 +11 -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/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 +3 -5
- data/lib/sisimai/smtp/status.rb +14 -24
- 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 +3 -2
data/lib/sisimai/fact/yaml.rb
CHANGED
@@ -10,8 +10,8 @@ module Sisimai
|
|
10
10
|
# @param [Sisimai::Fact] argvs Object
|
11
11
|
# @return [String, nil] Dumped data or nil if the argument is missing
|
12
12
|
def dump(argvs)
|
13
|
-
return
|
14
|
-
return
|
13
|
+
return "" unless argvs
|
14
|
+
return "" unless argvs.is_a? Sisimai::Fact
|
15
15
|
|
16
16
|
damneddata = argvs.damn
|
17
17
|
yamlstring = nil
|
@@ -19,7 +19,7 @@ module Sisimai
|
|
19
19
|
begin
|
20
20
|
yamlstring = ::YAML.dump(damneddata)
|
21
21
|
rescue StandardError => ce
|
22
|
-
warn '***warning: Failed to YAML.dump: '
|
22
|
+
warn '***warning: Failed to YAML.dump: ' + ce.to_s
|
23
23
|
end
|
24
24
|
|
25
25
|
return yamlstring
|
data/lib/sisimai/fact.rb
CHANGED
@@ -48,7 +48,7 @@ module Sisimai
|
|
48
48
|
|
49
49
|
RetryIndex = Sisimai::Reason.retry
|
50
50
|
RFC822Head = Sisimai::RFC5322.HEADERTABLE
|
51
|
-
ActionList = {
|
51
|
+
ActionList = {delayed: 1, delivered: 1, expanded: 1, failed: 1, relayed: 1};
|
52
52
|
|
53
53
|
if RUBY_PLATFORM.start_with?('java')
|
54
54
|
# [WORKAROUND] #159 #267 JRuby seems to fail and throws exception at strptime(), but this
|
@@ -108,7 +108,7 @@ module Sisimai
|
|
108
108
|
return nil unless argvs.is_a? Hash
|
109
109
|
|
110
110
|
email = argvs[:data]; return nil unless email
|
111
|
-
args1 = {
|
111
|
+
args1 = {data: email, hook: argvs[:hook]}
|
112
112
|
mesg1 = Sisimai::Message.rise(**args1)
|
113
113
|
return nil unless mesg1
|
114
114
|
return nil unless mesg1['ds']
|
@@ -179,7 +179,7 @@ module Sisimai
|
|
179
179
|
datevalues << mesg1['header']['date'] if datevalues.size < 2
|
180
180
|
while v = datevalues.shift do
|
181
181
|
# Parse each date value in the array
|
182
|
-
datestring = Sisimai::DateTime.parse(v)
|
182
|
+
datestring = Sisimai::DateTime.parse(v); next if datestring.empty?
|
183
183
|
|
184
184
|
if cv = datestring.match(/\A(.+)[ ]+([-+]\d{4})\z/)
|
185
185
|
# Get the value of timezone offset from datestring: Wed, 26 Feb 2014 06:05:48 -0500
|
@@ -195,7 +195,7 @@ module Sisimai
|
|
195
195
|
t = TimeModule.strptime(datestring, '%a, %d %b %Y %T')
|
196
196
|
piece['timestamp'] = (t.to_time.to_i - zoneoffset) || nil
|
197
197
|
rescue
|
198
|
-
warn
|
198
|
+
warn " ***warning: Failed to strptime #{datestring.to_s}"
|
199
199
|
end
|
200
200
|
next unless piece['timestamp']
|
201
201
|
|
@@ -402,8 +402,7 @@ module Sisimai
|
|
402
402
|
next unless er.include?(' for ')
|
403
403
|
|
404
404
|
af = Sisimai::RFC5322.received(er)
|
405
|
-
next if af.empty?
|
406
|
-
next if af[5].empty?
|
405
|
+
next if af.empty? || af[5].empty?
|
407
406
|
next unless Sisimai::Address.is_emailaddress(af[5])
|
408
407
|
next if thing['recipient'].address == af[5]
|
409
408
|
|
@@ -434,14 +433,14 @@ module Sisimai
|
|
434
433
|
thing['replycode'] = '' unless thing['reason'] == 'delivered'
|
435
434
|
else
|
436
435
|
# The reason is not "delivered", or "feedback", or "vacation"
|
437
|
-
smtperrors = piece['deliverystatus']
|
436
|
+
smtperrors = "#{piece['deliverystatus']} #{piece['diagnosticcode']}"
|
438
437
|
smtperrors = '' if smtperrors.size < 4
|
439
438
|
thing['hardbounce'] = Sisimai::SMTP::Failure.is_hardbounce(thing['reason'], smtperrors)
|
440
439
|
end
|
441
440
|
|
442
441
|
# DELIVERYSTATUS: Set a pseudo status code if the value of "deliverystatus" is empty
|
443
442
|
if thing['deliverystatus'].empty?
|
444
|
-
smtperrors = piece['replycode']
|
443
|
+
smtperrors = "#{piece['replycode']} #{piece['diagnosticcode']}"
|
445
444
|
smtperrors = '' if smtperrors.size < 4
|
446
445
|
permanent0 = Sisimai::SMTP::Failure.is_permanent(smtperrors)
|
447
446
|
temporary0 = Sisimai::SMTP::Failure.is_temporary(smtperrors)
|
@@ -459,7 +458,7 @@ module Sisimai
|
|
459
458
|
|
460
459
|
unless ActionList.has_key?(thing['action'])
|
461
460
|
# There is an action value which is not described at RFC1894
|
462
|
-
if ox = Sisimai::RFC1894.field(
|
461
|
+
if ox = Sisimai::RFC1894.field("Action: #{thing['action']}")
|
463
462
|
# Rewrite the value of "Action:" field to the valid value
|
464
463
|
#
|
465
464
|
# The syntax for the action-field is:
|
@@ -509,7 +508,7 @@ module Sisimai
|
|
509
508
|
v['recipient'] = self.recipient.address
|
510
509
|
v['timestamp'] = self.timestamp.to_time.to_i
|
511
510
|
|
512
|
-
# Backward compatibility until v5.
|
511
|
+
# Backward compatibility until v5.5.0
|
513
512
|
v["smtpagent"] = self.decodedby
|
514
513
|
v["smtpcommand"] = self.command
|
515
514
|
data = v
|
@@ -526,12 +525,12 @@ module Sisimai
|
|
526
525
|
# [Nil] The value of the first argument is neither "json" nor "yaml"
|
527
526
|
def dump(type = 'json')
|
528
527
|
return nil unless %w[json yaml].include?(type)
|
529
|
-
referclass =
|
528
|
+
referclass = "Sisimai::Fact::#{type.upcase}"
|
530
529
|
|
531
530
|
begin
|
532
531
|
require referclass.downcase.gsub('::', '/')
|
533
532
|
rescue
|
534
|
-
warn
|
533
|
+
warn "***warning: Failed to load #{referclass}"
|
535
534
|
end
|
536
535
|
|
537
536
|
dumpeddata = Module.const_get(referclass).dump(self)
|
data/lib/sisimai/lda.rb
CHANGED
@@ -68,9 +68,9 @@ module Sisimai
|
|
68
68
|
# @param [Sisimai::Fact] argvs Decoded email object
|
69
69
|
# @return [String] Bounce reason
|
70
70
|
def find(argvs)
|
71
|
-
return
|
72
|
-
return ""
|
73
|
-
return ""
|
71
|
+
return "" if argvs.nil?
|
72
|
+
return "" if argvs["diagnosticcode"].empty?
|
73
|
+
return "" if argvs["command"] != "" && argvs["command"] != "DATA"
|
74
74
|
|
75
75
|
deliversby = "" # [String] Local Delivery Agent name
|
76
76
|
reasontext = "" # [String] Error reason
|
@@ -8,7 +8,7 @@ module Sisimai::Lhost
|
|
8
8
|
|
9
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
10
|
Boundaries = ['Content-Type: message/rfc822'].freeze
|
11
|
-
StartingOf = {
|
11
|
+
StartingOf = {message: [' ----- The following addresses had permanent fatal errors -----']}.freeze
|
12
12
|
|
13
13
|
# @abstract decodes the bounce message from QUALITIA Active!hunter
|
14
14
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -20,12 +20,11 @@ module Sisimai::Lhost
|
|
20
20
|
# :subject => %r/FAILURE NOTICE :/,
|
21
21
|
return nil unless mhead['x-ahmailid']
|
22
22
|
|
23
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
23
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
24
24
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
25
25
|
bodyslices = emailparts[0].split("\n")
|
26
26
|
readcursor = 0 # (Integer) Points the current cursor position
|
27
27
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
28
|
-
v = nil
|
29
28
|
|
30
29
|
while e = bodyslices.shift do
|
31
30
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -35,8 +34,7 @@ module Sisimai::Lhost
|
|
35
34
|
readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
|
36
35
|
next
|
37
36
|
end
|
38
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
39
|
-
next if e.empty?
|
37
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
40
38
|
|
41
39
|
# ----- The following addresses had permanent fatal errors -----
|
42
40
|
#
|
@@ -68,7 +66,7 @@ module Sisimai::Lhost
|
|
68
66
|
return nil unless recipients > 0
|
69
67
|
|
70
68
|
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
71
|
-
return {
|
69
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
72
70
|
end
|
73
71
|
def description; return 'TransWARE Active!hunter'; end
|
74
72
|
end
|
@@ -111,7 +111,7 @@ module Sisimai::Lhost
|
|
111
111
|
end
|
112
112
|
rescue StandardError => ce
|
113
113
|
# Something wrong in decoding JSON
|
114
|
-
warn
|
114
|
+
warn " ***warning: Failed to decode JSON: #{ce.to_s}"
|
115
115
|
return nil
|
116
116
|
end
|
117
117
|
return nil if jsonobject.has_key?("notificationType") == false
|
@@ -121,10 +121,9 @@ module Sisimai::Lhost
|
|
121
121
|
require "sisimai/smtp/reply"
|
122
122
|
require "sisimai/smtp/status"
|
123
123
|
require "sisimai/smtp/command"
|
124
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
124
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = dscontents[-1]
|
125
125
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
126
126
|
whatnotify = jsonobject["notificationType"][0, 1] || ""
|
127
|
-
v = dscontents[-1]
|
128
127
|
|
129
128
|
if whatnotify == "B"
|
130
129
|
# "notificationType":"Bounce"
|
@@ -207,13 +206,13 @@ module Sisimai::Lhost
|
|
207
206
|
|
208
207
|
cv = ""
|
209
208
|
jsonobject["mail"]["headers"].each do |e|
|
210
|
-
cv
|
209
|
+
cv += sprintf("%s: %s\n", e["name"], e["value"])
|
211
210
|
end
|
212
211
|
%w[date subject].each do |e|
|
213
212
|
next if jsonobject["mail"]["commonHeaders"].has_key?(e) == false
|
214
|
-
cv
|
213
|
+
cv += sprintf("%s: %s\n", e.capitalize, jsonobject["mail"]["commonHeaders"][e])
|
215
214
|
end
|
216
|
-
return {
|
215
|
+
return {"ds" => dscontents, "rfc822" => cv}
|
217
216
|
end
|
218
217
|
def description; return 'Amazon SES(Sending): https://aws.amazon.com/ses/'; end
|
219
218
|
end
|
@@ -26,13 +26,12 @@ module Sisimai::Lhost
|
|
26
26
|
match += 1 if mhead["received"].any? { |a| a.include?("JAMES SMTP Server") }
|
27
27
|
return nil unless match > 0
|
28
28
|
|
29
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
29
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = dscontents[-1]
|
30
30
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
31
31
|
bodyslices = emailparts[0].split("\n")
|
32
32
|
readcursor = 0 # Points the current cursor position
|
33
33
|
recipients = 0 # The number of 'Final-Recipient' header
|
34
34
|
alternates = ["", "", "", ""] # [Envelope-From, Header-From, Date, Subject]
|
35
|
-
v = dscontents[-1]
|
36
35
|
|
37
36
|
while e = bodyslices.shift do
|
38
37
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -45,11 +44,10 @@ module Sisimai::Lhost
|
|
45
44
|
readcursor |= Indicators[:deliverystatus]
|
46
45
|
next
|
47
46
|
end
|
48
|
-
v["diagnosis"]
|
47
|
+
v["diagnosis"] += "#{e }" if e != ""
|
49
48
|
next
|
50
49
|
end
|
51
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
52
|
-
next if e.empty?
|
50
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
53
51
|
|
54
52
|
# Message details:
|
55
53
|
# Subject: Nyaaan
|
@@ -93,16 +91,16 @@ module Sisimai::Lhost
|
|
93
91
|
|
94
92
|
if emailparts[1].empty?
|
95
93
|
# The original message is empty
|
96
|
-
emailparts[1]
|
97
|
-
emailparts[1]
|
94
|
+
emailparts[1] += sprintf("From: %s\n", alternates[1]) if alternates[1] != ""
|
95
|
+
emailparts[1] += sprintf("Date: %s\n", alternates[2]) if alternates[2] != ""
|
98
96
|
end
|
99
97
|
if emailparts[1].include?("Return-Path: ") == false
|
100
98
|
# Set the envelope from address as a Return-Path: header
|
101
|
-
emailparts[1]
|
99
|
+
emailparts[1] += sprintf("Return-Path: <%s>\n", alternates[0]) if alternates[0] != ""
|
102
100
|
end
|
103
101
|
if emailparts[1].include?("\nSubject: ") == false
|
104
102
|
# Set the envelope from address as a Return-Path: header
|
105
|
-
emailparts[1]
|
103
|
+
emailparts[1] += sprintf("Subject: %s\n", alternates[3]) if alternates[3] != ""
|
106
104
|
end
|
107
105
|
|
108
106
|
dscontents.each { |e| e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"]) }
|
@@ -26,12 +26,11 @@ module Sisimai::Lhost
|
|
26
26
|
return nil unless %w[biglobe inacatv tmtv ttv].any? { |a| mhead['from'].include?('@' + a + '.ne.jp') }
|
27
27
|
return nil unless mhead['subject'].start_with?('Returned mail:')
|
28
28
|
|
29
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
29
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
30
30
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
31
31
|
bodyslices = emailparts[0].split("\n")
|
32
32
|
readcursor = 0 # (Integer) Points the current cursor position
|
33
33
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
34
|
-
v = nil
|
35
34
|
|
36
35
|
while e = bodyslices.shift do
|
37
36
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -41,8 +40,7 @@ module Sisimai::Lhost
|
|
41
40
|
readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
|
42
41
|
next
|
43
42
|
end
|
44
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
45
|
-
next if e.empty?
|
43
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
46
44
|
|
47
45
|
# This is a MIME-encapsulated message.
|
48
46
|
#
|
@@ -74,7 +72,7 @@ module Sisimai::Lhost
|
|
74
72
|
recipients += 1
|
75
73
|
else
|
76
74
|
next if e.include?('--')
|
77
|
-
v['diagnosis']
|
75
|
+
v['diagnosis'] += "#{e }"
|
78
76
|
end
|
79
77
|
end
|
80
78
|
return nil unless recipients > 0
|
@@ -44,14 +44,13 @@ module Sisimai::Lhost
|
|
44
44
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
45
45
|
permessage = {} # (Hash) Store values of each Per-Message field
|
46
46
|
|
47
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
47
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
48
48
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
49
49
|
bodyslices = emailparts[0].split("\n")
|
50
50
|
readslices = ['']
|
51
51
|
readcursor = 0 # (Integer) Points the current cursor position
|
52
52
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
53
53
|
thecommand = '' # (String) SMTP Command name begin with the string '>>>'
|
54
|
-
v = nil
|
55
54
|
|
56
55
|
while e = bodyslices.shift do
|
57
56
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -65,8 +64,7 @@ module Sisimai::Lhost
|
|
65
64
|
next
|
66
65
|
end
|
67
66
|
end
|
68
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
69
|
-
next if e.empty?
|
67
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
70
68
|
|
71
69
|
f = Sisimai::RFC1894.match(e)
|
72
70
|
if f > 0
|
@@ -118,8 +116,8 @@ module Sisimai::Lhost
|
|
118
116
|
# Continued line of the value of Diagnostic-Code field
|
119
117
|
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
120
118
|
next unless e.start_with?(' ')
|
121
|
-
v['diagnosis']
|
122
|
-
readslices[-1]
|
119
|
+
v['diagnosis'] += " #{Sisimai::String.sweep(e)}"
|
120
|
+
readslices[-1] = "Diagnostic-Code: #{e}"
|
123
121
|
end
|
124
122
|
end
|
125
123
|
end
|
data/lib/sisimai/lhost/domino.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: ['Your message']}.freeze
|
11
11
|
MessagesOf = {
|
12
12
|
"filtered" => ["Cannot route mail to user"],
|
13
13
|
"systemerror" => ["Several matches found in Domino Directory"],
|
@@ -33,13 +33,12 @@ module Sisimai::Lhost
|
|
33
33
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
34
34
|
permessage = {} # (Hash) Store values of each Per-Message field
|
35
35
|
|
36
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
36
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
37
37
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
38
38
|
bodyslices = emailparts[0].split("\n")
|
39
39
|
readcursor = 0 # (Integer) Points the current cursor position
|
40
40
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
41
41
|
subjecttxt = '' # (String) The value of Subject:
|
42
|
-
v = nil
|
43
42
|
|
44
43
|
while e = bodyslices.shift do
|
45
44
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -135,9 +134,9 @@ module Sisimai::Lhost
|
|
135
134
|
end
|
136
135
|
|
137
136
|
# Set the value of subjecttxt as a Subject if there is no original message in the bounce mail.
|
138
|
-
emailparts[1]
|
137
|
+
emailparts[1] += "Subject: #{subjecttxt}\n" unless emailparts[1].include?("\nSubject:")
|
139
138
|
|
140
|
-
return {
|
139
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
141
140
|
end
|
142
141
|
def description; return 'IBM Domino Server'; end
|
143
142
|
end
|
@@ -41,12 +41,11 @@ module Sisimai::Lhost
|
|
41
41
|
return nil unless mhead['subject'].start_with?('Mail delivery failed')
|
42
42
|
return nil unless mhead['received'].any? { |a| a.include?(' (DragonFly Mail Agent') }
|
43
43
|
|
44
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
44
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
45
45
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
46
46
|
bodyslices = emailparts[0].split("\n")
|
47
47
|
readcursor = 0 # (Integer) Points the current cursor position
|
48
48
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
49
|
-
v = nil
|
50
49
|
|
51
50
|
while e = bodyslices.shift do
|
52
51
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -56,8 +55,7 @@ module Sisimai::Lhost
|
|
56
55
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
57
56
|
next
|
58
57
|
end
|
59
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
60
|
-
next if e.empty?
|
58
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
61
59
|
|
62
60
|
# This is the DragonFly Mail Agent v0.13 at df.example.jp.
|
63
61
|
#
|
@@ -81,7 +79,7 @@ module Sisimai::Lhost
|
|
81
79
|
recipients += 1
|
82
80
|
else
|
83
81
|
# Pick the error message
|
84
|
-
v['diagnosis']
|
82
|
+
v['diagnosis'] += " #{e}"
|
85
83
|
|
86
84
|
# Pick the remote hostname, and the SMTP command
|
87
85
|
# net.c:500| snprintf(errmsg, sizeof(errmsg), "%s [%s] did not like our %s:\n%s",
|
@@ -11,7 +11,7 @@ module Sisimai::Lhost
|
|
11
11
|
message: ['This message was created automatically by mail delivery software'],
|
12
12
|
error: ['For the following reason:'],
|
13
13
|
}.freeze
|
14
|
-
MessagesOf = {
|
14
|
+
MessagesOf = {'mesgtoobig' => ['Mail size limit exceeded']}.freeze
|
15
15
|
|
16
16
|
# @abstract Decode the bounce message from 1&1
|
17
17
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -22,12 +22,11 @@ module Sisimai::Lhost
|
|
22
22
|
return nil unless mhead['from'].start_with?('"Mail Delivery System"')
|
23
23
|
return nil unless mhead['subject'] == 'Mail delivery failed: returning message to sender'
|
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
|
@@ -38,8 +37,7 @@ module Sisimai::Lhost
|
|
38
37
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
39
38
|
next
|
40
39
|
end
|
41
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
42
|
-
next if e.empty?
|
40
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
43
41
|
|
44
42
|
# The following address failed:
|
45
43
|
#
|
@@ -68,13 +66,13 @@ module Sisimai::Lhost
|
|
68
66
|
else
|
69
67
|
if v['diagnosis']
|
70
68
|
# Get error message and append error message strings
|
71
|
-
v['diagnosis']
|
69
|
+
v['diagnosis'] += " #{e}"
|
72
70
|
else
|
73
71
|
# OR the following format:
|
74
72
|
# neko@example.fr:
|
75
73
|
# SMTP error from remote server for TEXT command, host: ...
|
76
74
|
v['alterrors'] ||= ''
|
77
|
-
v['alterrors']
|
75
|
+
v['alterrors'] += " #{e}"
|
78
76
|
end
|
79
77
|
end
|
80
78
|
end
|
@@ -110,7 +108,7 @@ module Sisimai::Lhost
|
|
110
108
|
end
|
111
109
|
end
|
112
110
|
|
113
|
-
return {
|
111
|
+
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
114
112
|
end
|
115
113
|
def description; return '1&1: https://www.1und1.de'; end
|
116
114
|
end
|
@@ -83,7 +83,7 @@ module Sisimai::Lhost
|
|
83
83
|
end
|
84
84
|
return nil unless match > 0
|
85
85
|
|
86
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
86
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
87
87
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
88
88
|
bodyslices = emailparts[0].split("\n")
|
89
89
|
readcursor = 0 # (Integer) Points the current cursor position
|
@@ -95,7 +95,6 @@ module Sisimai::Lhost
|
|
95
95
|
'date' => '', # The value of "Date"
|
96
96
|
'subject' => '', # The value of "Subject"
|
97
97
|
}
|
98
|
-
v = nil
|
99
98
|
|
100
99
|
while e = bodyslices.shift do
|
101
100
|
# Read error messages and delivery status lines from the head of the email to the previous
|
@@ -105,8 +104,7 @@ module Sisimai::Lhost
|
|
105
104
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
106
105
|
next
|
107
106
|
end
|
108
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
109
|
-
next if statuspart
|
107
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || statuspart == true
|
110
108
|
|
111
109
|
if connvalues == connheader.keys.size
|
112
110
|
# did not reach the following recipient(s):
|
@@ -139,18 +137,18 @@ module Sisimai::Lhost
|
|
139
137
|
|
140
138
|
elsif e.start_with?(' ') && e.include?('MSEXCH:')
|
141
139
|
# MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
|
142
|
-
v['diagnosis']
|
140
|
+
v['diagnosis'] += e[e.index('MSEXCH:'), e.size]
|
143
141
|
else
|
144
142
|
next if v['msexch']
|
145
143
|
if v['diagnosis'].start_with?('MSEXCH:')
|
146
144
|
# Continued from MEEXCH in the previous line
|
147
145
|
v['msexch'] = true
|
148
|
-
v['diagnosis']
|
146
|
+
v['diagnosis'] += " #{e}"
|
149
147
|
statuspart = true
|
150
148
|
else
|
151
149
|
# Error message in the body part
|
152
150
|
v['alterrors'] ||= ''
|
153
|
-
v['alterrors']
|
151
|
+
v['alterrors'] += " #{e}"
|
154
152
|
end
|
155
153
|
end
|
156
154
|
else
|
@@ -197,7 +195,7 @@ module Sisimai::Lhost
|
|
197
195
|
# Find captured code from the error code table
|
198
196
|
next unless ErrorCodes[r].index(capturedcode)
|
199
197
|
e['reason'] = r
|
200
|
-
e['status'] = Sisimai::SMTP::Status.code(r)
|
198
|
+
e['status'] = Sisimai::SMTP::Status.code(r)
|
201
199
|
break
|
202
200
|
end
|
203
201
|
e['diagnosis'] = errormessage
|
@@ -208,7 +206,7 @@ module Sisimai::Lhost
|
|
208
206
|
next if e["alterrors"].empty?
|
209
207
|
|
210
208
|
# Copy alternative error message
|
211
|
-
e['diagnosis'] = e['alterrors']
|
209
|
+
e['diagnosis'] = "#{e['alterrors']} #{e['diagnosis']}"
|
212
210
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
213
211
|
e.delete('alterrors')
|
214
212
|
end
|
@@ -216,9 +214,9 @@ module Sisimai::Lhost
|
|
216
214
|
|
217
215
|
if emailparts[1].empty?
|
218
216
|
# When original message does not included in the bounce message
|
219
|
-
emailparts[1]
|
220
|
-
emailparts[1]
|
221
|
-
emailparts[1]
|
217
|
+
emailparts[1] += "From: #{connheader['to']}\n"
|
218
|
+
emailparts[1] += "Date: #{connheader['date']}\n"
|
219
|
+
emailparts[1] += "Subject: #{connheader['subject']}\n"
|
222
220
|
end
|
223
221
|
|
224
222
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
@@ -85,8 +85,7 @@ module Sisimai::Lhost
|
|
85
85
|
readcursor |= Indicators[:deliverystatus] if StartingOf[:message].any? { |a| e.start_with?(a) }
|
86
86
|
next
|
87
87
|
end
|
88
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
89
|
-
next if e == ""
|
88
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
90
89
|
|
91
90
|
# Diagnostic information for administrators:
|
92
91
|
#
|
@@ -124,9 +123,9 @@ module Sisimai::Lhost
|
|
124
123
|
if cr != "" || cs != "" || e.include?("Remote Server ")
|
125
124
|
# Remote Server returned '550 5.1.1 RESOLVER.ADR.RecipNotFound; not found'
|
126
125
|
# 3/09/2016 8:05:56 PM - Remote Server at mydomain.com (10.1.1.3) returned '550 4.4.7 QUEUE.Expired; message expired'
|
127
|
-
v["replycode"]
|
128
|
-
v["status"]
|
129
|
-
v["diagnosis"]
|
126
|
+
v["replycode"] = cr
|
127
|
+
v["status"] = cs
|
128
|
+
v["diagnosis"] += "#{e }"
|
130
129
|
end
|
131
130
|
end
|
132
131
|
end
|
data/lib/sisimai/lhost/exim.rb
CHANGED
@@ -168,14 +168,13 @@ module Sisimai::Lhost
|
|
168
168
|
require "sisimai/rfc2045"
|
169
169
|
require "sisimai/smtp/command"
|
170
170
|
|
171
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
171
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
172
172
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
173
173
|
bodyslices = emailparts[0].split("\n")
|
174
174
|
readcursor = 0 # (Integer) Points the current cursor position
|
175
175
|
nextcursor = false
|
176
176
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
177
177
|
boundary00 = "" # (String) Boundary string
|
178
|
-
v = nil
|
179
178
|
|
180
179
|
if mhead["content-type"]
|
181
180
|
# Get the boundary string and set regular expression for matching with the boundary string.
|
@@ -194,8 +193,7 @@ module Sisimai::Lhost
|
|
194
193
|
next unless StartingOf["frozen"].any? { |a| e.include?(a) }
|
195
194
|
end
|
196
195
|
end
|
197
|
-
next if (readcursor & Indicators[:deliverystatus]) == 0
|
198
|
-
next if e.empty?
|
196
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
199
197
|
|
200
198
|
# This message was created automatically by mail delivery software.
|
201
199
|
#
|
@@ -279,7 +277,7 @@ module Sisimai::Lhost
|
|
279
277
|
# Message *** has been frozen by the system filter.
|
280
278
|
# Message *** was frozen on arrival by ACL.
|
281
279
|
v["alterrors"] ||= ""
|
282
|
-
v["alterrors"]
|
280
|
+
v["alterrors"] += "#{e} "
|
283
281
|
elsif boundary00 != ""
|
284
282
|
# --NNNNNNNNNN-eximdsn-MMMMMMMMMM
|
285
283
|
# Content-type: message/delivery-status
|
@@ -313,19 +311,19 @@ module Sisimai::Lhost
|
|
313
311
|
# Content-type: message/delivery-status
|
314
312
|
nextcursor = true if e.start_with?(StartingOf["deliverystatus"][0])
|
315
313
|
v["alterrors"] ||= ''
|
316
|
-
v["alterrors"]
|
314
|
+
v["alterrors"] += "#{e} " unless v["alterrors"].include?(e) if e.start_with?(" ")
|
317
315
|
end
|
318
316
|
else
|
319
317
|
# There is no boundary string in $boundary00
|
320
318
|
if dscontents.size == recipients
|
321
319
|
# Error message
|
322
|
-
v["diagnosis"]
|
320
|
+
v["diagnosis"] += "#{e} "
|
323
321
|
else
|
324
322
|
# Error message when email address above does not include '@' and domain part
|
325
323
|
# pipe to |/path/to/prog ...
|
326
324
|
# generated by kijitora@example.com
|
327
325
|
next unless e.start_with?(" ")
|
328
|
-
v["diagnosis"]
|
326
|
+
v["diagnosis"] += "#{e} "
|
329
327
|
end
|
330
328
|
end
|
331
329
|
end
|