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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +12 -0
  3. data/Makefile +3 -2
  4. data/README-JA.md +2 -2
  5. data/README.md +6 -6
  6. data/lib/sisimai/address.rb +45 -56
  7. data/lib/sisimai/arf.rb +11 -16
  8. data/lib/sisimai/datetime.rb +16 -50
  9. data/lib/sisimai/fact/json.rb +5 -5
  10. data/lib/sisimai/fact/yaml.rb +3 -3
  11. data/lib/sisimai/fact.rb +11 -12
  12. data/lib/sisimai/lda.rb +3 -3
  13. data/lib/sisimai/lhost/activehunter.rb +4 -6
  14. data/lib/sisimai/lhost/amazonses.rb +5 -6
  15. data/lib/sisimai/lhost/apachejames.rb +7 -9
  16. data/lib/sisimai/lhost/biglobe.rb +3 -5
  17. data/lib/sisimai/lhost/courier.rb +4 -6
  18. data/lib/sisimai/lhost/domino.rb +4 -5
  19. data/lib/sisimai/lhost/dragonfly.rb +3 -5
  20. data/lib/sisimai/lhost/einsundeins.rb +6 -8
  21. data/lib/sisimai/lhost/exchange2003.rb +10 -12
  22. data/lib/sisimai/lhost/exchange2007.rb +4 -5
  23. data/lib/sisimai/lhost/exim.rb +6 -8
  24. data/lib/sisimai/lhost/ezweb.rb +10 -12
  25. data/lib/sisimai/lhost/fml.rb +2 -3
  26. data/lib/sisimai/lhost/gmail.rb +4 -6
  27. data/lib/sisimai/lhost/gmx.rb +6 -8
  28. data/lib/sisimai/lhost/googlegroups.rb +1 -2
  29. data/lib/sisimai/lhost/googleworkspace.rb +3 -4
  30. data/lib/sisimai/lhost/imailserver.rb +6 -7
  31. data/lib/sisimai/lhost/interscanmss.rb +1 -2
  32. data/lib/sisimai/lhost/kddi.rb +5 -8
  33. data/lib/sisimai/lhost/mailfoundry.rb +4 -7
  34. data/lib/sisimai/lhost/mailmarshalsmtp.rb +4 -6
  35. data/lib/sisimai/lhost/messagingserver.rb +5 -7
  36. data/lib/sisimai/lhost/mfilter.rb +4 -6
  37. data/lib/sisimai/lhost/notes.rb +7 -9
  38. data/lib/sisimai/lhost/opensmtpd.rb +2 -4
  39. data/lib/sisimai/lhost/postfix.rb +8 -11
  40. data/lib/sisimai/lhost/qmail.rb +5 -8
  41. data/lib/sisimai/lhost/sendmail.rb +7 -10
  42. data/lib/sisimai/lhost/v5sendmail.rb +15 -17
  43. data/lib/sisimai/lhost/verizon.rb +9 -14
  44. data/lib/sisimai/lhost/x1.rb +4 -6
  45. data/lib/sisimai/lhost/x2.rb +5 -7
  46. data/lib/sisimai/lhost/x3.rb +3 -4
  47. data/lib/sisimai/lhost/x6.rb +4 -6
  48. data/lib/sisimai/lhost/zoho.rb +6 -8
  49. data/lib/sisimai/lhost.rb +1 -1
  50. data/lib/sisimai/mail/mbox.rb +1 -1
  51. data/lib/sisimai/mail/memory.rb +1 -1
  52. data/lib/sisimai/mail.rb +8 -8
  53. data/lib/sisimai/message.rb +11 -13
  54. data/lib/sisimai/reason/authfailure.rb +10 -10
  55. data/lib/sisimai/reason/badreputation.rb +4 -6
  56. data/lib/sisimai/reason/blocked.rb +6 -8
  57. data/lib/sisimai/reason/contenterror.rb +5 -6
  58. data/lib/sisimai/reason/delivered.rb +2 -2
  59. data/lib/sisimai/reason/exceedlimit.rb +7 -8
  60. data/lib/sisimai/reason/expired.rb +6 -7
  61. data/lib/sisimai/reason/failedstarttls.rb +5 -7
  62. data/lib/sisimai/reason/feedback.rb +2 -2
  63. data/lib/sisimai/reason/filtered.rb +7 -10
  64. data/lib/sisimai/reason/hasmoved.rb +4 -5
  65. data/lib/sisimai/reason/hostunknown.rb +6 -7
  66. data/lib/sisimai/reason/mailboxfull.rb +7 -8
  67. data/lib/sisimai/reason/mailererror.rb +5 -8
  68. data/lib/sisimai/reason/mesgtoobig.rb +5 -6
  69. data/lib/sisimai/reason/networkerror.rb +5 -8
  70. data/lib/sisimai/reason/norelaying.rb +4 -5
  71. data/lib/sisimai/reason/notaccept.rb +5 -8
  72. data/lib/sisimai/reason/notcompliantrfc.rb +5 -6
  73. data/lib/sisimai/reason/onhold.rb +6 -9
  74. data/lib/sisimai/reason/policyviolation.rb +6 -9
  75. data/lib/sisimai/reason/rejected.rb +5 -6
  76. data/lib/sisimai/reason/requireptr.rb +6 -7
  77. data/lib/sisimai/reason/securityerror.rb +6 -9
  78. data/lib/sisimai/reason/spamdetected.rb +8 -9
  79. data/lib/sisimai/reason/speeding.rb +6 -7
  80. data/lib/sisimai/reason/suppressed.rb +3 -7
  81. data/lib/sisimai/reason/suspend.rb +5 -7
  82. data/lib/sisimai/reason/syntaxerror.rb +3 -5
  83. data/lib/sisimai/reason/systemerror.rb +6 -9
  84. data/lib/sisimai/reason/systemfull.rb +5 -8
  85. data/lib/sisimai/reason/toomanyconn.rb +5 -6
  86. data/lib/sisimai/reason/undefined.rb +2 -2
  87. data/lib/sisimai/reason/userunknown.rb +8 -9
  88. data/lib/sisimai/reason/vacation.rb +4 -5
  89. data/lib/sisimai/reason/virusdetected.rb +4 -5
  90. data/lib/sisimai/reason.rb +13 -13
  91. data/lib/sisimai/rfc1123.rb +4 -8
  92. data/lib/sisimai/rfc1894.rb +5 -6
  93. data/lib/sisimai/rfc2045.rb +27 -31
  94. data/lib/sisimai/rfc3464/thirdparty.rb +1 -1
  95. data/lib/sisimai/rfc3464.rb +7 -9
  96. data/lib/sisimai/rfc3834.rb +5 -9
  97. data/lib/sisimai/rfc5322.rb +8 -26
  98. data/lib/sisimai/rfc791.rb +6 -4
  99. data/lib/sisimai/rhost/google.rb +8 -0
  100. data/lib/sisimai/rhost/microsoft.rb +17 -5
  101. data/lib/sisimai/rhost.rb +2 -2
  102. data/lib/sisimai/smtp/command.rb +1 -1
  103. data/lib/sisimai/smtp/failure.rb +5 -12
  104. data/lib/sisimai/smtp/reply.rb +3 -5
  105. data/lib/sisimai/smtp/status.rb +14 -24
  106. data/lib/sisimai/smtp/transcript.rb +1 -10
  107. data/lib/sisimai/string.rb +20 -30
  108. data/lib/sisimai/version.rb +1 -1
  109. data/lib/sisimai.rb +11 -11
  110. data/set-of-emails/maildir/bsd/rhost-microsoft-06.eml +45 -0
  111. metadata +3 -2
@@ -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 nil unless argvs
14
- return nil unless argvs.is_a? Sisimai::Fact
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: ' << ce.to_s
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 = { delayed: 1, delivered: 1, expanded: 1, failed: 1, relayed: 1 };
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 = { data: email, hook: argvs[:hook] }
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) || next
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 ' ***warning: Failed to strptime ' << datestring.to_s
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'] + ' ' << piece['diagnosticcode']
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'] + ' ' << piece['diagnosticcode']
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('Action: ' << thing['action'])
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.2.0
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 = 'Sisimai::Fact::' << type.upcase
528
+ referclass = "Sisimai::Fact::#{type.upcase}"
530
529
 
531
530
  begin
532
531
  require referclass.downcase.gsub('::', '/')
533
532
  rescue
534
- warn '***warning: Failed to load' << referclass
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 nil if argvs.nil?
72
- return "" if argvs["diagnosticcode"].empty?
73
- return "" if argvs["command"] != "" && argvs["command"] != "DATA"
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 = { message: [' ----- The following addresses had permanent fatal errors -----'] }.freeze
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
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 ' ***warning: Failed to decode JSON: ' << ce.to_s
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 << sprintf("%s: %s\n", e["name"], e["value"])
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 << sprintf("%s: %s\n", e.capitalize, jsonobject["mail"]["commonHeaders"][e])
213
+ cv += sprintf("%s: %s\n", e.capitalize, jsonobject["mail"]["commonHeaders"][e])
215
214
  end
216
- return { "ds" => dscontents, "rfc822" => cv }
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"] << e << " " if e != ""
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] << sprintf("From: %s\n", alternates[1]) if alternates[1] != ""
97
- emailparts[1] << sprintf("Date: %s\n", alternates[2]) if alternates[2] != ""
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] << sprintf("Return-Path: <%s>\n", alternates[0]) if alternates[0] != ""
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] << sprintf("Subject: %s\n", alternates[3]) if alternates[3] != ""
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'] << e + ' '
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'] << ' ' << Sisimai::String.sweep(e)
122
- readslices[-1] = 'Diagnostic-Code: ' << e
119
+ v['diagnosis'] += " #{Sisimai::String.sweep(e)}"
120
+ readslices[-1] = "Diagnostic-Code: #{e}"
123
121
  end
124
122
  end
125
123
  end
@@ -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 = { message: ['Your message'] }.freeze
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] << ('Subject: ' << subjecttxt << "\n") unless emailparts[1].include?("\nSubject:")
137
+ emailparts[1] += "Subject: #{subjecttxt}\n" unless emailparts[1].include?("\nSubject:")
139
138
 
140
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
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'] << ' ' << e
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 = { 'mesgtoobig' => ['Mail size limit exceeded'] }.freeze
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'] << ' ' << e
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'] << ' ' << e
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
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'] << e[e.index('MSEXCH:'), e.size]
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'] << ' ' << e
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'] << ' ' << e
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'] + ' ' + e['diagnosis']
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] << ('From: ' << connheader['to'] << "\n")
220
- emailparts[1] << ('Date: ' << connheader['date'] << "\n")
221
- emailparts[1] << ('Subject: ' << connheader['subject'] << "\n")
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"] = cr
128
- v["status"] = cs
129
- v["diagnosis"] << e << " "
126
+ v["replycode"] = cr
127
+ v["status"] = cs
128
+ v["diagnosis"] += "#{e }"
130
129
  end
131
130
  end
132
131
  end
@@ -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"] << e + " "
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"] << e + " " unless v["alterrors"].include?(e) if e.start_with?(" ")
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"] << e + " "
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"] << e + " "
326
+ v["diagnosis"] += "#{e} "
329
327
  end
330
328
  end
331
329
  end