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,5 +1,5 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X5 parses a bounce email which created by Unknown MTA #5. Methods in the module
2
+ # Sisimai::Lhost::X5 decodes a bounce email which created by Unknown MTA #5. Methods in the module
3
3
  # are called from only Sisimai::Message.
4
4
  module X5
5
5
  class << self
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['Content-Type: message/rfc822'].freeze
10
10
  StartingOf = { message: ['Content-Type: message/delivery-status'] }.freeze
11
11
 
12
- # Parse bounce messages from Unknown MTA #5
12
+ # @abstract Decodes the bounce message from Unknown MTA #5
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
  match = 0
19
19
  match += 1 if mhead['to'].to_s.include?('NotificationRecipients')
@@ -1,5 +1,5 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X6 parses a bounce email which created by Unknown MTA #6. Methods in the module
2
+ # Sisimai::Lhost::X6 decodes a bounce email which created by Unknown MTA #6. Methods in the module
3
3
  # are called from only Sisimai::Message.
4
4
  module X6
5
5
  class << self
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['The attachment contains the original mail headers'].freeze
10
10
  StartingOf = { message: ['We had trouble delivering your message. Full details follow:'] }.freeze
11
11
 
12
- # Parse bounce messages from Unknown MTA #6
12
+ # @abstract Decodes the bounce message from Unknown MTA #6
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
  return nil unless mhead['subject'].start_with?('There was an error sending your mail')
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Yahoo parses a bounce email which created by Yahoo! MAIL. Methods in the module
3
- # are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Yahoo decodes a bounce email which created by Yahoo Mail https://mail.yahoo.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Yahoo
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['--- Below this line is a copy of the message.'].freeze
10
10
  StartingOf = { message: ['Sorry, we were unable to deliver your message'] }.freeze
11
11
 
12
- # Parse bounce messages from Yahoo! MAIL
12
+ # @abstract Decodes the bounce message from Yahoo Mail
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
  # X-YMailISG: YtyUVyYWLDsbDh...
19
19
  # X-YMail-JAS: Pb65aU4VM1mei...
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Yandex parses a bounce email which created by Yandex.Mail. Methods in the module
3
- # are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Yandex decodes a bounce email which created by Yandex Mail https://360.yandex.com/mail/'.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Yandex
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['Content-Type: message/rfc822'].freeze
10
10
  StartingOf = { message: ['This is the mail system at host yandex.ru.'] }.freeze
11
11
 
12
- # Parse bounce messages from Yandex.Mail
12
+ # @abstract Decodes the bounce message from Yandex Mail
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
  # X-Yandex-Front: mxback1h.mail.yandex.net
19
19
  # X-Yandex-TimeMark: 1417885948
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Zoho parses a bounce email which created by Zoho Mail. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Zoho decodes a bounce email which created by Zoho Mail https://www.zoho.com/mail/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Zoho
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'] }.freeze
11
11
  MessagesOf = { 'expired' => ['Host not reachable'] }.freeze
12
12
 
13
- # Parse bounce messages from Zoho Mail
13
+ # @abstract Decodes the bounce message from Zoho Mail
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
  # X-ZohoMail: Si CHF_MF_NL SS_10 UW48 UB48 FMWL UW48 UB48 SGR3_1_09124_42
20
20
  # X-Zoho-Virus-Status: 2
data/lib/sisimai/lhost.rb CHANGED
@@ -4,7 +4,7 @@ module Sisimai
4
4
  class << self
5
5
  require 'sisimai/rfc5322'
6
6
 
7
- # Data structure for parsed bounce messages
7
+ # @abstract Returns the data structure for decoded bounce messages
8
8
  # @return [Hash] Data structure for delivery status
9
9
  # @private
10
10
  def DELIVERYSTATUS
@@ -42,8 +42,8 @@ module Sisimai
42
42
  def index
43
43
  return %w[
44
44
  Activehunter Amavis AmazonSES AmazonWorkMail Aol ApacheJames Barracuda Bigfoot Biglobe
45
- Courier Domino EZweb EinsUndEins Exchange2003 Exchange2007 Exim FML Facebook GMX GSuite
46
- GoogleGroups Gmail IMailServer InterScanMSS KDDI MXLogic MailFoundry MailMarshalSMTP
45
+ Courier Domino DragonFly EZweb EinsUndEins Exchange2003 Exchange2007 Exim FML Facebook GMX
46
+ GSuite GoogleGroups Gmail IMailServer InterScanMSS KDDI MXLogic MailFoundry MailMarshalSMTP
47
47
  MailRu McAfee MessageLabs MessagingServer Notes Office365 OpenSMTPD Outlook Postfix
48
48
  PowerMTA ReceivingSES SendGrid Sendmail SurfControl V5sendmail Verizon X1 X2 X3 X4 X5 X6
49
49
  Yahoo Yandex Zoho MFILTER Qmail
@@ -64,11 +64,11 @@ module Sisimai
64
64
  return table
65
65
  end
66
66
 
67
- # @abstract Parse bounce messages
67
+ # @abstract decode bounce messages
68
68
  # @param [Hash] mhead Message headers of a bounce email
69
69
  # @param [String] mbody Message body of a bounce email
70
70
  # @return [Hash] Bounce data list and message/rfc822 part
71
- # @return [Nil] it failed to parse or the arguments are missing
71
+ # @return [Nil] it failed to decode or the arguments are missing
72
72
  def inquire; return nil; end
73
73
  def description; return ''; end
74
74
  end
@@ -27,7 +27,7 @@ module Sisimai
27
27
  @handle = Dir.open(argv1)
28
28
  end
29
29
 
30
- # Maildir reader, works as a iterator.
30
+ # Maildir reader, works as an iterator.
31
31
  # @return [String] Contents of file in Maildir/
32
32
  def read
33
33
  return nil unless self.offset < self.size
@@ -21,7 +21,7 @@ module Sisimai
21
21
  @handle = stdin
22
22
  end
23
23
 
24
- # Mbox reader, works as a iterator.
24
+ # Mbox reader, works as an iterator.
25
25
  # @return [String] Contents of mbox
26
26
  def read
27
27
  readhandle = self.handle
data/lib/sisimai/mda.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Sisimai
2
- # Sisimai::MDA - Error message parser for MDA
2
+ # Sisimai::MDA - Error message decoder for MDA
3
3
  module MDA
4
4
  class << self
5
5
  AgentNames = {
@@ -66,11 +66,11 @@ module Sisimai
66
66
  },
67
67
  }.freeze
68
68
 
69
- # Parse message body and return reason and text
69
+ # @abstract Decodes the message body and return the MDA name, the reason, and the error message
70
70
  # @param [Hash] mhead Message headers of a bounce email
71
71
  # @param [String] mbody Message body of a bounce email
72
72
  # @return [Hash] Bounce data list and message/rfc822 part
73
- # @return [Nil] it failed to parse or the arguments are missing
73
+ # @return [Nil] it failed to decode or the arguments are missing
74
74
  def inquire(mhead, mbody)
75
75
  return nil unless mhead
76
76
  return nil unless mbody.size > 0
@@ -351,11 +351,11 @@ module Sisimai
351
351
  # @param options mail [String] from From line of mbox
352
352
  # @param options mail [Hash] header Email header data
353
353
  # @param options mail [String] rfc822 Original message part
354
- # @param options mail [Array] ds Delivery status list(parsed data)
354
+ # @param options mail [Array] ds Delivery status list(decoded data)
355
355
  # @param options argvs [String] body Email message body
356
356
  # @param options argvs [Array] tryonfirst MTA module list to load on first
357
357
  # @param options argvs [Array] tobeloaded User defined MTA module list
358
- # @return [Hash] Parsed and structured bounce mails
358
+ # @return [Hash] Decoded and structured bounce mails
359
359
  def sift(argvs)
360
360
  return nil unless argvs['mail']
361
361
  return nil unless argvs['body']
@@ -414,7 +414,7 @@ module Sisimai
414
414
  end
415
415
  end
416
416
 
417
- catch :PARSER do
417
+ catch :DECODER do
418
418
  while true
419
419
  # 1. User-Defined Module
420
420
  # 2. MTA Module Candidates to be tried on first
@@ -428,7 +428,7 @@ module Sisimai
428
428
  havesifted = Module.const_get(r).inquire(mailheader, bodystring)
429
429
  haveloaded[r] = true
430
430
  modulename = r
431
- throw :PARSER if havesifted
431
+ throw :DECODER if havesifted
432
432
  end
433
433
 
434
434
  [argvs['tryonfirst'], DefaultSet].flatten.each do |r|
@@ -438,7 +438,7 @@ module Sisimai
438
438
  havesifted = Module.const_get(r).inquire(mailheader, bodystring)
439
439
  haveloaded[r] = true
440
440
  modulename = r
441
- throw :PARSER if havesifted
441
+ throw :DECODER if havesifted
442
442
  end
443
443
 
444
444
  unless haveloaded['Sisimai::RFC3464']
@@ -446,14 +446,14 @@ module Sisimai
446
446
  require 'sisimai/rfc3464'
447
447
  havesifted = Sisimai::RFC3464.inquire(mailheader, bodystring)
448
448
  modulename = 'RFC3464'
449
- throw :PARSER if havesifted
449
+ throw :DECODER if havesifted
450
450
  end
451
451
 
452
452
  unless haveloaded['Sisimai::ARF']
453
453
  # Feedback Loop message
454
454
  require 'sisimai/arf'
455
- havesifted = Sisimai::ARF.inquire(mailheader, bodystring) if Sisimai::ARF.is_arf(mailheader)
456
- throw :PARSER if havesifted
455
+ havesifted = Sisimai::ARF.inquire(mailheader, bodystring)
456
+ throw :DECODER if havesifted
457
457
  end
458
458
 
459
459
  unless haveloaded['Sisimai::RFC3834']
@@ -461,7 +461,7 @@ module Sisimai
461
461
  require 'sisimai/rfc3834'
462
462
  havesifted = Sisimai::RFC3834.inquire(mailheader, bodystring)
463
463
  modulename = 'RFC3834'
464
- throw :PARSER if havesifted
464
+ throw :DECODER if havesifted
465
465
  end
466
466
 
467
467
  break # as of now, we have no sample email for coding this block
data/lib/sisimai/order.rb CHANGED
@@ -105,6 +105,7 @@ module Sisimai
105
105
  'loop-alert' => ['Sisimai::Lhost::FML'],
106
106
  'mail-delivery' => [
107
107
  'Sisimai::Lhost::Exim',
108
+ 'Sisimai::Lhost::DragonFly',
108
109
  'Sisimai::Lhost::MailRu',
109
110
  'Sisimai::Lhost::GMX',
110
111
  'Sisimai::Lhost::EinsUndEins',
@@ -19,6 +19,7 @@ module Sisimai
19
19
  'has been temporarily rate limited due to ip reputation',
20
20
  'ip/domain reputation problems',
21
21
  'likely suspicious due to the very low reputation',
22
+ 'temporarily deferred due to unexpected volume or user complaints', # Yahoo Inc.
22
23
  "the sending mta's poor reputation",
23
24
  ].freeze
24
25
  def text; return 'badreputation'; end
@@ -40,7 +41,6 @@ module Sisimai
40
41
  # false: is not BadReputation
41
42
  # @see http://www.ietf.org/rfc/rfc2822.txt
42
43
  def true(argvs)
43
- return nil if argvs['deliverystatus'].empty?
44
44
  return true if argvs['reason'] == 'badreputation'
45
45
  return true if match(argvs['diagnosticcode'].downcase)
46
46
  return false
@@ -62,6 +62,7 @@ module Sisimai
62
62
  'we do not accept mail from dynamic ips', # @mail.ru
63
63
  'you are not allowed to connect',
64
64
  'you are sending spam',
65
+ 'your ip address is listed in the rbl',
65
66
  'your network is temporary blacklisted',
66
67
  'your server requires confirmation',
67
68
  ].freeze
@@ -7,10 +7,13 @@ module Sisimai
7
7
  # the message you sent has been in the queue for long time.
8
8
  module Expired
9
9
  class << self
10
+ require 'sisimai/string'
11
+
10
12
  Index = [
11
13
  'connection timed out',
12
14
  'could not find a gateway for',
13
15
  'delivery attempts will continue to be',
16
+ 'delivery expired',
14
17
  'delivery time expired',
15
18
  'failed to deliver to domain ',
16
19
  'giving up on',
@@ -28,6 +31,9 @@ module Sisimai
28
31
  'was not reachable within the allowed queue period',
29
32
  'your message could not be delivered for more than',
30
33
  ].freeze
34
+ Pairs = [
35
+ ['could not be delivered for', ' days'],
36
+ ].freeze
31
37
 
32
38
  def text; return 'expired'; end
33
39
  def description; return 'Delivery time has expired due to a connection failure'; end
@@ -39,6 +45,7 @@ module Sisimai
39
45
  def match(argv1)
40
46
  return nil unless argv1
41
47
  return true if Index.any? { |a| argv1.include?(a) }
48
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
42
49
  return false
43
50
  end
44
51
 
@@ -21,6 +21,7 @@ module Sisimai
21
21
  'resolver.rst.notauthorized', # Microsoft Exchange
22
22
  'this account is protected by',
23
23
  'user not found', # Filter on MAIL.RU
24
+ 'user refuses to receive this mail',
24
25
  'user reject',
25
26
  'we failed to deliver mail because the following address recipient id refuse to receive mail', # Willcom
26
27
  'you have been blocked by the recipient',
@@ -8,6 +8,7 @@ module Sisimai
8
8
  module MailboxFull
9
9
  class << self
10
10
  Index = [
11
+ '452 insufficient disk space',
11
12
  'account disabled temporarly for exceeding receiving limits',
12
13
  'account is exceeding their quota',
13
14
  'account is over quota',
@@ -35,7 +36,9 @@ module Sisimai
35
36
  'maildir delivery failed: userdisk quota ',
36
37
  'maildir delivery failed: domaindisk quota ',
37
38
  'mailfolder is full',
39
+ 'no space left on device',
38
40
  'not enough storage space in',
41
+ 'not sufficient disk space',
39
42
  'over the allowed quota',
40
43
  'quota exceeded',
41
44
  'quota violation for',
@@ -15,6 +15,7 @@ module Sisimai
15
15
  'insecure mail relay',
16
16
  'is not permitted to relay through this server without authentication',
17
17
  'mail server requires authentication when attempting to send to a non-local e-mail address', # MailEnable
18
+ 'no relaying',
18
19
  'not a gateway',
19
20
  'not allowed to relay through this machine',
20
21
  'not an open relay, so get lost',
@@ -24,6 +25,7 @@ module Sisimai
24
25
  'relay not permitted',
25
26
  'relaying denied', # Sendmail
26
27
  'relaying mail to ',
28
+ 'specified domain is not allowed',
27
29
  "that domain isn't in my list of allowed rcpthost",
28
30
  'this system is not configured to relay mail',
29
31
  'unable to relay for',
@@ -38,7 +38,7 @@ module Sisimai
38
38
  'email address is on senderfilterconfig list',
39
39
  'emetteur invalide',
40
40
  'empty envelope senders not allowed',
41
- 'envelope blocked ',
41
+ 'envelope blocked - ',
42
42
  'error: no third-party dsns', # SpamWall - block empty sender
43
43
  'from: domain is invalid. please provide a valid from:',
44
44
  'fully qualified email address required', # McAfee
@@ -63,6 +63,7 @@ module Sisimai
63
63
  'sender rejected',
64
64
  'sender domain is empty',
65
65
  'sender verify failed', # Exim callout
66
+ 'sender was rejected', # qmail
66
67
  'spam reporting address', # SendGrid|a message to an address has previously been marked as Spam by the recipient.
67
68
  'syntax error: empty email address',
68
69
  'the message has been rejected by batv defense',
@@ -12,17 +12,21 @@ module Sisimai
12
12
  'boite du destinataire archivee',
13
13
  'email account that you tried to reach is disabled',
14
14
  'has been suspended',
15
+ 'inactive account',
15
16
  'invalid/inactive user',
16
17
  'is a deactivated mailbox', # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
17
18
  'is unavailable: user is terminated',
18
19
  'mailbox currently suspended',
20
+ 'mailbox disabled',
19
21
  'mailbox is frozen',
20
22
  'mailbox unavailable or access denied',
21
23
  'recipient rejected: temporarily inactive',
22
24
  'recipient suspend the service',
23
25
  'this account has been disabled or discontinued',
26
+ 'this account has been temporarily suspended',
24
27
  'this address no longer accepts mail',
25
28
  'this mailbox is disabled',
29
+ 'user or domain is disabled',
26
30
  'user suspended', # http://mail.163.com/help/help_spam_16.htm
27
31
  'vdelivermail: account is locked email bounced',
28
32
  ].freeze
@@ -63,7 +63,6 @@ module Sisimai
63
63
  'no such mailbox',
64
64
  'no such person at this address',
65
65
  'no such recipient',
66
-
67
66
  'no such user',
68
67
  'no thank you rejected: account unavailable',
69
68
  'no valid recipients, bye',
@@ -76,7 +75,9 @@ module Sisimai
76
75
  'recipient address rejected: invalid user',
77
76
  'recipient address rejected: invalid-recipient',
78
77
  'recipient address rejected: unknown user',
78
+ 'recipient address rejected: userunknown',
79
79
  'recipient does not exist',
80
+ 'recipient is not accepted',
80
81
  'recipient is not local',
81
82
  'recipient not exist',
82
83
  'recipient not found',
@@ -125,6 +126,7 @@ module Sisimai
125
126
  ['no ', ' in name directory'],
126
127
  ['non', 'existent user'],
127
128
  ['rcpt <', ' does not exist'],
129
+ ['rcpt (', 't exist '],
128
130
  ['recipient ', ' was not found in'],
129
131
  ['recipient address rejected: user ', ' does not exist'],
130
132
  ['recipient address rejected: user unknown in ', ' table'],
@@ -135,6 +137,7 @@ module Sisimai
135
137
  ['unknown local', 'part'],
136
138
  ['user ', ' was not found'],
137
139
  ['user ', ' does not exist'],
140
+ ['user (', ') unknown'],
138
141
  ].freeze
139
142
 
140
143
  def text; return 'userunknown'; end
@@ -38,13 +38,13 @@ module Sisimai
38
38
  ClassOrder = [
39
39
  %w[
40
40
  MailboxFull MesgTooBig ExceedLimit Suspend HasMoved NoRelaying AuthFailure UserUnknown
41
- Filtered RequirePTR NotCompliantRFC Rejected HostUnknown SpamDetected Speeding TooManyConn
42
- Blocked
41
+ Filtered RequirePTR NotCompliantRFC BadReputation Rejected HostUnknown SpamDetected Speeding
42
+ TooManyConn Blocked
43
43
  ],
44
44
  %w[
45
- MailboxFull SpamDetected PolicyViolation VirusDetected NoRelaying AuthFailure
46
- BadReputation SecurityError SystemError NetworkError Speeding Suspend Expired ContentError
47
- SystemFull NotAccept MailerError
45
+ MailboxFull AuthFailure BadReputation Speeding SpamDetected VirusDetected PolicyViolation
46
+ NoRelaying SystemError NetworkError Suspend ContentError SystemFull NotAccept Expired
47
+ SecurityError MailerError
48
48
  ],
49
49
  %w[
50
50
  MailboxFull MesgTooBig ExceedLimit Suspend UserUnknown Filtered Rejected HostUnknown
@@ -55,7 +55,7 @@ module Sisimai
55
55
  ]
56
56
 
57
57
  # Detect the bounce reason
58
- # @param [Hash] argvs Parsed email object
58
+ # @param [Hash] argvs Decoded email object
59
59
  # @return [String, nil] Bounce reason or nil if the argument is missing or not Hash
60
60
  # @see anotherone
61
61
  def get(argvs)
@@ -112,7 +112,7 @@ module Sisimai
112
112
  end
113
113
 
114
114
  # Detect the other bounce reason, fall back method for get()
115
- # @param [Hash] argvs Parsed email object
115
+ # @param [Hash] argvs Decoded email object
116
116
  # @return [String, Nil] Bounce reason or nli if the argument is missing or not Hash
117
117
  # @see get
118
118
  def anotherone(argvs)
@@ -216,7 +216,7 @@ module Sisimai
216
216
  end
217
217
  return reasontext unless reasontext.empty?
218
218
 
219
- if issuedcode.upcase == 'X-UNIX'
219
+ if issuedcode.upcase.include?('X-UNIX; ')
220
220
  # X-Unix; ...
221
221
  reasontext = 'mailererror'
222
222
  else
@@ -1,5 +1,5 @@
1
1
  module Sisimai
2
- # Sisimai::RFC3464 - bounce mail parser class for Fallback.
2
+ # Sisimai::RFC3464 - bounce mail decoder class for Fallback.
3
3
  module RFC3464
4
4
  class << self
5
5
  require 'sisimai/lhost'
@@ -96,7 +96,7 @@ module Sisimai
96
96
  # @param [Hash] mhead Message headers of a bounce email
97
97
  # @param [String] mbody Message body of a bounce email
98
98
  # @return [Hash] Bounce data list and message/rfc822 part
99
- # @return [Nil] it failed to parse or the arguments are missing
99
+ # @return [Nil] it failed to decode or the arguments are missing
100
100
  def inquire(mhead, mbody)
101
101
  fieldtable = Sisimai::RFC1894.FIELDTABLE
102
102
  permessage = {} # (Hash) Store values of each Per-Message field
@@ -233,7 +233,7 @@ module Sisimai
233
233
 
234
234
  # -----------------------------------------------------------------------------------------
235
235
  while true
236
- # Fallback, parse entire message body
236
+ # Fallback, decode the entire message body
237
237
  break if recipients > 0
238
238
 
239
239
  # Failed to get a recipient address at code above
@@ -33,7 +33,7 @@ module Sisimai
33
33
  # @param [Hash] mhead Message headers of a bounce email
34
34
  # @param [String] mbody Message body of a bounce email
35
35
  # @return [Hash] Bounce data list and message/rfc822 part
36
- # @return [Nil] it failed to parse or the arguments are missing
36
+ # @return [Nil] it failed to decode or the arguments are missing
37
37
  def inquire(mhead, mbody)
38
38
  leave = 0
39
39
  match = 0
@@ -98,7 +98,7 @@ module Sisimai
98
98
  MarkingsOf[:boundary] = q unless q.empty?
99
99
  end
100
100
 
101
- # BODY_PARSER: Get vacation message
101
+ # MESSAGE_BODY: Get the vacation message
102
102
  while e = bodyslices.shift do
103
103
  # Read the first 5 lines except a blank line
104
104
  countuntil += 1 if e.include?(MarkingsOf[:boundary])
@@ -0,0 +1,92 @@
1
+ module Sisimai
2
+ module Rhost
3
+ # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
4
+ # of get() method when the value of "destination" of the object is "mail.icloud.com" or "apple.com".
5
+ # This class is called only Sisimai::Fact class.
6
+ module Apple
7
+ class << self
8
+ MessagesOf = {
9
+ 'authfailure' => [
10
+ # - 554 5.7.1 Your message was rejected due to example.jp's DMARC policy.
11
+ # See https://support.apple.com/en-us/HT204137 for
12
+ # - 554 5.7.1 [HME1] This message was blocked for failing both SPF and DKIM authentication
13
+ # checks. See https://support.apple.com/en-us/HT204137 for mailing best practices
14
+ 's dmarc policy',
15
+ 'blocked for failing both spf and dkim autentication checks',
16
+ ],
17
+ 'blocked' => [
18
+ # - 550 5.7.0 Blocked - see https://support.proofpoint.com/dnsbl-lookup.cgi?ip=192.0.1.2
19
+ # - 550 5.7.1 Your email was rejected due to having a domain present in the Spamhaus
20
+ # DBL -- see https://www.spamhaus.org/dbl/
21
+ # - 550 5.7.1 Mail from IP 192.0.2.1 was rejected due to listing in Spamhaus SBL.
22
+ # For details please see http://www.spamhaus.org/query/bl?ip=x.x.x.x
23
+ # - 554 ****-smtpin001.me.com ESMTP not accepting connections
24
+ 'rejected due to having a domain present in the spamhaus',
25
+ 'rejected due to listing in spamhaus',
26
+ 'blocked - see https://support.proofpoint.com/dnsbl-lookup',
27
+ 'not accepting connections',
28
+ ],
29
+ 'hasmoved' => [
30
+ # - 550 5.1.6 recipient no longer on server: *****@icloud.com
31
+ 'recipient no longer on server',
32
+ ],
33
+ 'mailboxfull' => [
34
+ # - 552 5.2.2 <****@icloud.com>: user is over quota (in reply to RCPT TO command)
35
+ 'user is over quota',
36
+ ],
37
+ 'norelaying' => [
38
+ # - 554 5.7.1 <*****@icloud.com>: Relay access denied
39
+ 'relay access denied',
40
+ ],
41
+ 'notaccept' => ['host/domain does not accept mail'],
42
+ 'policyviolation' => [
43
+ # - 550 5.7.1 [CS01] Message rejected due to local policy.
44
+ # Please visit https://support.apple.com/en-us/HT204137
45
+ 'due to local policy',
46
+ ],
47
+ 'rejected' => [
48
+ # - 450 4.1.8 <kijitora@example.jp>: Sender address rejected: Domain not found
49
+ 'sender address rejected',
50
+ ],
51
+ 'speeding' => [
52
+ # - 421 4.7.1 Messages to ****@icloud.com deferred due to excessive volume.
53
+ # Try again later - https://support.apple.com/en-us/HT204137
54
+ 'due to excessive volume',
55
+ ],
56
+ 'userunknown' => [
57
+ # - 550 5.1.1 <****@icloud.com>: inactive email address (in reply to RCPT TO command)
58
+ # - 550 5.1.1 unknown or illegal alias: ****@icloud.com
59
+ 'inactive email address',
60
+ 'user does not exist',
61
+ 'unknown or illegal alias',
62
+ ],
63
+ }.freeze
64
+
65
+ # Detect bounce reason from Apple iCloud Mail
66
+ # @param [Sisimai::Fact] argvs Decoded email object
67
+ # @return [String] The bounce reason for Apple
68
+ # @see https://support.apple.com/en-us/102322
69
+ # https://www.postmastery.com/icloud-postmastery-page/
70
+ # https://smtpfieldmanual.com/provider/apple
71
+ # @since v5.1.0
72
+ def get(argvs)
73
+ issuedcode = argvs['diagnosticcode'].downcase
74
+ reasontext = ''
75
+
76
+ MessagesOf.each_key do |e|
77
+ MessagesOf[e].each do |f|
78
+ next unless issuedcode.include?(f)
79
+ reasontext = e
80
+ break
81
+ end
82
+ break if reasontext.size > 0
83
+ end
84
+
85
+ return reasontext
86
+ end
87
+
88
+ end
89
+ end
90
+ end
91
+ end
92
+