sisimai 4.25.16-java → 5.0.0-java

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 +5 -5
  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 +42 -22
  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,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