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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake-test.yml +1 -1
  3. data/ChangeLog.md +24 -0
  4. data/Makefile +3 -2
  5. data/README-JA.md +4 -4
  6. data/README.md +8 -8
  7. data/lib/sisimai/address.rb +45 -56
  8. data/lib/sisimai/arf.rb +11 -16
  9. data/lib/sisimai/datetime.rb +16 -50
  10. data/lib/sisimai/fact/json.rb +5 -5
  11. data/lib/sisimai/fact/yaml.rb +3 -3
  12. data/lib/sisimai/fact.rb +21 -12
  13. data/lib/sisimai/lda.rb +3 -3
  14. data/lib/sisimai/lhost/activehunter.rb +4 -6
  15. data/lib/sisimai/lhost/amazonses.rb +5 -6
  16. data/lib/sisimai/lhost/apachejames.rb +7 -9
  17. data/lib/sisimai/lhost/biglobe.rb +3 -5
  18. data/lib/sisimai/lhost/courier.rb +4 -6
  19. data/lib/sisimai/lhost/domino.rb +4 -5
  20. data/lib/sisimai/lhost/dragonfly.rb +3 -5
  21. data/lib/sisimai/lhost/einsundeins.rb +6 -8
  22. data/lib/sisimai/lhost/exchange2003.rb +10 -12
  23. data/lib/sisimai/lhost/exchange2007.rb +4 -5
  24. data/lib/sisimai/lhost/exim.rb +6 -8
  25. data/lib/sisimai/lhost/ezweb.rb +10 -12
  26. data/lib/sisimai/lhost/fml.rb +2 -3
  27. data/lib/sisimai/lhost/gmail.rb +4 -6
  28. data/lib/sisimai/lhost/gmx.rb +6 -8
  29. data/lib/sisimai/lhost/googlegroups.rb +1 -2
  30. data/lib/sisimai/lhost/googleworkspace.rb +3 -4
  31. data/lib/sisimai/lhost/imailserver.rb +6 -7
  32. data/lib/sisimai/lhost/interscanmss.rb +1 -2
  33. data/lib/sisimai/lhost/kddi.rb +5 -8
  34. data/lib/sisimai/lhost/mailfoundry.rb +4 -7
  35. data/lib/sisimai/lhost/mailmarshalsmtp.rb +4 -6
  36. data/lib/sisimai/lhost/messagingserver.rb +5 -7
  37. data/lib/sisimai/lhost/mfilter.rb +4 -6
  38. data/lib/sisimai/lhost/notes.rb +7 -9
  39. data/lib/sisimai/lhost/opensmtpd.rb +2 -4
  40. data/lib/sisimai/lhost/postfix.rb +8 -11
  41. data/lib/sisimai/lhost/qmail.rb +5 -8
  42. data/lib/sisimai/lhost/sendmail.rb +7 -10
  43. data/lib/sisimai/lhost/v5sendmail.rb +15 -17
  44. data/lib/sisimai/lhost/verizon.rb +9 -14
  45. data/lib/sisimai/lhost/x1.rb +4 -6
  46. data/lib/sisimai/lhost/x2.rb +5 -7
  47. data/lib/sisimai/lhost/x3.rb +3 -4
  48. data/lib/sisimai/lhost/x6.rb +4 -6
  49. data/lib/sisimai/lhost/zoho.rb +6 -8
  50. data/lib/sisimai/lhost.rb +1 -1
  51. data/lib/sisimai/mail/mbox.rb +1 -1
  52. data/lib/sisimai/mail/memory.rb +1 -1
  53. data/lib/sisimai/mail.rb +8 -8
  54. data/lib/sisimai/message.rb +11 -13
  55. data/lib/sisimai/order.rb +12 -11
  56. data/lib/sisimai/reason/authfailure.rb +10 -10
  57. data/lib/sisimai/reason/badreputation.rb +4 -6
  58. data/lib/sisimai/reason/blocked.rb +6 -8
  59. data/lib/sisimai/reason/contenterror.rb +5 -6
  60. data/lib/sisimai/reason/delivered.rb +2 -2
  61. data/lib/sisimai/reason/exceedlimit.rb +7 -8
  62. data/lib/sisimai/reason/expired.rb +6 -7
  63. data/lib/sisimai/reason/failedstarttls.rb +5 -7
  64. data/lib/sisimai/reason/feedback.rb +2 -2
  65. data/lib/sisimai/reason/filtered.rb +7 -10
  66. data/lib/sisimai/reason/hasmoved.rb +4 -5
  67. data/lib/sisimai/reason/hostunknown.rb +6 -7
  68. data/lib/sisimai/reason/mailboxfull.rb +7 -8
  69. data/lib/sisimai/reason/mailererror.rb +5 -8
  70. data/lib/sisimai/reason/mesgtoobig.rb +5 -6
  71. data/lib/sisimai/reason/networkerror.rb +5 -8
  72. data/lib/sisimai/reason/norelaying.rb +4 -5
  73. data/lib/sisimai/reason/notaccept.rb +5 -8
  74. data/lib/sisimai/reason/notcompliantrfc.rb +5 -6
  75. data/lib/sisimai/reason/onhold.rb +6 -9
  76. data/lib/sisimai/reason/policyviolation.rb +6 -9
  77. data/lib/sisimai/reason/rejected.rb +5 -6
  78. data/lib/sisimai/reason/requireptr.rb +6 -7
  79. data/lib/sisimai/reason/securityerror.rb +6 -9
  80. data/lib/sisimai/reason/spamdetected.rb +8 -9
  81. data/lib/sisimai/reason/speeding.rb +6 -7
  82. data/lib/sisimai/reason/suppressed.rb +3 -7
  83. data/lib/sisimai/reason/suspend.rb +5 -7
  84. data/lib/sisimai/reason/syntaxerror.rb +3 -5
  85. data/lib/sisimai/reason/systemerror.rb +6 -9
  86. data/lib/sisimai/reason/systemfull.rb +5 -8
  87. data/lib/sisimai/reason/toomanyconn.rb +5 -6
  88. data/lib/sisimai/reason/undefined.rb +2 -2
  89. data/lib/sisimai/reason/userunknown.rb +8 -9
  90. data/lib/sisimai/reason/vacation.rb +4 -5
  91. data/lib/sisimai/reason/virusdetected.rb +4 -5
  92. data/lib/sisimai/reason.rb +13 -13
  93. data/lib/sisimai/rfc1123.rb +4 -8
  94. data/lib/sisimai/rfc1894.rb +5 -6
  95. data/lib/sisimai/rfc2045.rb +27 -31
  96. data/lib/sisimai/rfc3464/thirdparty.rb +1 -1
  97. data/lib/sisimai/rfc3464.rb +7 -9
  98. data/lib/sisimai/rfc3834.rb +5 -9
  99. data/lib/sisimai/rfc5322.rb +8 -26
  100. data/lib/sisimai/rfc791.rb +6 -4
  101. data/lib/sisimai/rhost/google.rb +8 -0
  102. data/lib/sisimai/rhost/microsoft.rb +17 -5
  103. data/lib/sisimai/rhost.rb +2 -2
  104. data/lib/sisimai/smtp/command.rb +1 -1
  105. data/lib/sisimai/smtp/failure.rb +5 -12
  106. data/lib/sisimai/smtp/reply.rb +33 -12
  107. data/lib/sisimai/smtp/status.rb +21 -22
  108. data/lib/sisimai/smtp/transcript.rb +1 -10
  109. data/lib/sisimai/string.rb +20 -30
  110. data/lib/sisimai/version.rb +1 -1
  111. data/lib/sisimai.rb +11 -11
  112. data/set-of-emails/maildir/bsd/rhost-microsoft-06.eml +45 -0
  113. 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 = { 'diagnosis' => false, 'command' => false }
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
112
+ return {"ds" => dscontents, "rfc822" => emailparts[1]}
115
113
  end
116
114
  def description; return 'Digital Arts m-FILTER'; end
117
115
  end
@@ -7,7 +7,7 @@ module Sisimai::Lhost
7
7
 
8
8
  Indicators = Sisimai::Lhost.INDICATORS
9
9
  Boundaries = ['------- Returned Message --------'].freeze
10
- StartingOf = { message: ['------- Failure Reasons '] }.freeze
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'] << encodedmsg
84
+ v['diagnosis'] += encodedmsg
87
85
  else
88
86
  # Error message does not include multi-byte character
89
- v['diagnosis'] << e
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
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'] << ' ' << Sisimai::String.sweep(e)
157
- readslices[-1] = 'Diagnostic-Code: ' << e
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] << 'X-Postfix-Sender: ' << Sisimai::Address.s3s4(e[e.index(';') + 1, e.size]) << "\n"
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'] << ' ' << e
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'] << ' ' << e[4, e.size]
198
+ anotherset['diagnosis'] += " #{e[4, e.size]}"
202
199
  end
203
200
  end
204
201
  end
@@ -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 RelayedVia.any? { |a| Sisimai::String.aligned(e, a) }
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"] << e + " "
183
- v["alterrors"] = e if e.start_with?(StartingOf["error"][0])
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'] << ' ' << e
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'] << ' ' << e
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'] << ' ' << Sisimai::String.sweep(e)
165
- readslices[-1] = 'Diagnostic-Code: ' << e
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
- curcommand = "" # The last SMTP command
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] << " " << e
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"] << " " << e
94
- v["replycode"] = Sisimai::SMTP::Reply.find(e)
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 += 1
105
- v["recipient"] = cv
106
- v["rhost"] = remotehost
107
- v["replycode"] = Sisimai::SMTP::Reply.find(e)
108
- v["diagnosis"] << " " << e
109
- v["command"] = curcommand if v["command"].empty?
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"] << " " << e
123
+ v["diagnosis"] += " #{e}"
126
124
  else
127
125
  # 421 Other error message
128
- anotherone[recipients] ||= ""; anotherone[recipients] << " " << e
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 = { message: ['Error: '] }
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 = { message: ['Message could not be delivered to mobile'] }
92
- messagesof = { 'userunknown' => ['No valid recipients for this MM'] }
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] << ('From: ' << senderaddr << "\n") if emailparts[1].include?("\nFrom: ") == false
142
- emailparts[1] << ('Subject: ' << subjecttxt << "\n") if emailparts[1].include?("\nSubject: ") == false
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
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
@@ -7,7 +7,7 @@ module Sisimai::Lhost
7
7
 
8
8
  Indicators = Sisimai::Lhost.INDICATORS
9
9
  Boundaries = ['Received: from '].freeze
10
- MarkingsOf = { message: ['The original message was received at '] }.freeze
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
71
+ return {"ds" => dscontents, "rfc822" => emailparts[1]}
74
72
  end
75
73
  def description; return 'Unknown MTA #1'; end
76
74
  end
@@ -7,7 +7,7 @@ module Sisimai::Lhost
7
7
 
8
8
  Indicators = Sisimai::Lhost.INDICATORS
9
9
  Boundaries = ['--- Original message follows.'].freeze
10
- StartingOf = { message: ['Unable to deliver message to the following address'] }.freeze
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'] << ' ' << e
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
65
+ return {"ds" => dscontents, "rfc822" => emailparts[1]}
68
66
  end
69
67
  def description; return 'Unknown MTA #2'; end
70
68
  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: [' This is an automatically generated Delivery Status Notification.'] }.freeze
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
89
+ return {"ds" => dscontents, "rfc822" => emailparts[1]}
91
90
  end
92
91
  def description; return 'Unknown MTA #3'; end
93
92
  end
@@ -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 = { message: ['We had trouble delivering your message. Full details follow:'] }.freeze
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 { 'ds' => dscontents, 'rfc822' => emailparts[1] }
90
+ return {"ds" => dscontents, "rfc822" => emailparts[1]}
93
91
  end
94
92
  def description; return 'Unknown MTA #6'; end
95
93
  end