sisimai 5.0.2 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codecovio.yml +35 -0
  3. data/.github/workflows/rake-test.yml +27 -24
  4. data/ChangeLog.md +62 -0
  5. data/Gemfile +2 -0
  6. data/README-JA.md +21 -18
  7. data/README.md +23 -20
  8. data/lib/sisimai/arf.rb +27 -8
  9. data/lib/sisimai/fact/json.rb +2 -2
  10. data/lib/sisimai/fact/yaml.rb +2 -2
  11. data/lib/sisimai/fact.rb +4 -19
  12. data/lib/sisimai/lhost/activehunter.rb +4 -3
  13. data/lib/sisimai/lhost/amavis.rb +4 -4
  14. data/lib/sisimai/lhost/amazonses.rb +6 -6
  15. data/lib/sisimai/lhost/amazonworkmail.rb +4 -4
  16. data/lib/sisimai/lhost/aol.rb +4 -4
  17. data/lib/sisimai/lhost/apachejames.rb +4 -4
  18. data/lib/sisimai/lhost/barracuda.rb +4 -4
  19. data/lib/sisimai/lhost/bigfoot.rb +4 -4
  20. data/lib/sisimai/lhost/biglobe.rb +4 -4
  21. data/lib/sisimai/lhost/courier.rb +4 -4
  22. data/lib/sisimai/lhost/domino.rb +4 -4
  23. data/lib/sisimai/lhost/dragonfly.rb +114 -0
  24. data/lib/sisimai/lhost/einsundeins.rb +4 -4
  25. data/lib/sisimai/lhost/exchange2003.rb +4 -3
  26. data/lib/sisimai/lhost/exchange2007.rb +4 -3
  27. data/lib/sisimai/lhost/exim.rb +4 -4
  28. data/lib/sisimai/lhost/ezweb.rb +4 -4
  29. data/lib/sisimai/lhost/facebook.rb +4 -4
  30. data/lib/sisimai/lhost/fml.rb +4 -4
  31. data/lib/sisimai/lhost/gmail.rb +4 -4
  32. data/lib/sisimai/lhost/gmx.rb +4 -4
  33. data/lib/sisimai/lhost/googlegroups.rb +4 -4
  34. data/lib/sisimai/lhost/gsuite.rb +4 -4
  35. data/lib/sisimai/lhost/imailserver.rb +4 -3
  36. data/lib/sisimai/lhost/interscanmss.rb +5 -4
  37. data/lib/sisimai/lhost/kddi.rb +4 -4
  38. data/lib/sisimai/lhost/mailfoundry.rb +4 -4
  39. data/lib/sisimai/lhost/mailmarshalsmtp.rb +6 -5
  40. data/lib/sisimai/lhost/mailru.rb +4 -4
  41. data/lib/sisimai/lhost/mcafee.rb +4 -4
  42. data/lib/sisimai/lhost/messagelabs.rb +4 -3
  43. data/lib/sisimai/lhost/messagingserver.rb +5 -4
  44. data/lib/sisimai/lhost/mfilter.rb +4 -4
  45. data/lib/sisimai/lhost/mxlogic.rb +3 -3
  46. data/lib/sisimai/lhost/notes.rb +4 -4
  47. data/lib/sisimai/lhost/office365.rb +4 -4
  48. data/lib/sisimai/lhost/opensmtpd.rb +9 -7
  49. data/lib/sisimai/lhost/outlook.rb +4 -4
  50. data/lib/sisimai/lhost/postfix.rb +4 -4
  51. data/lib/sisimai/lhost/powermta.rb +4 -4
  52. data/lib/sisimai/lhost/qmail.rb +10 -10
  53. data/lib/sisimai/lhost/receivingses.rb +4 -4
  54. data/lib/sisimai/lhost/sendgrid.rb +4 -4
  55. data/lib/sisimai/lhost/sendmail.rb +4 -4
  56. data/lib/sisimai/lhost/surfcontrol.rb +4 -4
  57. data/lib/sisimai/lhost/v5sendmail.rb +5 -4
  58. data/lib/sisimai/lhost/verizon.rb +4 -4
  59. data/lib/sisimai/lhost/x1.rb +3 -3
  60. data/lib/sisimai/lhost/x2.rb +3 -3
  61. data/lib/sisimai/lhost/x3.rb +3 -3
  62. data/lib/sisimai/lhost/x4.rb +3 -3
  63. data/lib/sisimai/lhost/x5.rb +3 -3
  64. data/lib/sisimai/lhost/x6.rb +3 -3
  65. data/lib/sisimai/lhost/yahoo.rb +4 -4
  66. data/lib/sisimai/lhost/yandex.rb +4 -4
  67. data/lib/sisimai/lhost/zoho.rb +4 -4
  68. data/lib/sisimai/lhost.rb +5 -5
  69. data/lib/sisimai/mail/maildir.rb +1 -1
  70. data/lib/sisimai/mail/stdin.rb +1 -1
  71. data/lib/sisimai/mda.rb +3 -3
  72. data/lib/sisimai/message.rb +9 -9
  73. data/lib/sisimai/order.rb +1 -0
  74. data/lib/sisimai/reason/badreputation.rb +1 -1
  75. data/lib/sisimai/reason/blocked.rb +1 -0
  76. data/lib/sisimai/reason/expired.rb +7 -0
  77. data/lib/sisimai/reason/filtered.rb +1 -0
  78. data/lib/sisimai/reason/mailboxfull.rb +3 -0
  79. data/lib/sisimai/reason/norelaying.rb +2 -0
  80. data/lib/sisimai/reason/rejected.rb +2 -1
  81. data/lib/sisimai/reason/suspend.rb +4 -0
  82. data/lib/sisimai/reason/userunknown.rb +4 -1
  83. data/lib/sisimai/reason.rb +8 -8
  84. data/lib/sisimai/rfc3464.rb +3 -3
  85. data/lib/sisimai/rfc3834.rb +2 -2
  86. data/lib/sisimai/rhost/apple.rb +92 -0
  87. data/lib/sisimai/rhost/cox.rb +81 -32
  88. data/lib/sisimai/rhost/franceptt.rb +84 -81
  89. data/lib/sisimai/rhost/godaddy.rb +205 -43
  90. data/lib/sisimai/rhost/google.rb +85 -72
  91. data/lib/sisimai/rhost/iua.rb +2 -2
  92. data/lib/sisimai/rhost/kddi.rb +6 -5
  93. data/lib/sisimai/rhost/microsoft.rb +12 -5
  94. data/lib/sisimai/rhost/mimecast.rb +15 -4
  95. data/lib/sisimai/rhost/nttdocomo.rb +4 -4
  96. data/lib/sisimai/rhost/spectrum.rb +100 -40
  97. data/lib/sisimai/rhost/tencent.rb +46 -25
  98. data/lib/sisimai/rhost/yahooinc.rb +110 -0
  99. data/lib/sisimai/rhost.rb +28 -35
  100. data/lib/sisimai/smtp/reply.rb +4 -3
  101. data/lib/sisimai/smtp/transcript.rb +3 -3
  102. data/lib/sisimai/version.rb +1 -1
  103. data/lib/sisimai.rb +0 -6
  104. data/set-of-emails/maildir/bsd/arf-26.eml +27 -0
  105. data/set-of-emails/maildir/bsd/lhost-dragonfly-01.eml +36 -0
  106. data/set-of-emails/maildir/bsd/lhost-dragonfly-02.eml +32 -0
  107. data/set-of-emails/maildir/bsd/lhost-dragonfly-03.eml +32 -0
  108. data/set-of-emails/maildir/bsd/lhost-dragonfly-04.eml +31 -0
  109. data/set-of-emails/maildir/bsd/lhost-dragonfly-05.eml +32 -0
  110. data/set-of-emails/maildir/bsd/lhost-dragonfly-06.eml +32 -0
  111. data/set-of-emails/maildir/bsd/lhost-dragonfly-07.eml +32 -0
  112. data/set-of-emails/maildir/bsd/lhost-dragonfly-08.eml +32 -0
  113. data/set-of-emails/maildir/bsd/lhost-dragonfly-09.eml +32 -0
  114. data/set-of-emails/maildir/bsd/lhost-dragonfly-10.eml +32 -0
  115. data/set-of-emails/maildir/bsd/lhost-dragonfly-11.eml +32 -0
  116. data/set-of-emails/maildir/bsd/lhost-dragonfly-12.eml +32 -0
  117. data/set-of-emails/maildir/bsd/lhost-dragonfly-13.eml +32 -0
  118. data/set-of-emails/maildir/bsd/lhost-dragonfly-14.eml +32 -0
  119. data/set-of-emails/maildir/bsd/lhost-dragonfly-15.eml +32 -0
  120. data/set-of-emails/maildir/bsd/lhost-dragonfly-16.eml +32 -0
  121. data/set-of-emails/maildir/bsd/lhost-dragonfly-17.eml +32 -0
  122. data/set-of-emails/maildir/bsd/lhost-dragonfly-18.eml +32 -0
  123. data/set-of-emails/maildir/bsd/lhost-dragonfly-19.eml +32 -0
  124. data/set-of-emails/maildir/bsd/lhost-dragonfly-20.eml +32 -0
  125. data/set-of-emails/maildir/bsd/lhost-dragonfly-21.eml +33 -0
  126. data/set-of-emails/maildir/bsd/lhost-dragonfly-22.eml +32 -0
  127. data/set-of-emails/maildir/bsd/lhost-dragonfly-23.eml +32 -0
  128. data/set-of-emails/maildir/bsd/lhost-dragonfly-24.eml +32 -0
  129. data/set-of-emails/maildir/bsd/lhost-dragonfly-25.eml +33 -0
  130. data/set-of-emails/maildir/bsd/lhost-dragonfly-26.eml +33 -0
  131. data/set-of-emails/maildir/bsd/lhost-dragonfly-27.eml +47 -0
  132. data/set-of-emails/maildir/bsd/lhost-dragonfly-28.eml +47 -0
  133. data/set-of-emails/maildir/bsd/lhost-dragonfly-29.eml +32 -0
  134. data/set-of-emails/maildir/bsd/lhost-dragonfly-30.eml +32 -0
  135. data/set-of-emails/maildir/bsd/lhost-opensmtpd-10.eml +58 -0
  136. data/set-of-emails/maildir/bsd/lhost-opensmtpd-11.eml +58 -0
  137. data/set-of-emails/maildir/bsd/lhost-opensmtpd-12.eml +62 -0
  138. data/set-of-emails/maildir/bsd/lhost-opensmtpd-13.eml +62 -0
  139. data/set-of-emails/maildir/bsd/lhost-opensmtpd-14.eml +58 -0
  140. data/set-of-emails/maildir/bsd/lhost-opensmtpd-15.eml +63 -0
  141. data/set-of-emails/maildir/bsd/lhost-opensmtpd-16.eml +62 -0
  142. data/set-of-emails/maildir/bsd/lhost-opensmtpd-17.eml +63 -0
  143. data/set-of-emails/maildir/bsd/lhost-qmail-11.eml +29 -0
  144. data/set-of-emails/maildir/bsd/lhost-qmail-12.eml +29 -0
  145. data/set-of-emails/maildir/bsd/lhost-qmail-13.eml +29 -0
  146. data/set-of-emails/maildir/bsd/lhost-qmail-14.eml +34 -0
  147. data/set-of-emails/maildir/bsd/lhost-qmail-15.eml +30 -0
  148. data/set-of-emails/maildir/bsd/lhost-qmail-16.eml +31 -0
  149. data/set-of-emails/maildir/bsd/lhost-qmail-17.eml +38 -0
  150. data/set-of-emails/maildir/bsd/lhost-qmail-18.eml +31 -0
  151. data/set-of-emails/maildir/bsd/lhost-qmail-19.eml +31 -0
  152. data/set-of-emails/maildir/bsd/lhost-qmail-20.eml +46 -0
  153. data/set-of-emails/maildir/bsd/lhost-qmail-21.eml +41 -0
  154. data/set-of-emails/maildir/bsd/lhost-qmail-22.eml +42 -0
  155. data/set-of-emails/maildir/bsd/lhost-qmail-23.eml +43 -0
  156. data/set-of-emails/maildir/bsd/lhost-qmail-24.eml +43 -0
  157. data/set-of-emails/maildir/bsd/lhost-qmail-25.eml +54 -0
  158. data/set-of-emails/maildir/bsd/rhost-apple-01.eml +79 -0
  159. data/set-of-emails/maildir/bsd/rhost-apple-02.eml +81 -0
  160. data/set-of-emails/maildir/bsd/rhost-apple-03.eml +75 -0
  161. data/set-of-emails/maildir/bsd/rhost-apple-04.eml +74 -0
  162. data/set-of-emails/maildir/bsd/rhost-microsoft-04.eml +86 -0
  163. data/set-of-emails/maildir/bsd/rhost-microsoft-05.eml +83 -0
  164. data/set-of-emails/maildir/bsd/rhost-yahooinc-01.eml +80 -0
  165. data/set-of-emails/maildir/bsd/rhost-yahooinc-02.eml +83 -0
  166. data/set-of-emails/maildir/bsd/rhost-yahooinc-03.eml +125 -0
  167. metadata +69 -3
  168. data/.travis.yml +0 -23
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Aol parses a bounce email which created by Aol Mail. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Aol decodes a bounce email which created by Aol Mail https://mail.aol.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Aol
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -13,11 +13,11 @@ module Sisimai::Lhost
13
13
  'notaccept' => ['type=MX: Malformed or unexpected name server reply'],
14
14
  }.freeze
15
15
 
16
- # Parse bounce messages from Aol Mail
16
+ # @abstract Decodes the bounce message from Aol Mail
17
17
  # @param [Hash] mhead Message headers of a bounce email
18
18
  # @param [String] mbody Message body of a bounce email
19
19
  # @return [Hash] Bounce data list and message/rfc822 part
20
- # @return [Nil] it failed to parse or the arguments are missing
20
+ # @return [Nil] it failed to decode or the arguments are missing
21
21
  def inquire(mhead, mbody)
22
22
  # X-AOL-IP: 192.0.2.135
23
23
  # X-AOL-VSS-INFO: 5600.1067/98281
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::ApacheJames parses a bounce email which created by ApacheJames. Methods in the
3
- # module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::ApacheJames decodes a bounce email which created by ApacheJames https://james.apache.org/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module ApacheJames
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -15,11 +15,11 @@ module Sisimai::Lhost
15
15
  error: ['Error message below:'],
16
16
  }.freeze
17
17
 
18
- # Parse bounce messages from Apache James
18
+ # @abstract decodes the bounce message from Apache James
19
19
  # @param [Hash] mhead Message headers of a bounce email
20
20
  # @param [String] mbody Message body of a bounce email
21
21
  # @return [Hash] Bounce data list and message/rfc822 part
22
- # @return [Nil] it failed to parse or the arguments are missing
22
+ # @return [Nil] it failed to decode or the arguments are missing
23
23
  def inquire(mhead, mbody)
24
24
  match = 0
25
25
  match += 1 if mhead['subject'] == '[BOUNCE]'
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Barracuda parses a bounce email which created by Barracuda. Methods in the module
3
- # are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Barracuda decodes a bounce email which created by Barracuda https://www.barracuda.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Barracuda
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['Content-Type: text/rfc822-headers'].freeze
10
10
  StartingOf = { message: ['Your message to:'] }.freeze
11
11
 
12
- # Parse bounce messages from Barracuda
12
+ # @abstract Decodes the bounce message from Barracuda
13
13
  # @param [Hash] mhead Message headers of a bounce email
14
14
  # @param [String] mbody Message body of a bounce email
15
15
  # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
16
+ # @return [Nil] it failed to decode or the arguments are missing
17
17
  # @since v4.25.6
18
18
  def inquire(mhead, mbody)
19
19
  # Subject: **Message you sent blocked by our bulk email filter**
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Bigfoot parses a bounce email which created by Bigfoot. Methods in the module
3
- # are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Bigfoot decodes a bounce email which created by Bigfoot https://www.bigfoot.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Bigfoot
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['Content-Type: message/partial'].freeze
10
10
  MarkingsOf = { message: ' ----- Transcript of session follows -----' }.freeze
11
11
 
12
- # Parse bounce messages from Bigfoot
12
+ # @abstract Decodes the bounce message from Bigfoot
13
13
  # @param [Hash] mhead Message headers of a bounce email
14
14
  # @param [String] mbody Message body of a bounce email
15
15
  # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
16
+ # @return [Nil] it failed to decode or the arguments are missing
17
17
  def inquire(mhead, mbody)
18
18
  # :subject => %r/\AReturned mail: /,
19
19
  match = 0
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Biglobe parses a bounce email which created by BIGLOBE. Methods in the module
3
- # are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Biglobe decodes a bounce email which created by BIGLOBE https://www.biglobe.ne.jp/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Biglobe
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -16,11 +16,11 @@ module Sisimai::Lhost
16
16
  'mailboxfull' => ["The number of messages in recipient's mailbox exceeded the local limit."],
17
17
  }.freeze
18
18
 
19
- # Parse bounce messages from Biglobe
19
+ # @asbtract Decodes the bounce message from Biglobe
20
20
  # @param [Hash] mhead Message headers of a bounce email
21
21
  # @param [String] mbody Message body of a bounce email
22
22
  # @return [Hash] Bounce data list and message/rfc822 part
23
- # @return [Nil] it failed to parse or the arguments are missing
23
+ # @return [Nil] it failed to decode or the arguments are missing
24
24
  def inquire(mhead, mbody)
25
25
  return nil unless mhead['from'].include?('postmaster@')
26
26
  return nil unless %w[biglobe inacatv tmtv ttv].any? { |a| mhead['from'].include?('@' + a + '.ne.jp') }
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Courier parses a bounce email which created by Courier MTA. Methods in the module
3
- # are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Courier decodes a bounce email which created by Courier MTA https://www.courier-mta.org/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Courier
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -23,11 +23,11 @@ module Sisimai::Lhost
23
23
  'networkerror' => ['DNS lookup failed.'],
24
24
  }.freeze
25
25
 
26
- # Parse bounce messages from Courier MTA
26
+ # @abstract Decodes the bounce message from Courier MTA
27
27
  # @param [Hash] mhead Message headers of a bounce email
28
28
  # @param [String] mbody Message body of a bounce email
29
29
  # @return [Hash] Bounce data list and message/rfc822 part
30
- # @return [Nil] it failed to parse or the arguments are missing
30
+ # @return [Nil] it failed to decode or the arguments are missing
31
31
  def inquire(mhead, mbody)
32
32
  match = 0
33
33
  match += 1 if mhead['from'].include?('Courier mail server at ')
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Domino parses a bounce email which created by IBM Domino Server. Methods in the
3
- # module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Domino decodes a bounce email which created by HCL Domino https://www.hcl-software.com/domino.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Domino
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -20,11 +20,11 @@ module Sisimai::Lhost
20
20
  'systemerror' => ['Several matches found in Domino Directory'],
21
21
  }.freeze
22
22
 
23
- # Parse bounce messages from IBM Domino Server
23
+ # @abstract Decodes the bounce message from HCL Domino (formerly IBM Domino Server (formerly Lotus Domino))
24
24
  # @param [Hash] mhead Message headers of a bounce email
25
25
  # @param [String] mbody Message body of a bounce email
26
26
  # @return [Hash] Bounce data list and message/rfc822 part
27
- # @return [Nil] it failed to parse or the arguments are missing
27
+ # @return [Nil] it failed to decode or the arguments are missing
28
28
  def inquire(mhead, mbody)
29
29
  return nil unless mhead['subject'].start_with?('DELIVERY FAILURE:', 'DELIVERY_FAILURE:')
30
30
 
@@ -0,0 +1,114 @@
1
+ module Sisimai::Lhost
2
+ # Sisimai::Lhost::DragonFly decodes a bounce email which created by DMA: DragonFly Mail Agent
3
+ # https://www.dragonflybsd.org/handbook/mta/.
4
+ # Methods in the module are called from only Sisimai::Message.
5
+ module DragonFly
6
+ class << self
7
+ require 'sisimai/lhost'
8
+ require 'sisimai/address'
9
+ require 'sisimai/smtp/command'
10
+
11
+ Indicators = Sisimai::Lhost.INDICATORS
12
+ Boundaries = ['Original message follows.', 'Message headers follow'].freeze
13
+ StartingOf = {
14
+ # https://github.com/corecode/dma/blob/ffad280aa40c242aa9a2cb9ca5b1b6e8efedd17e/mail.c#L84
15
+ message: ['This is the DragonFly Mail Agent '],
16
+ }.freeze
17
+ MessagesOf = {
18
+ 'expired' => [
19
+ # https://github.com/corecode/dma/blob/master/dma.c#L370C1-L374C19
20
+ # dma.c:370| if (gettimeofday(&now, NULL) == 0 &&
21
+ # dma.c:371| (now.tv_sec - st.st_mtim.tv_sec > MAX_TIMEOUT)) {
22
+ # dma.c:372| snprintf(errmsg, sizeof(errmsg),
23
+ # dma.c:373| "Could not deliver for the last %d seconds. Giving up.",
24
+ # dma.c:374| MAX_TIMEOUT);
25
+ # dma.c:375| goto bounce;
26
+ # dma.c:376| }
27
+ 'Could not deliver for the last ',
28
+ ],
29
+ 'hostunknown' => [
30
+ # net.c:663| snprintf(errmsg, sizeof(errmsg), "DNS lookup failure: host %s not found", host);
31
+ 'DNS lookup failure: host ',
32
+ ],
33
+ }.freeze
34
+
35
+ # @abstract Decodes the bounce message from DMA: DragonFly Mail Agent
36
+ # @param [Hash] mhead Message headers of a bounce email
37
+ # @param [String] mbody Message body of a bounce email
38
+ # @return [Hash] Bounce data list and message/rfc822 part
39
+ # @return [Nil] it failed to decode or the arguments are missing
40
+ def inquire(mhead, mbody)
41
+ return nil unless mhead['subject'].start_with?('Mail delivery failed')
42
+ return nil unless mhead['received'].any? { |a| a.include?(' (DragonFly Mail Agent') }
43
+
44
+ dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
45
+ emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
46
+ bodyslices = emailparts[0].split("\n")
47
+ readcursor = 0 # (Integer) Points the current cursor position
48
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
49
+ v = nil
50
+
51
+ while e = bodyslices.shift do
52
+ # Read error messages and delivery status lines from the head of the email to the previous
53
+ # line of the beginning of the original message.
54
+ if readcursor == 0
55
+ # Beginning of the bounce message or delivery status part
56
+ readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
57
+ next
58
+ end
59
+ next if (readcursor & Indicators[:deliverystatus]) == 0
60
+ next if e.empty?
61
+
62
+ # This is the DragonFly Mail Agent v0.13 at df.example.jp.
63
+ #
64
+ # There was an error delivering your mail to <kijitora@example.com>.
65
+ #
66
+ # email.example.jp [192.0.2.25] did not like our RCPT TO:
67
+ # 552 5.2.2 <kijitora@example.com>: Recipient address rejected: Mailbox full
68
+ #
69
+ # Original message follows.
70
+ v = dscontents[-1]
71
+
72
+ if e.start_with?('There was an error delivering your mail to <')
73
+ # email.example.jp [192.0.2.25] did not like our RCPT TO:
74
+ # 552 5.2.2 <kijitora@example.com>: Recipient address rejected: Mailbox full
75
+ if v['recipient']
76
+ # There are multiple recipient addresses in the message body.
77
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
78
+ v = dscontents[-1]
79
+ end
80
+ v['recipient'] = Sisimai::Address.find(e, false)[0][:address]
81
+ recipients += 1
82
+ else
83
+ # Pick the error message
84
+ v['diagnosis'] ||= ''
85
+ v['diagnosis'] << ' ' << e
86
+
87
+ # Pick the remote hostname, and the SMTP command
88
+ # net.c:500| snprintf(errmsg, sizeof(errmsg), "%s [%s] did not like our %s:\n%s",
89
+ next unless e.include?(' did not like our ')
90
+ next if v['rhost']
91
+
92
+ p = e.split(' ', 3)
93
+ v['rhost'] = if p[0].include?('.') then p[0] else p[1] end
94
+ v['command'] = Sisimai::SMTP::Command.find(e) || ''
95
+ end
96
+ end
97
+ return nil unless recipients > 0
98
+
99
+ dscontents.each do |e|
100
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
101
+ MessagesOf.each_key do |r|
102
+ # Verify each regular expression of session errors
103
+ next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
104
+ e['reason'] = r
105
+ break
106
+ end
107
+ end
108
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
109
+ end
110
+ def description; return 'DragonFly'; end
111
+ end
112
+ end
113
+ end
114
+
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::EinsUndEins parses a bounce email which created by 1&1. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::EinsUndEins decodes a bounce email which created by 1&1 https://www.1und1.de/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module EinsUndEins
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -13,11 +13,11 @@ module Sisimai::Lhost
13
13
  }.freeze
14
14
  MessagesOf = { 'mesgtoobig' => ['Mail size limit exceeded'] }.freeze
15
15
 
16
- # Parse bounce messages from 1&1
16
+ # @abstract Decode the bounce message from 1&1
17
17
  # @param [Hash] mhead Message headers of a bounce email
18
18
  # @param [String] mbody Message body of a bounce email
19
19
  # @return [Hash] Bounce data list and message/rfc822 part
20
- # @return [Nil] it failed to parse or the arguments are missing
20
+ # @return [Nil] it failed to decode or the arguments are missing
21
21
  def inquire(mhead, mbody)
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'
@@ -1,5 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Exchange2003 parses a bounce email which created by Microsoft Exchange Server 2003.
2
+ # Sisimai::Lhost::Exchange2003 decodes a bounce email which created by Microsoft Exchange Server
3
+ # 2003 https://www.microsoft.com/microsoft-365/exchange/email.
3
4
  # Methods in the module are called from only Sisimai::Message.
4
5
  module Exchange2003
5
6
  class << self
@@ -39,11 +40,11 @@ module Sisimai::Lhost
39
40
  ],
40
41
  }.freeze
41
42
 
42
- # Parse bounce messages from Microsoft Exchange Server 2003
43
+ # @abstract Decodes the bounce message from Microsoft Exchange Server 2003
43
44
  # @param [Hash] mhead Message headers of a bounce email
44
45
  # @param [String] mbody Message body of a bounce email
45
46
  # @return [Hash] Bounce data list and message/rfc822 part
46
- # @return [Nil] it failed to parse or the arguments are missing
47
+ # @return [Nil] it failed to decode or the arguments are missing
47
48
  def inquire(mhead, mbody)
48
49
  match = 0
49
50
  tryto = []
@@ -1,5 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Exchange2007 parses a bounce email which created by Microsoft Exchange Server 2007.
2
+ # Sisimai::Lhost::Exchange2007 decodes a bounce email which created by Microsoft Exchange Server
3
+ # 2007 https://www.microsoft.com/microsoft-365/exchange/email.
3
4
  # Methods in the module are called from only Sisimai::Message.
4
5
  module Exchange2007
5
6
  class << self
@@ -39,11 +40,11 @@ module Sisimai::Lhost
39
40
  'QUEUE.Expired' => 'expired', # 550 4.4.7 QUEUE.Expired
40
41
  }.freeze
41
42
 
42
- # Parse bounce messages from Microsoft Exchange Server 2007
43
+ # @abstract Decodes the bounce message from Microsoft Exchange Server 2007
43
44
  # @param [Hash] mhead Message headers of a bounce email
44
45
  # @param [String] mbody Message body of a bounce email
45
46
  # @return [Hash] Bounce data list and message/rfc822 part
46
- # @return [Nil] it failed to parse or the arguments are missing
47
+ # @return [Nil] it failed to decode or the arguments are missing
47
48
  def inquire(mhead, mbody)
48
49
  # Content-Language: en-US, fr-FR
49
50
  match = nil
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Exim parses a bounce email which created by Exim. Methods in the module are called
3
- # from only Sisimai::Message.
2
+ # Sisimai::Lhost::Exim decodes a bounce email which created by Exim Internet Mailer https://www.exim.org/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Exim
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -117,11 +117,11 @@ module Sisimai::Lhost
117
117
  'was frozen on arrival by ',
118
118
  ].freeze
119
119
 
120
- # Parse bounce messages from Exim
120
+ # @abstract Decodes the bounce message from Exim
121
121
  # @param [Hash] mhead Message headers of a bounce email
122
122
  # @param [String] mbody Message body of a bounce email
123
123
  # @return [Hash] Bounce data list and message/rfc822 part
124
- # @return [Nil] it failed to parse or the arguments are missing
124
+ # @return [Nil] it failed to decode or the arguments are missing
125
125
  def inquire(mhead, mbody)
126
126
  return nil if mhead['from'].include?('.mail.ru')
127
127
 
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::EZweb parses a bounce email which created by au EZweb. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::EZweb decodes a bounce email which created by au EZweb https://www.au.com/mobile/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module EZweb
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -25,11 +25,11 @@ module Sisimai::Lhost
25
25
  'onhold' => ['Each of the following recipients was rejected by a remote mail server'],
26
26
  }.freeze
27
27
 
28
- # Parse bounce messages from au EZweb
28
+ # @abstract Decodes the bounce message from au EZweb
29
29
  # @param [Hash] mhead Message headers of a bounce email
30
30
  # @param [String] mbody Message body of a bounce email
31
31
  # @return [Hash] Bounce data list and message/rfc822 part
32
- # @return [Nil] it failed to parse or the arguments are missing
32
+ # @return [Nil] it failed to decode or the arguments are missing
33
33
  def inquire(mhead, mbody)
34
34
  match = 0
35
35
  match += 1 if mhead['from'].include?('Postmaster@ezweb.ne.jp')
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Facebook parses a bounce email which created by Facebook. Methods in the module
3
- # are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Facebook decodes a bounce email which created by Facebook https://www.facebook.com.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Facebook
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -68,11 +68,11 @@ module Sisimai::Lhost
68
68
  ],
69
69
  }.freeze
70
70
 
71
- # Parse bounce messages from Facebook
71
+ # @abstract Decodes the bounce message from Facebook
72
72
  # @param [Hash] mhead Message headers of a bounce email
73
73
  # @param [String] mbody Message body of a bounce email
74
74
  # @return [Hash] Bounce data list and message/rfc822 part
75
- # @return [Nil] it failed to parse or the arguments are missing
75
+ # @return [Nil] it failed to decode or the arguments are missing
76
76
  def inquire(mhead, mbody)
77
77
  return nil unless mhead['from'] == 'Facebook <mailer-daemon@mx.facebook.com>'
78
78
  return nil unless mhead['subject'] == 'Sorry, your message could not be delivered'
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::FML parses a bounce email which created by fml. Methods in the module are called
3
- # from only Sisimai::Message.
2
+ # Sisimai::Lhost::FML decodes a bounce email which created by fml mailing list server/manager
3
+ # https://www.fml.org/. Methods in the module are called from only Sisimai::Message.
4
4
  module FML
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -38,11 +38,11 @@ module Sisimai::Lhost
38
38
  'securityerror' => ['Security alert:'],
39
39
  }.freeze
40
40
 
41
- # Parse bounce messages from fml mailling list server/manager
41
+ # @abstract Decodes the bounce message from fml mailling list server/manager
42
42
  # @param [Hash] mhead Message headers of a bounce email
43
43
  # @param [String] mbody Message body of a bounce email
44
44
  # @return [Hash] Bounce data list and message/rfc822 part
45
- # @return [Nil] it failed to parse or the arguments are missing
45
+ # @return [Nil] it failed to decode or the arguments are missing
46
46
  # @since v4.22.3
47
47
  def inquire(mhead, mbody)
48
48
  return nil unless mhead['x-mlserver']
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Gmail parses a bounce email which created by Gmail. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Gmail decodes a bounce email which created by Gmail https://mail.google.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Gmail
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -96,11 +96,11 @@ module Sisimai::Lhost
96
96
  '18' => { 'command' => 'DATA', 'reason' => 'filtered' },
97
97
  }.freeze
98
98
 
99
- # Parse bounce messages from Gmail
99
+ # @abstract Decodes the bounce message from Gmail
100
100
  # @param [Hash] mhead Message headers of a bounce email
101
101
  # @param [String] mbody Message body of a bounce email
102
102
  # @return [Hash] Bounce data list and message/rfc822 part
103
- # @return [Nil] it failed to parse or the arguments are missing
103
+ # @return [Nil] it failed to decode or the arguments are missing
104
104
  def inquire(mhead, mbody)
105
105
  # From: Mail Delivery Subsystem <mailer-daemon@googlemail.com>
106
106
  # Received: from vw-in-f109.1e100.net [74.125.113.109] by ...
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::GMX parses a bounce email which created by GMX. Methods in the module are called
3
- # from only Sisimai::Message.
2
+ # Sisimai::Lhost::GMX decodes a bounce email which created by GMX https://gmx.net/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module GMX
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -10,11 +10,11 @@ module Sisimai::Lhost
10
10
  StartingOf = { message: ['This message was created automatically by mail delivery software'] }.freeze
11
11
  MessagesOf = { 'expired' => ['delivery retry timeout exceeded'] }.freeze
12
12
 
13
- # Parse bounce messages from GMX
13
+ # @abstract Decodes the bounce message from GMX
14
14
  # @param [Hash] mhead Message headers of a bounce email
15
15
  # @param [String] mbody Message body of a bounce email
16
16
  # @return [Hash] Bounce data list and message/rfc822 part
17
- # @return [Nil] it failed to parse or the arguments are missing
17
+ # @return [Nil] it failed to decode or the arguments are missing
18
18
  def inquire(mhead, mbody)
19
19
  # Envelope-To: <kijitora@mail.example.com>
20
20
  # X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=V3;
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::GoogleGroups parses a bounce email which created by Google Groups. Methods in the
3
- # module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::GoogleGroups decodes a bounce email which created by Google Groups https://groups.google.com.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module GoogleGroups
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -8,11 +8,11 @@ module Sisimai::Lhost
8
8
  Indicators = Sisimai::Lhost.INDICATORS
9
9
  Boundaries = ['----- Original message -----'].freeze
10
10
 
11
- # Parse bounce messages from Google Groups
11
+ # @abstract Decodes the bounce message from Google Groups
12
12
  # @param [Hash] mhead Message headers of a bounce email
13
13
  # @param [String] mbody Message body of a bounce email
14
14
  # @return [Hash] Bounce data list and message/rfc822 part
15
- # @return [Nil] it failed to parse or the arguments are missing
15
+ # @return [Nil] it failed to decode or the arguments are missing
16
16
  # @since v4.25.6
17
17
  def inquire(mhead, mbody)
18
18
  return nil unless mhead['from'].end_with?('<mailer-daemon@googlemail.com>')
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::GSuite parses a bounce email which created by G Suite. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::GSuite decodes a bounce email which created by Google Workspace https://workspace.google.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module GSuite
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -17,11 +17,11 @@ module Sisimai::Lhost
17
17
  'networkerror' => [' had no relevant answers.', ' responded with code NXDOMAIN'],
18
18
  }.freeze
19
19
 
20
- # Parse bounce messages from G Suite (Transfer from G Suite to a destinaion host)
20
+ # @abstract Decodes the bounce message from G Suite (Transfer from G Suite to a destinaion host)
21
21
  # @param [Hash] mhead Message headers of a bounce email
22
22
  # @param [String] mbody Message body of a bounce email
23
23
  # @return [Hash] Bounce data list and message/rfc822 part
24
- # @return [Nil] it failed to parse or the arguments are missing
24
+ # @return [Nil] it failed to decode or the arguments are missing
25
25
  def inquire(mhead, mbody)
26
26
  return nil unless mhead['from'].end_with?('<mailer-daemon@googlemail.com>')
27
27
  return nil unless mhead['subject'].start_with?('Delivery Status Notification')
@@ -1,5 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::IMailServer parses a bounce email which created by Ipswitch IMail Server.
2
+ # Sisimai::Lhost::IMailServer decodes a bounce email which created by Progress iMail Server
3
+ # https://community.progress.com/s/products/imailserver.
3
4
  # Methods in the module are called from only Sisimai::Message.
4
5
  module IMailServer
5
6
  class << self
@@ -16,11 +17,11 @@ module Sisimai::Lhost
16
17
  'expired' => ['Delivery failed '],
17
18
  }.freeze
18
19
 
19
- # Parse bounce messages from IMailServer
20
+ # @abstract Decodes the bounce message from Progress iMail Server
20
21
  # @param [Hash] mhead Message headers of a bounce email
21
22
  # @param [String] mbody Message body of a bounce email
22
23
  # @return [Hash] Bounce data list and message/rfc822 part
23
- # @return [Nil] it failed to parse or the arguments are missing
24
+ # @return [Nil] it failed to decode or the arguments are missing
24
25
  def inquire(mhead, mbody)
25
26
  # X-Mailer: <SMTP32 v8.22>
26
27
  match = 0
@@ -1,16 +1,17 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::InterScanMSS parses a bounce email which created by Trend Micro InterScan Messaging
3
- # Security Suite. Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::InterScanMSS decodes a bounce email which created by Trend Micro InterScan
3
+ # Messaging Security Suite https://www.trendmicro.com/en_us/business/products/user-protection/sps/email-and-collaboration/interscan-messaging.html.
4
+ # Methods in the module are called from only Sisimai::Message.
4
5
  module InterScanMSS
5
6
  class << self
6
7
  require 'sisimai/lhost'
7
8
  Boundaries = ['Content-Type: message/rfc822'].freeze
8
9
 
9
- # Parse bounce messages from InterScanMSS
10
+ # @abstract Decodes the bounce message from Trend Micro InterScanMSS Messaging Secutiry Suie
10
11
  # @param [Hash] mhead Message headers of a bounce email
11
12
  # @param [String] mbody Message body of a bounce email
12
13
  # @return [Hash] Bounce data list and message/rfc822 part
13
- # @return [Nil] it failed to parse or the arguments are missing
14
+ # @return [Nil] it failed to decode or the arguments are missing
14
15
  def inquire(mhead, mbody)
15
16
  # :received => %r/[ ][(]InterScanMSS[)][ ]with[ ]/,
16
17
  match = 0
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::KDDI parses a bounce email which created by au by KDDI. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::KDDI decodes a bounce email which created by au by KDDI https://www.au.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module KDDI
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -14,11 +14,11 @@ module Sisimai::Lhost
14
14
  'hostunknown' => ['As the remote domain doesnt exist'],
15
15
  }.freeze
16
16
 
17
- # Parse bounce messages from au by KDDI
17
+ # @abstract Decodes the bounce message from au by KDDI
18
18
  # @param [Hash] mhead Message headers of a bounce email
19
19
  # @param [String] mbody Message body of a bounce email
20
20
  # @return [Hash] Bounce data list and message/rfc822 part
21
- # @return [Nil] it failed to parse or the arguments are missing
21
+ # @return [Nil] it failed to decode or the arguments are missing
22
22
  def inquire(mhead, mbody)
23
23
  # :'message-id' => %r/[@].+[.]ezweb[.]ne[.]jp[>]\z/,
24
24
  match = 0
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::MailFoundry parses a bounce email which created by MailFoundry. Methods in the
3
- # module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::MailFoundry decodes a bounce email which created by MailFoundry https://www.barracuda.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module MailFoundry
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -12,11 +12,11 @@ module Sisimai::Lhost
12
12
  error: ['Delivery failed for the following reason:'],
13
13
  }.freeze
14
14
 
15
- # Parse bounce messages from MailFoundry
15
+ # @abstract Decodes the bounce message from MailFoundry
16
16
  # @param [Hash] mhead Message headers of a bounce email
17
17
  # @param [String] mbody Message body of a bounce email
18
18
  # @return [Hash] Bounce data list and message/rfc822 part
19
- # @return [Nil] it failed to parse or the arguments are missing
19
+ # @return [Nil] it failed to decode or the arguments are missing
20
20
  def inquire(mhead, mbody)
21
21
  return nil unless mhead['subject'] == 'Message delivery has failed'
22
22
  return nil unless mhead['received'].any? { |a| a.include?('(MAILFOUNDRY) id ') }