sisimai 4.25.16 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/ANALYTICAL-PRECISION +2 -2
  4. data/Benchmarks.mk +3 -3
  5. data/CONTRIBUTING +1 -1
  6. data/ChangeLog.md +412 -393
  7. data/Developers.mk +5 -6
  8. data/Gemfile +1 -1
  9. data/Makefile +15 -15
  10. data/README-JA.md +140 -78
  11. data/README.md +290 -143
  12. data/Rakefile +9 -3
  13. data/Repository.mk +2 -3
  14. data/lib/sisimai/address.rb +118 -74
  15. data/lib/sisimai/arf.rb +84 -82
  16. data/lib/sisimai/datetime.rb +5 -52
  17. data/lib/sisimai/{data → fact}/json.rb +7 -9
  18. data/lib/sisimai/fact/yaml.rb +31 -0
  19. data/lib/sisimai/fact.rb +468 -0
  20. data/lib/sisimai/lhost/activehunter.rb +12 -14
  21. data/lib/sisimai/lhost/amavis.rb +11 -14
  22. data/lib/sisimai/lhost/amazonses.rb +37 -41
  23. data/lib/sisimai/lhost/amazonworkmail.rb +15 -18
  24. data/lib/sisimai/lhost/aol.rb +12 -14
  25. data/lib/sisimai/lhost/apachejames.rb +19 -21
  26. data/lib/sisimai/lhost/barracuda.rb +10 -12
  27. data/lib/sisimai/lhost/bigfoot.rb +21 -21
  28. data/lib/sisimai/lhost/biglobe.rb +15 -16
  29. data/lib/sisimai/lhost/courier.rb +20 -20
  30. data/lib/sisimai/lhost/domino.rb +23 -19
  31. data/lib/sisimai/lhost/einsundeins.rb +23 -18
  32. data/lib/sisimai/lhost/exchange2003.rb +30 -29
  33. data/lib/sisimai/lhost/exchange2007.rb +70 -58
  34. data/lib/sisimai/lhost/exim.rb +175 -161
  35. data/lib/sisimai/lhost/ezweb.rb +31 -56
  36. data/lib/sisimai/lhost/facebook.rb +21 -33
  37. data/lib/sisimai/lhost/fml.rb +43 -48
  38. data/lib/sisimai/lhost/gmail.rb +29 -29
  39. data/lib/sisimai/lhost/gmx.rb +18 -17
  40. data/lib/sisimai/lhost/googlegroups.rb +9 -10
  41. data/lib/sisimai/lhost/gsuite.rb +21 -27
  42. data/lib/sisimai/lhost/imailserver.rb +25 -39
  43. data/lib/sisimai/lhost/interscanmss.rb +28 -31
  44. data/lib/sisimai/lhost/kddi.rb +22 -28
  45. data/lib/sisimai/lhost/mailfoundry.rb +11 -12
  46. data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
  47. data/lib/sisimai/lhost/mailru.rb +33 -27
  48. data/lib/sisimai/lhost/mcafee.rb +21 -31
  49. data/lib/sisimai/lhost/messagelabs.rb +17 -20
  50. data/lib/sisimai/lhost/messagingserver.rb +40 -37
  51. data/lib/sisimai/lhost/mfilter.rb +15 -16
  52. data/lib/sisimai/lhost/mxlogic.rb +24 -23
  53. data/lib/sisimai/lhost/notes.rb +17 -17
  54. data/lib/sisimai/lhost/office365.rb +63 -27
  55. data/lib/sisimai/lhost/opensmtpd.rb +12 -13
  56. data/lib/sisimai/lhost/outlook.rb +12 -15
  57. data/lib/sisimai/lhost/postfix.rb +179 -129
  58. data/lib/sisimai/lhost/powermta.rb +12 -14
  59. data/lib/sisimai/lhost/qmail.rb +44 -47
  60. data/lib/sisimai/lhost/receivingses.rb +15 -20
  61. data/lib/sisimai/lhost/sendgrid.rb +34 -32
  62. data/lib/sisimai/lhost/sendmail.rb +66 -53
  63. data/lib/sisimai/lhost/surfcontrol.rb +19 -19
  64. data/lib/sisimai/lhost/v5sendmail.rb +45 -39
  65. data/lib/sisimai/lhost/verizon.rb +35 -39
  66. data/lib/sisimai/lhost/x1.rb +18 -17
  67. data/lib/sisimai/lhost/x2.rb +17 -14
  68. data/lib/sisimai/lhost/x3.rb +19 -19
  69. data/lib/sisimai/lhost/x4.rb +72 -57
  70. data/lib/sisimai/lhost/x5.rb +17 -19
  71. data/lib/sisimai/lhost/x6.rb +41 -17
  72. data/lib/sisimai/lhost/yahoo.rb +17 -16
  73. data/lib/sisimai/lhost/yandex.rb +16 -20
  74. data/lib/sisimai/lhost/zoho.rb +16 -15
  75. data/lib/sisimai/lhost.rb +8 -10
  76. data/lib/sisimai/mail/maildir.rb +1 -3
  77. data/lib/sisimai/mail/mbox.rb +3 -4
  78. data/lib/sisimai/mail/memory.rb +0 -1
  79. data/lib/sisimai/mail/stdin.rb +1 -3
  80. data/lib/sisimai/mail.rb +3 -7
  81. data/lib/sisimai/mda.rb +28 -42
  82. data/lib/sisimai/message.rb +435 -326
  83. data/lib/sisimai/order.rb +5 -5
  84. data/lib/sisimai/reason/authfailure.rb +64 -0
  85. data/lib/sisimai/reason/badreputation.rb +53 -0
  86. data/lib/sisimai/reason/blocked.rb +94 -160
  87. data/lib/sisimai/reason/contenterror.rb +8 -9
  88. data/lib/sisimai/reason/delivered.rb +4 -6
  89. data/lib/sisimai/reason/exceedlimit.rb +10 -12
  90. data/lib/sisimai/reason/expired.rb +6 -8
  91. data/lib/sisimai/reason/feedback.rb +2 -3
  92. data/lib/sisimai/reason/filtered.rb +17 -19
  93. data/lib/sisimai/reason/hasmoved.rb +9 -10
  94. data/lib/sisimai/reason/hostunknown.rb +15 -15
  95. data/lib/sisimai/reason/mailboxfull.rb +10 -12
  96. data/lib/sisimai/reason/mailererror.rb +18 -20
  97. data/lib/sisimai/reason/mesgtoobig.rb +9 -11
  98. data/lib/sisimai/reason/networkerror.rb +5 -8
  99. data/lib/sisimai/reason/norelaying.rb +8 -11
  100. data/lib/sisimai/reason/notaccept.rb +13 -14
  101. data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
  102. data/lib/sisimai/reason/onhold.rb +6 -9
  103. data/lib/sisimai/reason/policyviolation.rb +14 -12
  104. data/lib/sisimai/reason/rejected.rb +26 -24
  105. data/lib/sisimai/reason/requireptr.rb +69 -0
  106. data/lib/sisimai/reason/securityerror.rb +33 -36
  107. data/lib/sisimai/reason/spamdetected.rb +114 -147
  108. data/lib/sisimai/reason/speeding.rb +49 -0
  109. data/lib/sisimai/reason/suspend.rb +11 -11
  110. data/lib/sisimai/reason/syntaxerror.rb +11 -10
  111. data/lib/sisimai/reason/systemerror.rb +7 -9
  112. data/lib/sisimai/reason/systemfull.rb +7 -8
  113. data/lib/sisimai/reason/toomanyconn.rb +9 -11
  114. data/lib/sisimai/reason/undefined.rb +2 -3
  115. data/lib/sisimai/reason/userunknown.rb +129 -146
  116. data/lib/sisimai/reason/vacation.rb +3 -4
  117. data/lib/sisimai/reason/virusdetected.rb +10 -11
  118. data/lib/sisimai/reason.rb +59 -64
  119. data/lib/sisimai/rfc1894.rb +55 -28
  120. data/lib/sisimai/rfc2045.rb +373 -0
  121. data/lib/sisimai/rfc3464.rb +250 -308
  122. data/lib/sisimai/rfc3834.rb +42 -45
  123. data/lib/sisimai/rfc5322.rb +75 -100
  124. data/lib/sisimai/rfc5965.rb +31 -0
  125. data/lib/sisimai/rhost/cox.rb +5 -6
  126. data/lib/sisimai/rhost/franceptt.rb +6 -8
  127. data/lib/sisimai/rhost/godaddy.rb +12 -12
  128. data/lib/sisimai/rhost/{googleapps.rb → google.rb} +80 -72
  129. data/lib/sisimai/rhost/iua.rb +9 -10
  130. data/lib/sisimai/rhost/kddi.rb +6 -8
  131. data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
  132. data/lib/sisimai/rhost/mimecast.rb +42 -40
  133. data/lib/sisimai/rhost/nttdocomo.rb +12 -12
  134. data/lib/sisimai/rhost/spectrum.rb +10 -12
  135. data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
  136. data/lib/sisimai/rhost.rb +23 -31
  137. data/lib/sisimai/smtp/command.rb +59 -0
  138. data/lib/sisimai/smtp/error.rb +4 -7
  139. data/lib/sisimai/smtp/reply.rb +161 -74
  140. data/lib/sisimai/smtp/status.rb +504 -393
  141. data/lib/sisimai/smtp/transcript.rb +124 -0
  142. data/lib/sisimai/smtp.rb +0 -1
  143. data/lib/sisimai/string.rb +74 -5
  144. data/lib/sisimai/time.rb +1 -2
  145. data/lib/sisimai/version.rb +1 -1
  146. data/lib/sisimai.rb +35 -21
  147. data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
  148. data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
  149. data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
  150. data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
  151. data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
  152. data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
  153. data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
  154. data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
  155. data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
  156. data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
  157. data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
  158. data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
  159. data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
  160. data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
  161. data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
  162. data/sisimai-java.gemspec +1 -1
  163. data/sisimai.gemspec +1 -1
  164. metadata +41 -20
  165. data/.rspec +0 -2
  166. data/lib/sisimai/data/yaml.rb +0 -33
  167. data/lib/sisimai/data.rb +0 -411
  168. data/lib/sisimai/mime.rb +0 -456
  169. /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
  170. /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
  171. /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
  172. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
  173. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
  174. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
  175. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
  176. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
  177. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
@@ -1,21 +1,20 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::Suspend checks the bounce reason is C<suspend> or not.
4
- # This class is called only Sisimai::Reason class.
5
- #
6
- # This is the error that a recipient account is being suspended due to
7
- # unpaid or other reasons.
3
+ # Sisimai::Reason::Suspend checks the bounce reason is "suspend" or not. This class is called
4
+ # only Sisimai::Reason class. This is the error that a recipient account is being suspended
5
+ # due to unpaid or other reasons.
8
6
  module Suspend
9
- # Imported from p5-Sisimail/lib/Sisimai/Reason/Suspend.pm
10
7
  class << self
11
8
  Index = [
12
9
  ' is currently suspended',
13
10
  ' temporary locked',
11
+ 'archived recipient',
14
12
  'boite du destinataire archivee',
15
13
  'email account that you tried to reach is disabled',
16
14
  'has been suspended',
17
15
  'invalid/inactive user',
18
16
  'is a deactivated mailbox', # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
17
+ 'is unavailable: user is terminated',
19
18
  'mailbox currently suspended',
20
19
  'mailbox is frozen',
21
20
  'mailbox unavailable or access denied',
@@ -25,7 +24,7 @@ module Sisimai
25
24
  'this mailbox is disabled',
26
25
  'user suspended', # http://mail.163.com/help/help_spam_16.htm
27
26
  'vdelivermail: account is locked email bounced',
28
- ]
27
+ ].freeze
29
28
 
30
29
  def text; return 'suspend'; end
31
30
  def description; return 'Email rejected due to a recipient account is being suspended'; end
@@ -41,14 +40,15 @@ module Sisimai
41
40
  end
42
41
 
43
42
  # The envelope recipient's mailbox is suspended or not
44
- # @param [Sisimai::Data] argvs Object to be detected the reason
43
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
45
44
  # @return [True,False] true: is mailbox suspended
46
45
  # false: is not suspended
47
46
  # @see http://www.ietf.org/rfc/rfc2822.txt
48
47
  def true(argvs)
49
- return nil if argvs.deliverystatus.empty?
50
- return true if argvs.reason == 'suspend'
51
- return true if match(argvs.diagnosticcode.downcase)
48
+ return nil if argvs['deliverystatus'].empty?
49
+ return true if argvs['reason'] == 'suspend'
50
+ return true if argvs['replycode'].to_i == 525
51
+ return true if match(argvs['diagnosticcode'].downcase)
52
52
  return false
53
53
  end
54
54
 
@@ -1,33 +1,34 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SyntaxError checks the bounce reason is "syntaxerror" or
4
- # not. This class is called only Sisimai::Reason class.
3
+ # Sisimai::Reason::SyntaxError checks the bounce reason is "syntaxerror" or not. This class is
4
+ # called only Sisimai::Reason class.
5
5
  #
6
- # This is the error that a destination mail server could not recognize SMTP
7
- # command which is sent from a sender's MTA. Sisimai will set "syntaxerror"
8
- # to the reason if the value of "replycode" begins with "50" such as 502,
9
- # or 503.
6
+ # This is the error that a destination mail server could not recognize SMTP command which is
7
+ # sent from a sender's MTA. Sisimai will set "syntaxerror" to the reason if the value of
8
+ # "replycode" begins with "50" such as 502, or 503.
10
9
  # Action: failed
11
10
  # Status: 5.5.0
12
11
  # Diagnostic-Code: SMTP; 503 Improper sequence of commands
13
12
  #
14
13
  module SyntaxError
15
- # Imported from p5-Sisimail/lib/Sisimai/Reason/SyntaxError.pm
16
14
  class << self
17
15
  def text; return 'syntaxerror'; end
18
16
  def description; return 'Email rejected due to syntax error at sent commands in SMTP session'; end
19
17
  def match(*); return nil; end
20
18
 
21
19
  # Connection rejected due to syntax error or not
22
- # @param [Sisimai::Data] argvs Object to be detected the reason
20
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
23
21
  # @return [True,False] true: Connection rejected due to
24
22
  # syntax error
25
23
  # false: is not syntax error
26
24
  # @since 4.1.25
27
25
  # @see http://www.ietf.org/rfc/rfc2822.txt
28
26
  def true(argvs)
29
- return true if argvs.reason == 'syntaxerror'
30
- return true if argvs.replycode =~ /\A[45]0[0-7]\z/
27
+ return true if argvs['reason'] == 'syntaxerror'
28
+
29
+ reply = argvs['replycode'].to_i
30
+ return true if reply > 400 && reply < 408
31
+ return true if reply > 500 && reply < 508
31
32
  return false
32
33
  end
33
34
 
@@ -1,16 +1,13 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SystemError checks the bounce reason is "systemerror" or
4
- # not. This class is called only Sisimai::Reason class.
5
- #
6
- # This is the error that an email has bounced due to system error on the
7
- # remote host such as LDAP connection failure or other internal system error.
3
+ # Sisimai::Reason::SystemError checks the bounce reason is "systemerror" or not. This class is
4
+ # called only Sisimai::Reason class. This is the error that an email has bounced due to system
5
+ # error on the remote host such as LDAP connection failure or other internal system error.
8
6
  #
9
7
  # <kijitora@example.net>:
10
8
  # Unable to contact LDAP server. (#4.4.3)I'm not going to try again; this
11
9
  # message has been in the queue too long.
12
10
  module SystemError
13
- # Imported from p5-Sisimail/lib/Sisimai/Reason/SystemError.pm
14
11
  class << self
15
12
  Index = [
16
13
  'aliasing/forwarding loop broken',
@@ -27,14 +24,15 @@ module Sisimai
27
24
  'loops back to myself',
28
25
  'mail system configuration error',
29
26
  'queue file write error',
27
+ 'recipient deferred because there is no mdb',
30
28
  'remote server is misconfigured',
31
29
  'server configuration error',
32
30
  'service currently unavailable',
33
31
  'system config error',
34
32
  'temporary local problem',
35
33
  'timeout waiting for input',
36
- 'transaction failed',
37
- ]
34
+ 'transaction failed ',
35
+ ].freeze
38
36
 
39
37
  def text; return 'systemerror'; end
40
38
  def description; return 'Email returned due to system error on the remote host'; end
@@ -50,7 +48,7 @@ module Sisimai
50
48
  end
51
49
 
52
50
  # The bounce reason is system error or not
53
- # @param [Sisimai::Data] argvs Object to be detected the reason
51
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
54
52
  # @return [True,False] true: is system error
55
53
  # false: is not system error
56
54
  # @see http://www.ietf.org/rfc/rfc2822.txt
@@ -1,18 +1,17 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SystemFull checks the bounce reason is "systemfull" or
4
- # not. This class is called only Sisimai::Reason class.
3
+ # Sisimai::Reason::SystemFull checks the bounce reason is "systemfull" or not. This class is called
4
+ # only Sisimai::Reason class.
5
5
  #
6
- # This is the error that a destination mail server's disk (or spool) is full.
7
- # Sisimai will set C<systemfull> to the reason of email bounce if the value
8
- # of Status: field in a bounce email is "4.3.1" or "5.3.1".
6
+ # This is the error that a destination mail server's disk (or spool) is full. Sisimai will set
7
+ # systemfull to the reason of email bounce if the value of Status: field in a bounce email is
8
+ # "4.3.1" or "5.3.1".
9
9
  module SystemFull
10
- # Imported from p5-Sisimail/lib/Sisimai/Reason/SystemFull.pm
11
10
  class << self
12
11
  Index = [
13
12
  'mail system full',
14
13
  'requested mail action aborted: exceeded storage allocation', # MS Exchange
15
- ]
14
+ ].freeze
16
15
 
17
16
  def text; return 'systemfull'; end
18
17
  def description; return "Email rejected due to a destination mail server's disk is full"; end
@@ -28,7 +27,7 @@ module Sisimai
28
27
  end
29
28
 
30
29
  # The bounce reason is system full or not
31
- # @param [Sisimai::Data] argvs Object to be detected the reason
30
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
32
31
  # @return [True,False] true: is system full
33
32
  # false: is not system full
34
33
  # @see http://www.ietf.org/rfc/rfc2822.txt
@@ -1,16 +1,14 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::TooManyConn checks the bounce reason is "toomanyconn" or
4
- # not. This class is called only Sisimai::Reason class.
3
+ # Sisimai::Reason::TooManyConn checks the bounce reason is "toomanyconn" or not. This class is
4
+ # called only Sisimai::Reason class.
5
5
  #
6
- # This is the error that SMTP connection was rejected temporarily due to too
7
- # many concurrency connections to the remote server. This reason has added
8
- # in Sisimai 4.1.26 and does not exist in any version of bounceHammer.
6
+ # This is the error that SMTP connection was rejected temporarily due to too many concurrency
7
+ # connections to the remote server. This reason has added in Sisimai 4.1.26.
9
8
  #
10
9
  # <kijitora@example.ne.jp>: host mx02.example.ne.jp[192.0.1.20] said:
11
10
  # 452 4.3.2 Connection rate limit exceeded. (in reply to MAIL FROM command)
12
11
  module TooManyConn
13
- # Imported from p5-Sisimail/lib/Sisimai/Reason/TooManyConn.pm
14
12
  class << self
15
13
  Index = [
16
14
  'all available ips are at maximum connection limit', # SendGrid
@@ -27,7 +25,7 @@ module Sisimai
27
25
  'too many smtp sessions for this host', # Sendmail(daemon.c)
28
26
  'trop de connexions, ',
29
27
  'we have already made numerous attempts to deliver this message',
30
- ]
28
+ ].freeze
31
29
 
32
30
  def text; return 'toomanyconn'; end
33
31
  def description; return 'SMTP connection rejected temporarily due to too many concurrency connections to the remote host'; end
@@ -43,14 +41,14 @@ module Sisimai
43
41
  end
44
42
 
45
43
  # Rejected by domain or address filter ?
46
- # @param [Sisimai::Data] argvs Object to be detected the reason
44
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
47
45
  # @return [True,False] true: is filtered
48
46
  # false: is not filtered
49
47
  # @see http://www.ietf.org/rfc/rfc2822.txt
50
48
  def true(argvs)
51
- return true if argvs.reason == 'toomanyconn'
52
- return true if Sisimai::SMTP::Status.name(argvs.deliverystatus).to_s == 'toomanyconn'
53
- return true if match(argvs.diagnosticcode.downcase)
49
+ return true if argvs['reason'] == 'toomanyconn'
50
+ return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']).to_s == 'toomanyconn'
51
+ return true if match(argvs['diagnosticcode'].downcase)
54
52
  return false
55
53
  end
56
54
 
@@ -1,9 +1,8 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::Undefined is for only returning text and description.
4
- # This class is called only from Sisimai.reason method.
3
+ # Sisimai::Reason::Undefined is for only returning text and description. This class is called only
4
+ # from Sisimai.reason method.
5
5
  module Undefined
6
- # Imported from p5-Sisimail/lib/Sisimai/Reason/Undefined.pm
7
6
  class << self
8
7
  def text; return 'undefined'; end
9
8
  def description; return 'Sisimai could not detect an error reason'; end
@@ -1,21 +1,21 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::UserUnknown checks the bounce reason is "userunknown" or
4
- # not. This class is called only Sisimai::Reason class.
3
+ # Sisimai::Reason::UserUnknown checks the bounce reason is "userunknown" or not. This class is
4
+ # called only Sisimai::Reason class.
5
5
  #
6
- # This is the error that a local part (Left hand side of @ sign) of a recipient's
7
- # email address does not exist. In many case, a user has changed internet service
8
- # provider, or has quit company, or the local part is misspelled. Sisimai will
9
- # set "userunknown" to the reason of email bounce if the value of Status: field
10
- # in a bounce email is "5.1.1", or connection was refused at SMTP RCPT command,
11
- # or the contents of Diagnostic-Code: field represents that it is unknown user.
6
+ # This is the error that a local part (Left hand side of @ sign) of a recipient's email address
7
+ # does not exist. In many case, a user has changed internet service provider, or has quit company,
8
+ # or the local part is misspelled. Sisimai will set "userunknown" to the reason of email bounce
9
+ # if the value of Status: field in a bounce email is "5.1.1", or connection was refused at SMTP
10
+ # RCPT command, or the contents of Diagnostic-Code: field represents that it is unknown user.
12
11
  #
13
12
  # <kijitora@example.co.jp>: host mx01.example.co.jp[192.0.2.8] said:
14
13
  # 550 5.1.1 Address rejected kijitora@example.co.jp (in reply to
15
14
  # RCPT TO command)
16
15
  module UserUnknown
17
- # Imported from p5-Sisimail/lib/Sisimai/Reason/UserUnknown.pm
18
16
  class << self
17
+ require 'sisimai/string'
18
+
19
19
  PreMatches = %w[NoRelaying Blocked MailboxFull HasMoved Rejected NotAccept]
20
20
  ModulePath = {
21
21
  'Sisimai::Reason::NoRelaying' => 'sisimai/reason/norelaying',
@@ -25,135 +25,117 @@ module Sisimai
25
25
  'Sisimai::Reason::Rejected' => 'sisimai/reason/rejected',
26
26
  'Sisimai::Reason::NotAccept' => 'sisimai/reason/notaccept',
27
27
  }
28
- Regex = %r{(?>
29
- [#]5[.]1[.]1[ ]bad[ ]address
30
- |[<][^ ]+[>][ ]not[ ]found
31
- |[<][^ ]+[@][^ ]+[>][.][.][.][ ]blocked[ ]by[ ]
32
- |550[ ]address[ ]invalid
33
- |5[.]0[.]0[.][ ]mail[ ]rejected[.]
34
- |5[.]1[.]0[ ]address[ ]rejected[.]
35
- |account[ ][^ ]+[ ]does[ ]not[ ]exist[ ]at[ ]the[ ]organization
36
- |adresse[ ]d[ ]au[ ]moins[ ]un[ ]destinataire[ ]invalide[.][ ]invalid[ ]recipient[.][0-9a-z_]+41[68]
37
- |address[ ](?:does[ ]not[ ]exist|unknown)
38
- |address[ ](?:does[ ]not[ ]exist|not[ ]present[ ]in[ ]directory|unknown)
39
- |archived[ ]recipient
40
- |bad[-_ ]recipient
41
- |can[']t[ ]accept[ ]user
42
- |does[ ]not[ ]exist[.]
43
- |destination[ ](?:
44
- addresses[ ]were[ ]unknown
45
- |server[ ]rejected[ ]recipients
46
- )
47
- |email[ ]address[ ](?:does[ ]not[ ]exist|could[ ]not[ ]be[ ]found)
48
- |invalid[ ](?:
49
- address
50
- |mailbox:?
51
- |mailbox[ ]path
52
- |recipient
53
- )
54
- |is[ ]not[ ](?:
55
- a[ ]known[ ]user
56
- |a[ ]valid[ ]mailbox
57
- |an[ ]active[ ]address[ ]at[ ]this[ ]host
58
- )
59
- |mailbox[ ](?:
60
- [^ ]+[ ]does[ ]not[ ]exist
61
- |[^ ]+[@][^ ]+[ ]unavailable
62
- |does[ ]not[ ]exist
63
- |invalid
64
- |is[ ](?:inactive|unavailable)
65
- |not[ ](?:present|found)
66
- |unavailable
67
- )
68
- |nessun[ ]utente[ ]simile[ ]in[ ]questo[ ]indirizzo
69
- |no[ ](?:
70
- [ ][^ ]+[ ]in[ ]name[ ]directory
71
- |account[ ]by[ ]that[ ]name[ ]here
72
- |existe[ ](?:dicha[ ]persona|ese[ ]usuario[ ])
73
- |mail[ ]box[ ]available[ ]for[ ]this[ ]user
74
- |mailbox[ ](?:
75
- by[ ]that[ ]name[ ]is[ ]currently[ ]available
76
- |found
77
- )
78
- |matches[ ]to[ ]nameserver[ ]query
79
- |such[ ](?:
80
- address[ ]here
81
- |mailbox
82
- |person[ ]at[ ]this[ ]address
83
- |recipient
84
- |user(?:[ ]here)?
85
- )
86
- |thank[ ]you[ ]rejected:[ ]account[ ]unavailable:
87
- |valid[ ]recipients,[ ]bye
88
- )
89
- |non[- ]?existent[ ]user
90
- |not[ ](?:
91
- a[ ]valid[ ](?:recipient|user[ ]here)
92
- |a[ ]local[ ]address
93
- |email[ ]addresses
94
- )
95
- |rcpt[ ][<][^ ]+[>][ ]does[ ]not[ ]exist
96
- |recipient[ ]address[ ]rejected[.][ ][(]in[ ]reply[ ]to[ ]rcpt[ ]to[ ]command[)]
97
- |recipient[ ](?:
98
- [^ ]+[ ]was[ ]not[ ]found[ ]in
99
- |address[ ]rejected:[ ](?:
100
- access[ ]denied
101
- |invalid[ ]user
102
- |invalid-recipient
103
- |user[ ][^ ]+[ ]does[ ]not[ ]exist
104
- |user[ ]unknown[ ]in[ ][^ ]+[ ]table
105
- |unknown[ ]user
106
- )
107
- |does[ ]not[ ]exist(?:[ ]on[ ]this[ ]system)?
108
- |is[ ]not[ ]local
109
- |not[ ](?:exist|found|ok)
110
- |refuses[ ]to[ ]accept[ ]your[ ]mail
111
- |unknown
112
- )
113
- |requested[ ]action[ ]not[ ]taken:[ ]mailbox[ ]unavailable
114
- |resolver[.]adr[.]recipient notfound
115
- |said:[ ]550[-[ ]]5[.]1[.]1[ ][^ ]+[ ]user[ ]unknown[ ]
116
- |sorry,[ ](?:
117
- user[ ]unknown
118
- |badrcptto
119
- |no[ ]mailbox[ ]here[ ]by[ ]that[ ]name
120
- |your[ ]envelope[ ]recipient[ ]has[ ]been[ ]denied
121
- )
122
- |that[ ]domain[ ]or[ ]user[ ]isn't[ ]in[ ]my[ ]list[ ]of[ ]allowed[ ]rcpthosts
123
- |the[ ](?:
124
- email[ ]account[ ]that[ ]you[ ]tried[ ]to[ ]reach[ ]does[ ]not[ ]exist
125
- |following[ ]recipients[ ]was[ ]undeliverable
126
- |user[']s[ ]email[ ]name[ ]is[ ]not[ ]found
127
- )
128
- |there[ ]is[ ]no[ ]one[ ]at[ ]this[ ]address
129
- |this[ ](?:
130
- address[ ]no[ ]longer[ ]accepts[ ]mail
131
- |email[ ]address[ ]is[ ]wrong[ ]or[ ]no[ ]longer[ ]valid
132
- |recipient[ ]is[ ]in[ ]my[ ]badrecipientto[ ]list
133
- |recipient[ ]is[ ]not[ ]in[ ]my[ ]validrcptto[ ]list
134
- |spectator[ ]does[ ]not[ ]exist
135
- |user[ ]doesn[']?t[ ]have[ ]a[ ][^ ]+[ ]account
136
- )
137
- |unknown[ ](?:
138
- e[-]?mail[ ]address
139
- |local[- ]part
140
- |mailbox
141
- |recipient
142
- |user
143
- )
144
- |user[ ](?:
145
- [^ ]+[ ]was[ ]not[ ]found
146
- |[^ ]+[ ]does[ ]not[ ]exist
147
- |does[ ]not[ ]exist
148
- |missing[ ]home[ ]directory
149
- |not[ ](?:active|exist|found|known)
150
- |unknown
151
- )
152
- |utilisateur[ ]inconnu[ ]!
153
- |vdeliver:[ ]invalid[ ]or[ ]unknown[ ]virtual[ ]user
154
- |your[ ]envelope[ ]recipient[ ]is[ ]in[ ]my[ ]badrcptto[ ]list
155
- )
156
- }x
28
+ Index = [
29
+ '#5.1.1 bad address',
30
+ '550 address invalid',
31
+ '5.1.0 address rejected.',
32
+ 'address does not exist',
33
+ 'address not present in directory',
34
+ 'address unknown',
35
+ "can't accept user",
36
+ 'does not exist.',
37
+ 'destination addresses were unknown',
38
+ 'destination server rejected recipients',
39
+ 'email address does not exist',
40
+ 'email address could not be found',
41
+ 'invalid address',
42
+ 'invalid mailbox',
43
+ 'invalid mailbox path',
44
+ 'invalid recipient',
45
+ 'is not a known user',
46
+ 'is not a valid mailbox',
47
+ 'is not an active address at this host',
48
+ 'mailbox does not exist',
49
+ 'mailbox invalid',
50
+ 'mailbox is inactive',
51
+ 'mailbox is unavailable',
52
+ 'mailbox not present',
53
+ 'mailbox not found',
54
+ 'mailbox unavaiable',
55
+ 'nessun utente simile in questo indirizzo',
56
+ 'no account by that name here',
57
+ 'no existe dicha persona',
58
+ 'no existe ese usuario ',
59
+ 'no mail box available for this user',
60
+ 'no mailbox by that name is currently available',
61
+ 'no mailbox found',
62
+ 'no such address here',
63
+ 'no such mailbox',
64
+ 'no such person at this address',
65
+ 'no such recipient',
66
+
67
+ 'no such user',
68
+ 'no thank you rejected: account unavailable',
69
+ 'no valid recipients, bye',
70
+ 'not a valid recipient',
71
+ 'not a valid user here',
72
+ 'not a local address',
73
+ 'not email addresses',
74
+ 'recipient address rejected. (in reply to rcpt to command)',
75
+ 'recipient address rejected: access denied',
76
+ 'recipient address rejected: invalid user',
77
+ 'recipient address rejected: invalid-recipient',
78
+ 'recipient address rejected: unknown user',
79
+ 'recipient does not exist',
80
+ 'recipient is not local',
81
+ 'recipient not exist',
82
+ 'recipient not found',
83
+ 'recipient not ok',
84
+ 'recipient refuses to accept your mail',
85
+ 'recipient unknown',
86
+ 'requested action not taken: mailbox unavailable',
87
+ 'resolver.adr.recipient notfound',
88
+ 'sorry, user unknown',
89
+ 'sorry, badrcptto',
90
+ 'sorry, no mailbox here by that name',
91
+ 'sorry, your envelope recipient has been denied',
92
+ "that domain or user isn't in my list of allowed rcpthosts",
93
+ 'the email account that you tried to reach does not exist',
94
+ 'the following recipients was undeliverable',
95
+ "the user's email name is not found",
96
+ 'there is no one at this address',
97
+ 'this address no longer accepts mail',
98
+ 'this email address is wrong or no longer valid',
99
+ 'this recipient is in my badrecipientto list',
100
+ 'this recipient is not in my validrcptto list',
101
+ 'this spectator does not exist',
102
+ 'unknown mailbox',
103
+ 'unknown recipient',
104
+ 'unknown user',
105
+ 'user does not exist',
106
+ 'user missing home directory',
107
+ 'user not active',
108
+ 'user not exist',
109
+ 'user not found',
110
+ 'user not known',
111
+ 'user unknown',
112
+ 'utilisateur inconnu !',
113
+ 'vdeliver: invalid or unknown virtual user',
114
+ 'your envelope recipient is in my badrcptto list',
115
+ ].freeze
116
+ Pairs = [
117
+ ['<', '> not found'],
118
+ ['<', '>... blocked by '],
119
+ ['account ', ' does not exist at the organization'],
120
+ ['adresse d au moins un destinataire invalide. invalid recipient.', '416'],
121
+ ['adresse d au moins un destinataire invalide. invalid recipient.', '418'],
122
+ ['bad', 'recipient'],
123
+ ['mailbox ', 'does not exist'],
124
+ ['mailbox ', 'unavailable or access denied'],
125
+ ['no ', ' in name directory'],
126
+ ['non', 'existent user'],
127
+ ['rcpt <', ' does not exist'],
128
+ ['recipient ', ' was not found in'],
129
+ ['recipient address rejected: user ', ' does not exist'],
130
+ ['recipient address rejected: user unknown in ', ' table'],
131
+ ['said: 550-5.1.1 ', ' user unknown '],
132
+ ['said: 550 5.1.1 ', ' user unknown '],
133
+ ["this user doesn't have a ", " account"],
134
+ ['unknown e', 'mail address'],
135
+ ['unknown local', 'part'],
136
+ ['user ', ' was not found'],
137
+ ['user ', ' does not exist'],
138
+ ].freeze
157
139
 
158
140
  def text; return 'userunknown'; end
159
141
  def description; return "Email rejected due to a local part of a recipient's email address does not exist"; end
@@ -164,22 +146,23 @@ module Sisimai
164
146
  # true: Matched
165
147
  def match(argv1)
166
148
  return nil unless argv1
167
- return true if argv1 =~ Regex
149
+ return true if Index.any? { |a| argv1.include?(a) }
150
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
168
151
  return false
169
152
  end
170
153
 
171
154
  # Whether the address is "userunknown" or not
172
- # @param [Sisimai::Data] argvs Object to be detected the reason
155
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
173
156
  # @return [True,False] true: is unknown user
174
157
  # false: is not unknown user.
175
158
  # @see http://www.ietf.org/rfc/rfc2822.txt
176
159
  def true(argvs)
177
- return true if argvs.reason == 'userunknown'
160
+ return true if argvs['reason'] == 'userunknown'
178
161
 
179
- tempreason = Sisimai::SMTP::Status.name(argvs.deliverystatus) || ''
162
+ tempreason = Sisimai::SMTP::Status.name(argvs['deliverystatus']) || ''
180
163
  return false if tempreason == 'suspend'
181
164
 
182
- diagnostic = argvs.diagnosticcode.downcase
165
+ issuedcode = argvs['diagnosticcode'].downcase
183
166
  if tempreason == 'userunknown'
184
167
  # *.1.1 = 'Bad destination mailbox address'
185
168
  # Status: 5.1.1
@@ -198,17 +181,17 @@ module Sisimai
198
181
  next
199
182
  end
200
183
 
201
- next unless r.match(diagnostic)
184
+ next unless r.match(issuedcode)
202
185
  # Match with reason defined in Sisimai::Reason::* except UserUnknown.
203
186
  matchother = true
204
187
  break
205
188
  end
206
189
  return true unless matchother # Did not match with other message patterns
207
190
 
208
- elsif argvs.smtpcommand == 'RCPT'
191
+ elsif argvs['smtpcommand'] == 'RCPT'
209
192
  # When the SMTP command is not "RCPT", the session rejected by other
210
193
  # reason, maybe.
211
- return true if match(diagnostic)
194
+ return true if match(issuedcode)
212
195
  end
213
196
 
214
197
  return false
@@ -1,16 +1,15 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::Vacation is for only returning text and description.
4
- # This class is called only from Sisimai.reason method.
3
+ # Sisimai::Reason::Vacation is for only returning text and description. This class is called only
4
+ # from Sisimai.reason method.
5
5
  module Vacation
6
- # Imported from p5-Sisimail/lib/Sisimai/Reason/Vacation.pm
7
6
  class << self
8
7
  Index = [
9
8
  'i am away on vacation',
10
9
  'i am away until',
11
10
  'i am out of the office',
12
11
  'i will be traveling for work on',
13
- ]
12
+ ].freeze
14
13
 
15
14
  def text; return 'vacation'; end
16
15
  def description; return 'Email replied automatically due to a recipient is out of office'; end