sisimai 4.25.17 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) 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 +406 -407
  7. data/Developers.mk +5 -6
  8. data/Gemfile +1 -1
  9. data/Makefile +12 -12
  10. data/README-JA.md +142 -94
  11. data/README.md +282 -150
  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 +20 -16
  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 -325
  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 +13 -18
  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 -21
  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/mac/reported-from-nick4tech-san-01.eml +0 -6
  170. /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
  171. /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
  172. /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
  173. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
  174. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
  175. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
  176. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
  177. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
  178. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
@@ -1,93 +1,180 @@
1
1
  # http://www.ietf.org/rfc/rfc5321.txt
2
2
  # 4.2.1. Reply Code Severities and Theory
3
- # 2yz Positive Completion reply
4
- # 3yz Positive Intermediate reply
5
- # 4yz Transient Negative Completion reply
6
- # 5yz Permanent Negative Completion reply
7
3
  #
8
- # x0z Syntax: These replies refer to syntax errors, syntactically
9
- # correct commands that do not fit any functional category, and
10
- # unimplemented or superfluous commands.
11
- # x1z Information: These are replies to requests for information, such
12
- # as status or help.
13
- # x2z Connections: These are replies referring to the transmission
14
- # channel.
15
- # x3z Unspecified.
16
- # x4z Unspecified.
17
- # x5z Mail system: These replies indicate the status of the receiver
18
- # mail system vis-a-vis the requested transfer or other mail system
19
- # action.
4
+ # There are four values for the first digit of the reply code:
5
+ #
6
+ # 2yz Positive Completion reply
7
+ # The requested action has been successfully completed. A new request may be initiated.
8
+ #
9
+ # 3yz Positive Intermediate reply
10
+ # The command has been accepted, but the requested action is being held in abeyance, pending
11
+ # receipt of further information. The SMTP client should send another command specifying this
12
+ # information. This reply is used in command sequence groups (i.e., in DATA).
13
+ #
14
+ # 4yz Transient Negative Completion reply
15
+ # The command was not accepted, and the requested action did not occur. However, the error
16
+ # condition is temporary, and the action may be requested again. The sender should return to
17
+ # the beginning of the command sequence (if any). It is difficult to assign a meaning to
18
+ # "transient" when two different sites (receiver- and sender-SMTP agents) must agree on the
19
+ # interpretation. Each reply in this category might have a different time value, but the SMTP
20
+ # client SHOULD try again. A rule of thumb to determine whether a reply fits into the 4yz or
21
+ # the 5yz category (see below) is that replies are 4yz if they can be successful if repeated
22
+ # without any change in command form or in properties of the sender or receiver (that is, the
23
+ # command is repeated identically and the receiver does not put up a new implementation).
24
+ #
25
+ # 5yz Permanent Negative Completion reply
26
+ # The command was not accepted and the requested action did not occur. The SMTP client SHOULD
27
+ # NOT repeat the exact request (in the same sequence). Even some "permanent" error conditions
28
+ # can be corrected, so the human user may want to direct the SMTP client to reinitiate the
29
+ # command sequence by direct action at some point in the future (e.g., after the spelling has
30
+ # been changed, or the user has altered the account status).
20
31
  #
21
- # 4.2.3. Reply Codes in Numeric Order
22
- # 211 System status, or system help reply
23
- # 214 Help message (Information on how to use the receiver or the
24
- # meaning of a particular non-standard command; this reply is useful
25
- # only to the human user)
26
- # 220 <domain> Service ready
27
- # 221 <domain> Service closing transmission channel
28
- # 250 Requested mail action okay, completed
29
- # 251 User not local; will forward to <forward-path> (See Section 3.4)
30
- # 252 Cannot VRFY user, but will accept message and attempt delivery
31
- # (See Section 3.5.3)
32
- # 354 Start mail input; end with <CRLF>.<CRLF>
33
- # 421 <domain> Service not available, closing transmission channel
34
- # (This may be a reply to any command if the service knows it must
35
- # shut down)
36
- # 450 Requested mail action not taken: mailbox unavailable (e.g.,
37
- # mailbox busy or temporarily blocked for policy reasons)
38
- # 451 Requested action aborted: local error in processing
39
- # 452 Requested action not taken: insufficient system storage
40
- # 455 Server unable to accommodate parameters
41
- # 500 Syntax error, command unrecognized (This may include errors such
42
- # as command line too long)
43
- # 501 Syntax error in parameters or arguments
44
- # 502 Command not implemented (see Section 4.2.4)
45
- # 503 Bad sequence of commands
46
- # 504 Command parameter not implemented
47
- # 550 Requested action not taken: mailbox unavailable (e.g., mailbox
48
- # not found, no access, or command rejected for policy reasons)
49
- # 551 User not local; please try <forward-path> (See Section 3.4)
50
- # 552 Requested mail action aborted: exceeded storage allocation
51
- # 553 Requested action not taken: mailbox name not allowed (e.g.,
52
- # mailbox syntax incorrect)
53
- # 554 Transaction failed (Or, in the case of a connection-opening
54
- # response, "No SMTP service here")
55
- # 555 MAIL FROM/RCPT TO parameters not recognized or not implemented
32
+ # The second digit encodes responses in specific categories:
56
33
  #
34
+ # x0z Syntax: These replies refer to syntax errors, syntactically correct commands that do
35
+ # not fit any functional category, and unimplemented or superfluous commands.
36
+ # x1z Information: These are replies to requests for information, such as status or help.
37
+ # x2z Connections: These are replies referring to the transmission channel.
38
+ # x3z Unspecified.
39
+ # x4z Unspecified.
40
+ # x5z Mail system: These replies indicate the status of the receiver mail system vis-a-vis
41
+ # the requested transfer or other mail system action.
42
+
57
43
  module Sisimai
58
44
  module SMTP
59
- # Sisimai::SMTP::Reply is utilities for getting SMTP Reply Code value from
60
- # error message text.
45
+ # Sisimai::SMTP::Reply is utilities for getting SMTP Reply Code value from error message text.
61
46
  module Reply
62
- # Imported from p5-Sisimail/lib/Sisimai/SMTP/Reply.pm
63
47
  class << self
64
- IP4Re = %r{\b
65
- (?:\d|[01]?\d\d|2[0-4]\d|25[0-5])[.]
66
- (?:\d|[01]?\d\d|2[0-4]\d|25[0-5])[.]
67
- (?:\d|[01]?\d\d|2[0-4]\d|25[0-5])[.]
68
- (?:\d|[01]?\d\d|2[0-4]\d|25[0-5])
69
- \b}x
48
+ ReplyCode2 = [
49
+ # http://www.ietf.org/rfc/rfc5321.txt
50
+ # 211 System status, or system help reply
51
+ # 214 Help message (Information on how to use the receiver or the meaning of a particular
52
+ # non-standard command; this reply is useful only to the human user)
53
+ # 220 <domain> Service ready
54
+ # 221 <domain> Service closing transmission channel
55
+ # 235 Authentication successful (See RFC2554)
56
+ # 250 Requested mail action okay, completed
57
+ # 251 User not local; will forward to <forward-path> (See Section 3.4)
58
+ # 252 Cannot VRFY user, but will accept message and attempt delivery (See Section 3.5.3)
59
+ # 253 OK, <n> pending messages for node <domain> started (See RFC1985)
60
+ # 354 Start mail input; end with <CRLF>.<CRLF>
61
+ '211', '214', '220', '221', '235', '250', '251', '252', '253', '354'
62
+ ].freeze
63
+ ReplyCode4 = [
64
+ # 421 <domain> Service not available, closing transmission channel (This may be a reply
65
+ # to any command if the service knows it must shut down)
66
+ # 422 (See RFC5248)
67
+ # 430 (See RFC5248)
68
+ # 432 A password transition is needed (See RFC4954)
69
+ # 450 Requested mail action not taken: mailbox unavailable (e.g., mailbox busy or temporarily
70
+ # blocked for policy reasons)
71
+ # 451 Requested action aborted: local error in processing
72
+ # 452 Requested action not taken: insufficient system storage
73
+ # 453 You have no mail (See RFC2645)
74
+ # 454 Temporary authentication failure (See RFC4954)
75
+ # 455 Server unable to accommodate parameters
76
+ # 456 please retry immediately the message over IPv4 because it fails SPF and DKIM (See
77
+ # https://datatracker.ietf.org/doc/html/draft-martin-smtp-ipv6-to-ipv4-fallback-00
78
+ # 458 Unable to queue messages for node <domain> (See RFC1985)
79
+ # 459 Node <domain> not allowed: <reason> (See RFC51985)
80
+ '421', '450', '451', '452', '422', '430', '432', '453', '454', '455', '456', '458', '459'
81
+ ].freeze
82
+ ReplyCode5 = [
83
+ # 500 Syntax error, command unrecognized (This may include errors such as command line too long)
84
+ # 501 Syntax error in parameters or arguments
85
+ # 502 Command not implemented (see Section 4.2.4)
86
+ # 503 Bad sequence of commands
87
+ # 504 Command parameter not implemented
88
+ # 520 Please use the correct QHLO ID (See https://datatracker.ietf.org/doc/id/draft-fanf-smtp-quickstart-01.txt)
89
+ # 521 Host does not accept mail (See RFC7504)
90
+ # 523 Encryption Needed (See RFC5248)
91
+ # 524 (See RFC5248)
92
+ # 525 User Account Disabled (See RFC5248)
93
+ # 530 Authentication required (See RFC4954)
94
+ # 533 (See RFC5248)
95
+ # 534 Authentication mechanism is too weak (See RFC4954)
96
+ # 535 Authentication credentials invalid (See RFC4954)
97
+ # 538 Encryption required for requested authentication mechanism (See RFC4954)
98
+ # 550 Requested action not taken: mailbox unavailable (e.g., mailbox not found, no access, or
99
+ # command rejected for policy reasons)
100
+ # 551 User not local; please try <forward-path> (See Section 3.4)
101
+ # 552 Requested mail action aborted: exceeded storage allocation
102
+ # 553 Requested action not taken: mailbox name not allowed (e.g., mailbox syntax incorrect)
103
+ # 554 Transaction failed (Or, in the case of a connection-opening response, "No SMTP service here")
104
+ # 555 MAIL FROM/RCPT TO parameters not recognized or not implemented
105
+ # 556 Domain does not accept mail (See RFC7504)
106
+ '550', '552', '553', '551', '521', '525', '502', '520', '523', '524', '530', '533', '534',
107
+ '535', '538', '551', '555', '556', '554', '500', '501', '502', '503', '504',
108
+ ].freeze
109
+ CodeOfSMTP = { '2' => ReplyCode2, '4' => ReplyCode4, '5' => ReplyCode5 }.freeze
110
+
111
+ # Check whether a reply code is a valid code or not
112
+ # @param [String] argv1 Reply Code(DSN)
113
+ # @return [Boolean] 0 = Invalid reply code, 1 = Valid reply code
114
+ # @see code
115
+ # @since v5.0.0
116
+ def test(argv1 = '')
117
+ return nil if argv1.empty?
118
+
119
+ reply = argv1.to_i
120
+ first = (reply / 100).to_i
121
+
122
+ return false if reply < 200
123
+ return false if reply > 599
124
+ return false if reply % 100 > 59
125
+
126
+ if first == 2
127
+ # 2yz
128
+ return false if reply < 211
129
+ return false if reply > 252
130
+ return false if reply > 221 && reply < 250
131
+ return true
132
+ end
133
+
134
+ if first == 3
135
+ # 3yz
136
+ return false unless reply == 354
137
+ return true
138
+ end
139
+
140
+ return true
141
+ end
70
142
 
71
143
  # Get SMTP Reply Code from the given string
72
144
  # @param [String] argv1 String including SMTP Reply Code like 550
73
- # @return [String] SMTP Reply Code or Nil if the first argument
74
- # did not include SMTP Reply Code value
75
- def find(argv1 = nil)
76
- return nil unless argv1
77
- return nil if argv1.empty?
145
+ # @param [String] argv2 Status code like 5.1.1 or 2 or 4 or 5
146
+ # @return [String] SMTP Reply Code
147
+ # [Nil] The first argument did not include SMTP Reply Code value
148
+ def find(argv1 = '', argv2 = '0')
149
+ return nil if argv1.to_s.size < 3
78
150
  return nil if argv1.upcase.include?('X-UNIX')
79
151
 
80
- # Convert found IPv4 addresses to '***.***.***.***' to avoid that
81
- # the following code detects an octet of the IPv4 adress as an SMTP
82
- # reply code.
83
- argv1 = argv1.gsub(/#{IP4Re}/, '***.***.***.***') if argv1 =~ IP4Re
152
+ statuscode = argv2[0, 1]
153
+ replycodes = if statuscode == '5' || statuscode == '4' || statuscode == '2'
154
+ CodeOfSMTP[statuscode]
155
+ else
156
+ [*CodeOfSMTP['5'], *CodeOfSMTP['4'], *CodeOfSMTP['2']]
157
+ end
158
+ esmtperror = ' ' + argv1 + ' '
159
+ esmtpreply = '' # SMTP Reply Code
160
+ replyindex = 0 # A position of SMTP reply code found by the index()
161
+ formerchar = 0 # a character that is one character before the SMTP reply code
162
+ latterchar = 0 # a character that is one character after the SMTP reply code
84
163
 
85
- if cv = argv1.match(/\b([45][0-7][0-9])\b/) || argv1.match(/\b(25[0-3])\b/)
86
- # 550, 447, or 250
87
- return cv[1]
88
- else
89
- return nil
164
+ replycodes.each do |e|
165
+ # Try to find an SMTP Reply Code from the given string
166
+ replyindex = esmtperror.index(e); next unless replyindex
167
+ formerchar = esmtperror[replyindex - 1, 1].ord || 0
168
+ latterchar = esmtperror[replyindex + 3, 1].ord || 0
169
+
170
+ next if formerchar > 45 && formerchar < 58
171
+ next if latterchar > 45 && latterchar < 58
172
+ esmtpreply = e
173
+ break
90
174
  end
175
+
176
+ return nil if esmtpreply.empty?
177
+ return esmtpreply
91
178
  end
92
179
 
93
180
  end