sisimai 5.1.0-java → 5.2.0-java
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.
- checksums.yaml +4 -4
- data/.github/workflows/rake-test.yml +1 -1
- data/ChangeLog.md +102 -0
- data/Makefile +4 -2
- data/README-JA.md +23 -16
- data/README.md +22 -15
- data/lib/sisimai/arf.rb +121 -210
- data/lib/sisimai/fact.rb +208 -158
- data/lib/sisimai/lda.rb +98 -0
- data/lib/sisimai/lhost/activehunter.rb +1 -1
- data/lib/sisimai/lhost/amazonses.rb +185 -301
- data/lib/sisimai/lhost/apachejames.rb +48 -51
- data/lib/sisimai/lhost/biglobe.rb +1 -2
- data/lib/sisimai/lhost/courier.rb +10 -8
- data/lib/sisimai/lhost/domino.rb +25 -25
- data/lib/sisimai/lhost/dragonfly.rb +3 -4
- data/lib/sisimai/lhost/einsundeins.rb +3 -4
- data/lib/sisimai/lhost/exchange2003.rb +6 -8
- data/lib/sisimai/lhost/exchange2007.rb +111 -101
- data/lib/sisimai/lhost/exim.rb +232 -242
- data/lib/sisimai/lhost/ezweb.rb +43 -51
- data/lib/sisimai/lhost/fml.rb +2 -3
- data/lib/sisimai/lhost/gmail.rb +32 -28
- data/lib/sisimai/lhost/gmx.rb +4 -16
- data/lib/sisimai/lhost/googlegroups.rb +9 -8
- data/lib/sisimai/lhost/googleworkspace.rb +94 -0
- data/lib/sisimai/lhost/imailserver.rb +7 -16
- data/lib/sisimai/lhost/interscanmss.rb +1 -1
- data/lib/sisimai/lhost/kddi.rb +3 -4
- data/lib/sisimai/lhost/mailfoundry.rb +2 -5
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +1 -2
- data/lib/sisimai/lhost/messagingserver.rb +14 -13
- data/lib/sisimai/lhost/mfilter.rb +4 -3
- data/lib/sisimai/lhost/notes.rb +2 -4
- data/lib/sisimai/lhost/opensmtpd.rb +2 -2
- data/lib/sisimai/lhost/postfix.rb +25 -27
- data/lib/sisimai/lhost/qmail.rb +130 -106
- data/lib/sisimai/lhost/sendmail.rb +19 -18
- data/lib/sisimai/lhost/v5sendmail.rb +88 -60
- data/lib/sisimai/lhost/verizon.rb +2 -2
- data/lib/sisimai/lhost/x1.rb +1 -1
- data/lib/sisimai/lhost/x2.rb +1 -2
- data/lib/sisimai/lhost/x3.rb +2 -2
- data/lib/sisimai/lhost/x6.rb +1 -1
- data/lib/sisimai/lhost/zoho.rb +2 -2
- data/lib/sisimai/lhost.rb +18 -21
- data/lib/sisimai/message.rb +93 -146
- data/lib/sisimai/order.rb +21 -77
- data/lib/sisimai/reason/authfailure.rb +1 -4
- data/lib/sisimai/reason/badreputation.rb +2 -2
- data/lib/sisimai/reason/blocked.rb +7 -10
- data/lib/sisimai/reason/contenterror.rb +7 -1
- data/lib/sisimai/reason/exceedlimit.rb +1 -4
- data/lib/sisimai/reason/failedstarttls.rb +42 -0
- data/lib/sisimai/reason/filtered.rb +5 -4
- data/lib/sisimai/reason/hasmoved.rb +1 -2
- data/lib/sisimai/reason/hostunknown.rb +3 -3
- data/lib/sisimai/reason/mailboxfull.rb +2 -4
- data/lib/sisimai/reason/mailererror.rb +1 -2
- data/lib/sisimai/reason/mesgtoobig.rb +2 -4
- data/lib/sisimai/reason/norelaying.rb +2 -3
- data/lib/sisimai/reason/notaccept.rb +2 -3
- data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
- data/lib/sisimai/reason/rejected.rb +1 -1
- data/lib/sisimai/reason/requireptr.rb +2 -2
- data/lib/sisimai/reason/securityerror.rb +1 -3
- data/lib/sisimai/reason/spamdetected.rb +6 -8
- data/lib/sisimai/reason/speeding.rb +1 -2
- data/lib/sisimai/reason/suppressed.rb +36 -0
- data/lib/sisimai/reason/suspend.rb +1 -3
- data/lib/sisimai/reason/systemerror.rb +5 -0
- data/lib/sisimai/reason/toomanyconn.rb +1 -2
- data/lib/sisimai/reason/userunknown.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +5 -6
- data/lib/sisimai/reason.rb +77 -73
- data/lib/sisimai/rfc1123.rb +152 -0
- data/lib/sisimai/rfc1894.rb +102 -62
- data/lib/sisimai/rfc2045.rb +2 -1
- data/lib/sisimai/rfc3464/thirdparty.rb +102 -0
- data/lib/sisimai/rfc3464.rb +222 -343
- data/lib/sisimai/rfc3834.rb +1 -1
- data/lib/sisimai/rfc5322.rb +7 -17
- data/lib/sisimai/rfc791.rb +69 -0
- data/lib/sisimai/rhost/aol.rb +36 -0
- data/lib/sisimai/rhost/apple.rb +5 -2
- data/lib/sisimai/rhost/cox.rb +3 -2
- data/lib/sisimai/rhost/facebook.rb +100 -0
- data/lib/sisimai/rhost/franceptt.rb +3 -2
- data/lib/sisimai/rhost/godaddy.rb +3 -2
- data/lib/sisimai/rhost/google.rb +19 -17
- data/lib/sisimai/rhost/gsuite.rb +42 -0
- data/lib/sisimai/rhost/iua.rb +3 -3
- data/lib/sisimai/rhost/kddi.rb +3 -2
- data/lib/sisimai/rhost/messagelabs.rb +37 -0
- data/lib/sisimai/rhost/microsoft.rb +56 -49
- data/lib/sisimai/rhost/mimecast.rb +29 -27
- data/lib/sisimai/rhost/nttdocomo.rb +4 -3
- data/lib/sisimai/rhost/outlook.rb +36 -0
- data/lib/sisimai/rhost/spectrum.rb +3 -2
- data/lib/sisimai/rhost/tencent.rb +3 -2
- data/lib/sisimai/rhost/yahooinc.rb +4 -3
- data/lib/sisimai/rhost.rb +69 -39
- data/lib/sisimai/smtp/command.rb +31 -21
- data/lib/sisimai/smtp/failure.rb +103 -0
- data/lib/sisimai/smtp/reply.rb +29 -25
- data/lib/sisimai/smtp/status.rb +36 -19
- data/lib/sisimai/smtp/transcript.rb +15 -15
- data/lib/sisimai/string.rb +0 -46
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
- data/set-of-emails/maildir/bsd/{lhost-aol-03.eml → rhost-aol-03.eml} +1264 -1264
- data/set-of-emails/maildir/bsd/{lhost-aol-04.eml → rhost-aol-04.eml} +1260 -1260
- data/set-of-emails/maildir/bsd/{lhost-aol-05.eml → rhost-aol-05.eml} +105 -105
- data/set-of-emails/maildir/bsd/{lhost-aol-06.eml → rhost-aol-06.eml} +105 -105
- data/set-of-emails/maildir/bsd/rhost-gsuite-01.eml +189 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-02.eml +180 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-03.eml +251 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-04.eml +211 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-05.eml +226 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-06.eml +257 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-07.eml +289 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-08.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-09.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-10.eml +254 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-11.eml +228 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-12.eml +271 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-13.eml +261 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-14.eml +273 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/{lhost-messagelabs-01.eml → rhost-messagelabs-01.eml} +93 -93
- data/set-of-emails/maildir/bsd/rhost-outlook-01.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-02.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-03.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-04.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-06.eml +75 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-07.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-08.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-09.eml +56 -0
- data/set-of-emails/maildir/tmp/arf-22.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-23.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-24.eml +50 -0
- data/set-of-emails/maildir/tmp/lhost-exim-07.eml +28 -0
- metadata +73 -56
- data/lib/sisimai/lhost/amavis.rb +0 -163
- data/lib/sisimai/lhost/amazonworkmail.rb +0 -127
- data/lib/sisimai/lhost/aol.rb +0 -125
- data/lib/sisimai/lhost/barracuda.rb +0 -92
- data/lib/sisimai/lhost/bigfoot.rb +0 -125
- data/lib/sisimai/lhost/facebook.rb +0 -188
- data/lib/sisimai/lhost/gsuite.rb +0 -194
- data/lib/sisimai/lhost/mailru.rb +0 -214
- data/lib/sisimai/lhost/mcafee.rb +0 -109
- data/lib/sisimai/lhost/messagelabs.rb +0 -120
- data/lib/sisimai/lhost/mxlogic.rb +0 -198
- data/lib/sisimai/lhost/office365.rb +0 -252
- data/lib/sisimai/lhost/outlook.rb +0 -129
- data/lib/sisimai/lhost/powermta.rb +0 -118
- data/lib/sisimai/lhost/receivingses.rb +0 -126
- data/lib/sisimai/lhost/sendgrid.rb +0 -150
- data/lib/sisimai/lhost/surfcontrol.rb +0 -105
- data/lib/sisimai/lhost/x4.rb +0 -269
- data/lib/sisimai/lhost/x5.rb +0 -112
- data/lib/sisimai/lhost/yahoo.rb +0 -102
- data/lib/sisimai/lhost/yandex.rb +0 -118
- data/lib/sisimai/mda.rb +0 -121
- data/lib/sisimai/smtp/error.rb +0 -119
- /data/set-of-emails/maildir/bsd/{lhost-googlegroups-15.eml → lhost-googleworkspace-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-x4-08.eml → lhost-x2-06.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-01.eml → rfc3464-51.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-03.eml → rfc3464-52.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-04.eml → rfc3464-53.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-05.eml → rfc3464-54.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-06.eml → rfc3464-55.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-07.eml → rfc3464-56.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-08.eml → rfc3464-57.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-09.eml → rfc3464-58.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-10.eml → rfc3464-59.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-11.eml → rfc3464-60.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-12.eml → rfc3464-61.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-13.eml → rfc3464-62.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-14.eml → rfc3464-63.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-15.eml → rfc3464-64.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-02.eml → rfc3464-65.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-01.eml → rhost-aol-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-02.eml → rhost-aol-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-03.eml → rhost-facebook-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-04.eml → rhost-facebook-04.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-02.eml → rhost-messagelabs-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-03.eml → rhost-messagelabs-03.eml} +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-37.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-38.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-39.eml +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
module Rhost
|
3
3
|
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
|
4
|
-
# of
|
4
|
+
# of find() method when the value of "rhost" of the object is *.protection.outlook.com. This class
|
5
5
|
# is called only Sisimai::Fact class.
|
6
6
|
#
|
7
7
|
# https://technet.microsoft.com/en-us/library/bb232118
|
@@ -16,43 +16,10 @@ module Sisimai
|
|
16
16
|
# - The sending message sent over IPv6 must pass either SPF or DKIM.
|
17
17
|
['4.7.26', 0, 0, 'must pass either spf or dkim validation, this message is not signed'],
|
18
18
|
|
19
|
-
# - Records are DNSSEC authentic, but one or multiple of these scenarios occurred:
|
20
|
-
# - The destination mail server's certificate doesn't match with what is expected per
|
21
|
-
# the authentic TLSA record.
|
22
|
-
# - Authentic TLSA record is misconfigured.
|
23
|
-
# - Destination domain is being attacked.
|
24
|
-
# - Any other DANE failure.
|
25
|
-
# - This message usually indicates an issue on the destination email server. Check the
|
26
|
-
# validity of recipient address and determine if the destination server is configured
|
27
|
-
# correctly to receive messages.
|
28
|
-
# - For more information about DANE, see: https://datatracker.ietf.org/doc/html/rfc7671
|
29
|
-
['4.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
|
30
|
-
['5.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
|
31
|
-
|
32
|
-
# - The destination domain indicated it was DNSSEC-authentic, but Exchange Online was
|
33
|
-
# not able to verify it as DNSSEC-authentic.
|
34
|
-
['4.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
|
35
|
-
['5.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
|
36
|
-
|
37
|
-
# - This happens when the presented certificate identities (CN and SAN) of a destina-
|
38
|
-
# tion SMTP target host don't match any of the domains or MX host.
|
39
|
-
# - This message usually indicates an issue on the destination email server. Check the
|
40
|
-
# validity of recipient address and determine if the destination server is configured
|
41
|
-
# correctly to receive messages. For more information, see How SMTP DNS-based Authen-
|
42
|
-
# tication of Named Entities (DANE) works to secure email communications.
|
43
|
-
['4.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
|
44
|
-
['5.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
|
45
|
-
|
46
19
|
# - The destination email system uses SPF to validate inbound mail, and there's a prob-
|
47
20
|
# lem with your SPF configuration.
|
48
21
|
['5.7.23', 0, 0, 'the message was rejected because of sender policy framework violation'],
|
49
22
|
|
50
|
-
# - DNSSEC checks have passed, yet upon establishing the connection the destination
|
51
|
-
# mail server provides a certificate that is expired.
|
52
|
-
# - A valid X.509 certificate that isn't expired must be presented. X.509 certificates
|
53
|
-
# must be renewed after their expiration, commonly annually.
|
54
|
-
['5.7.322', 0, 0, "certificate-expired: destination mail server's certificate is expired"],
|
55
|
-
|
56
23
|
# - Access denied, sending domain [$SenderDomain] does not pass DMARC verification
|
57
24
|
# - The sender's domain in the 5322.From address doesn't pass DMARC.
|
58
25
|
['5.7.509', 0, 0, 'does not pass dmarc verification'],
|
@@ -136,7 +103,6 @@ module Sisimai
|
|
136
103
|
|
137
104
|
# Previous versions of Exchange Server ------------------------------------------------
|
138
105
|
['5.5.4', 0, 0, 'invalid domain name'],
|
139
|
-
['5.7.51', 0, 0, 'restrictdomainstoipaddresses or restrictdomainstocertificate'],
|
140
106
|
|
141
107
|
# Undocumented error messages ---------------------------------------------------------
|
142
108
|
# - 550 5.7.1 Unfortunately, messages from [10.0.2.5] weren't sent. Please contact your
|
@@ -216,6 +182,53 @@ module Sisimai
|
|
216
182
|
# couldn't be delivered to the original sender.
|
217
183
|
['5.4.300', 0, 0, 'message expired'],
|
218
184
|
],
|
185
|
+
'failedstarttls' => [
|
186
|
+
# Exchange Online ---------------------------------------------------------------------
|
187
|
+
# - DNSSEC checks have passed, yet upon connection, destination mail server doesn't re-
|
188
|
+
# spond to the STARTTLS command. The destination server responds to the STARTTLS com-
|
189
|
+
# mand, but the TLS handshake fails.
|
190
|
+
# - This message usually indicates an issue on the destination email server. Check the
|
191
|
+
# validity of the recipient address. Determine if the destination server is configur-
|
192
|
+
# ed correctly to receive the messages.
|
193
|
+
['4.4.317', 0, 0, 'starttls is required to send mail'],
|
194
|
+
['5.4.317', 0, 0, 'starttls is required to send mail'],
|
195
|
+
|
196
|
+
# - DNSSEC checks have passed, yet upon establishing the connection the destination
|
197
|
+
# mail server provides a certificate that is expired.
|
198
|
+
# - A valid X.509 certificate that isn't expired must be presented. X.509 certificates
|
199
|
+
# must be renewed after their expiration, commonly annually.
|
200
|
+
['5.7.51', 0, 0, 'restrictdomainstoipaddresses or restrictdomainstocertificate'],
|
201
|
+
['4.7.321', 0, 0, 'starttls-not-supported: destination mail server must support tls to receive mail'],
|
202
|
+
['5.7.321', 0, 0, 'starttls-not-supported: destination mail server must support tls to receive mail'],
|
203
|
+
['5.7.322', 0, 0, "certificate-expired: destination mail server's certificate is expired"],
|
204
|
+
|
205
|
+
# - Records are DNSSEC authentic, but one or multiple of these scenarios occurred:
|
206
|
+
# - The destination mail server's certificate doesn't match with what is expected per
|
207
|
+
# the authentic TLSA record.
|
208
|
+
# - Authentic TLSA record is misconfigured.
|
209
|
+
# - Destination domain is being attacked.
|
210
|
+
# - Any other DANE failure.
|
211
|
+
# - This message usually indicates an issue on the destination email server. Check the
|
212
|
+
# validity of recipient address and determine if the destination server is configured
|
213
|
+
# correctly to receive messages.
|
214
|
+
# - For more information about DANE, see: https://datatracker.ietf.org/doc/html/rfc7671
|
215
|
+
['4.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
|
216
|
+
['5.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
|
217
|
+
|
218
|
+
# - The destination domain indicated it was DNSSEC-authentic, but Exchange Online was
|
219
|
+
# not able to verify it as DNSSEC-authentic.
|
220
|
+
['4.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
|
221
|
+
['5.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
|
222
|
+
|
223
|
+
# - This happens when the presented certificate identities (CN and SAN) of a destina-
|
224
|
+
# tion SMTP target host don't match any of the domains or MX host.
|
225
|
+
# - This message usually indicates an issue on the destination email server. Check the
|
226
|
+
# validity of recipient address and determine if the destination server is configured
|
227
|
+
# correctly to receive messages. For more information, see How SMTP DNS-based Authen-
|
228
|
+
# tication of Named Entities (DANE) works to secure email communications.
|
229
|
+
['4.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
|
230
|
+
['5.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
|
231
|
+
],
|
219
232
|
'mailboxfull' => [
|
220
233
|
# Exchange Server 2019 ----------------------------------------------------------------
|
221
234
|
# - The recipient's mailbox has exceeded its storage quota and is no longer able to ac-
|
@@ -328,6 +341,7 @@ module Sisimai
|
|
328
341
|
],
|
329
342
|
'notaccept' => [
|
330
343
|
['4.3.2', 0, 0, 'system not accepting network messages'],
|
344
|
+
['4.4.4', 0, 0, 'hosted tenant which has no mail-enabled subscriptions'],
|
331
345
|
|
332
346
|
# Exchange Server 2019 ----------------------------------------------------------------
|
333
347
|
# - You're using the ABP Routing agent, and the recipient isn't a member of the global
|
@@ -448,19 +462,6 @@ module Sisimai
|
|
448
462
|
['5.7.3', 0, 0, 'cannot achieve exchange server authentication'],
|
449
463
|
['5.7.3', 0, 0, 'not authorized'],
|
450
464
|
|
451
|
-
# Exchange Online ---------------------------------------------------------------------
|
452
|
-
# - DNSSEC checks have passed, yet upon connection, destination mail server doesn't re-
|
453
|
-
# spond to the STARTTLS command. The destination server responds to the STARTTLS com-
|
454
|
-
# mand, but the TLS handshake fails.
|
455
|
-
# - This message usually indicates an issue on the destination email server. Check the
|
456
|
-
# validity of the recipient address. Determine if the destination server is configur-
|
457
|
-
# ed correctly to receive the messages.
|
458
|
-
['4.4.317', 0, 0, 'starttls is required to send mail'],
|
459
|
-
['5.4.317', 0, 0, 'starttls is required to send mail'],
|
460
|
-
|
461
|
-
['4.7.321', 0, 0, 'starttls-not-supported: destination mail server must support tls to receive mail'],
|
462
|
-
['5.7.321', 0, 0, 'starttls-not-supported: destination mail server must support tls to receive mail'],
|
463
|
-
|
464
465
|
# - The sending email system didn't authenticate with the receiving email system. The
|
465
466
|
# receiving email system requires authentication before message submission.
|
466
467
|
# - This error occurs when the receiving server must be authenticated before message
|
@@ -644,6 +645,12 @@ module Sisimai
|
|
644
645
|
# envelope recipients into smaller chunks (chunking) and resend the message.
|
645
646
|
['4.5.3', 0, 0, 'too many recipients'],
|
646
647
|
|
648
|
+
# - 451 4.7.652 The mail server [192.0.2.251] has exceeded the maximum number of
|
649
|
+
# connections. (S3115) [Name=Protocol Filter Agent][AGT=PFA][MxId=11BA9B3FA168ABBF]
|
650
|
+
# [BN3PEPF0000B370.namprd21.prod.outlook.com 2025-02-20T14:30:32.425Z 08DD4D9FD5AFF45C]
|
651
|
+
# (in reply to MAIL FROM command))
|
652
|
+
["4.7.652", 0, 0, "has exceeded the maximum number of connections"],
|
653
|
+
|
647
654
|
# Previous versions of Exchange Server ------------------------------------------------
|
648
655
|
['5.2.122', 0, 0, 'the recipient has exceeded their limit for'],
|
649
656
|
],
|
@@ -714,7 +721,7 @@ module Sisimai
|
|
714
721
|
# @param [Sisimai::Fact] argvs Decoded email object
|
715
722
|
# @return [String] The bounce reason for Exchange Online
|
716
723
|
# @since v4.17.2
|
717
|
-
def
|
724
|
+
def find(argvs)
|
718
725
|
return '' if argvs['deliverystatus'].empty?
|
719
726
|
return '' unless Sisimai::SMTP::Status.test(argvs['deliverystatus'])
|
720
727
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
module Rhost
|
3
3
|
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argu-
|
4
|
-
# ment of
|
4
|
+
# ment of find() method when the value of "rhost" of the object is "*.mimecast.com". This class
|
5
5
|
# is called only Sisimai::Fact class.
|
6
6
|
module Mimecast
|
7
7
|
class << self
|
@@ -76,6 +76,32 @@ module Sisimai
|
|
76
76
|
# Discontinue journaling old messages past the expiry threshold.
|
77
77
|
[550, 'Journal messages past the expiration'],
|
78
78
|
],
|
79
|
+
'failedstarttls' => [
|
80
|
+
# - This email has been sent using SMTP, but TLS is required by policy.
|
81
|
+
# - Delete or change the Secure Receipt or Secure Delivery policy enforcing TLS.
|
82
|
+
# Alternatively, ensure the certificates on the mail server haven't expired. If using
|
83
|
+
# a proxy server, ensure it isn't intercepting the traffic and modifying encryption
|
84
|
+
# parameters.
|
85
|
+
[553, 'this route requires encryption (tls)'],
|
86
|
+
|
87
|
+
# - A TLS connection has been attempted using a TLS version that is lower than TLS 1.2.
|
88
|
+
# - Delete or change the Secure Receipt or Secure Delivery policy enforcing TLS.
|
89
|
+
# Alternatively, ensure the mail server attempting to connect is using the appropri-
|
90
|
+
# ate version of TLS.
|
91
|
+
[553, 'this route requires tls version 1.2 or greater'],
|
92
|
+
|
93
|
+
# - A secure connection was attempted using ciphers that do not meet the configured ci-
|
94
|
+
# pher strength.
|
95
|
+
# - Delete or change the Secure Receipt or Secure Delivery policy enforcing TLS. Alter-
|
96
|
+
# natively, ensure the certificates on the mail server haven't expired. If using a
|
97
|
+
# proxy server, ensure it isn't intercepting the traffic and modifying encryption
|
98
|
+
# parameters.
|
99
|
+
[553, 'this route requires high-strength ciphers'],
|
100
|
+
|
101
|
+
# - Validation on your umbrella account's domain name does not conform to your DNS.
|
102
|
+
# - Check you DNS has the required umbrella accounts listed as comma-separated values.
|
103
|
+
[554, 'configuration is invalid for this certificate'],
|
104
|
+
],
|
79
105
|
'mesgtoobig' => [
|
80
106
|
# - The email size either exceeds an Email Size Limit policy or is larger than the
|
81
107
|
# Mimecast service limit. The default is 100 MB for the Legacy MTA, and 200 MB for
|
@@ -172,31 +198,6 @@ module Sisimai
|
|
172
198
|
[535, 'incorrect authentication data'],
|
173
199
|
[550, 'submitter failed to disabled'],
|
174
200
|
[550, 'submitter failed to authenticate'],
|
175
|
-
|
176
|
-
# - This email has been sent using SMTP, but TLS is required by policy.
|
177
|
-
# - Delete or change the Secure Receipt or Secure Delivery policy enforcing TLS.
|
178
|
-
# Alternatively, ensure the certificates on the mail server haven't expired. If using
|
179
|
-
# a proxy server, ensure it isn't intercepting the traffic and modifying encryption
|
180
|
-
# parameters.
|
181
|
-
[553, 'this route requires encryption (tls)'],
|
182
|
-
|
183
|
-
# - A TLS connection has been attempted using a TLS version that is lower than TLS 1.2.
|
184
|
-
# - Delete or change the Secure Receipt or Secure Delivery policy enforcing TLS.
|
185
|
-
# Alternatively, ensure the mail server attempting to connect is using the appropri-
|
186
|
-
# ate version of TLS.
|
187
|
-
[553, 'this route requires tls version 1.2 or greater'],
|
188
|
-
|
189
|
-
# - A secure connection was attempted using ciphers that do not meet the configured ci-
|
190
|
-
# pher strength.
|
191
|
-
# - Delete or change the Secure Receipt or Secure Delivery policy enforcing TLS. Alter-
|
192
|
-
# natively, ensure the certificates on the mail server haven't expired. If using a
|
193
|
-
# proxy server, ensure it isn't intercepting the traffic and modifying encryption
|
194
|
-
# parameters.
|
195
|
-
[553, 'this route requires high-strength ciphers'],
|
196
|
-
|
197
|
-
# - Validation on your umbrella account's domain name does not conform to your DNS.
|
198
|
-
# - Check you DNS has the required umbrella accounts listed as comma-separated values.
|
199
|
-
[554, 'configuration is invalid for this certificate'],
|
200
201
|
],
|
201
202
|
'systemerror' => [
|
202
203
|
# - The Mimecast server is under maximum load.
|
@@ -281,7 +282,8 @@ module Sisimai
|
|
281
282
|
# Detect bounce reason from Mimecast
|
282
283
|
# @param [Sisimai::Fact] argvs Decoded email object
|
283
284
|
# @return [String] The bounce reason for mimecast.com
|
284
|
-
def
|
285
|
+
def find(argvs)
|
286
|
+
return argvs['reason'] unless argvs['reason'].empty?
|
285
287
|
return '' unless Sisimai::SMTP::Reply.test(argvs['replycode'])
|
286
288
|
|
287
289
|
issuedcode = argvs['diagnosticcode'].downcase || ''
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
module Rhost
|
3
3
|
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
|
4
|
-
# of
|
4
|
+
# of find() method when the value of "rhost" of the object is "mfsmax.docomo.ne.jp". This class
|
5
5
|
# is called only Sisimai::Fact class.
|
6
6
|
module NTTDOCOMO
|
7
7
|
class << self
|
@@ -14,9 +14,10 @@ module Sisimai
|
|
14
14
|
# Detect bounce reason from NTT DOCOMO
|
15
15
|
# @param [Sisimai::Fact] argvs Decoded email object
|
16
16
|
# @return [String] The bounce reason for docomo.ne.jp
|
17
|
-
def
|
17
|
+
def find(argvs)
|
18
|
+
return argvs['reason'] unless argvs['reason'].empty?
|
18
19
|
statuscode = argvs['deliverystatus'] || ''
|
19
|
-
thecommand = argvs['
|
20
|
+
thecommand = argvs['command'] || ''
|
20
21
|
esmtperror = argvs['diagnosticcode'].downcase || ''
|
21
22
|
reasontext = ''
|
22
23
|
|
@@ -0,0 +1,36 @@
|
|
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 find() method when the value of "rhost" of the object is "*.hotmail.com". This class is called
|
5
|
+
# only from Sisimai::Fact class.
|
6
|
+
module Outlook
|
7
|
+
class << self
|
8
|
+
MessagesOf = {
|
9
|
+
"hostunknown" => ["The mail could not be delivered to the recipient because the domain is not reachable"],
|
10
|
+
"userunknown" => ["Requested action not taken: mailbox unavailable"],
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
# Detect bounce reason from Microsoft Outlook.com: https://www.outlook.com/
|
14
|
+
# @param [Sisimai::Fact] argvs Decoded email object
|
15
|
+
# @return [String] The bounce reason for Outlook
|
16
|
+
# @since v5.2.0
|
17
|
+
def find(argvs)
|
18
|
+
return "" if argvs["diagnosticcode"].empty?
|
19
|
+
issuedcode = argvs["diagnosticcode"]
|
20
|
+
reasontext = ""
|
21
|
+
|
22
|
+
MessagesOf.each_key do |e|
|
23
|
+
# Try to match the error message with message patterns defined in $MessagesOf
|
24
|
+
next unless MessagesOf[e].any? { |a| issuedcode.include?(a) }
|
25
|
+
reasontext = e
|
26
|
+
break
|
27
|
+
end
|
28
|
+
|
29
|
+
return reasontext
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
module Rhost
|
3
3
|
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
|
4
|
-
# of
|
4
|
+
# of find() method when the value of "destination" of the object is "charter.net". This class is
|
5
5
|
# called only Sisimai::Fact class.
|
6
6
|
module Spectrum
|
7
7
|
class << self
|
@@ -100,7 +100,8 @@ module Sisimai
|
|
100
100
|
# @param [Sisimai::Fact] argvs Decoded email object
|
101
101
|
# @return [String, Nil] The bounce reason at Spectrum
|
102
102
|
# @since v4.25.8
|
103
|
-
def
|
103
|
+
def find(argvs)
|
104
|
+
return argvs['reason'] unless argvs['reason'].empty?
|
104
105
|
issuedcode = argvs['diagnosticcode']
|
105
106
|
reasontext = ''
|
106
107
|
codenumber = if cv = issuedcode.match(/AUP#[-A-Za-z]*(\d{4})/) then cv[1].to_i else 0 end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
module Rhost
|
3
3
|
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
|
4
|
-
# of
|
4
|
+
# of find() method when the value of "rhost" of the object is "mx*.qq.com". This class is called
|
5
5
|
# only Sisimai::Fact class.
|
6
6
|
module Tencent
|
7
7
|
class << self
|
@@ -49,7 +49,8 @@ module Sisimai
|
|
49
49
|
# Detect bounce reason from Tencent QQ
|
50
50
|
# @param [Sisimai::Fact] argvs Decoded email object
|
51
51
|
# @return [String] The bounce reason at Tencent QQ
|
52
|
-
def
|
52
|
+
def find(argvs)
|
53
|
+
return argvs['reason'] unless argvs['reason'].empty?
|
53
54
|
issuedcode = argvs['diagnosticcode'].downcase
|
54
55
|
reasontext = ''
|
55
56
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
module Rhost
|
3
3
|
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
|
4
|
-
# of
|
4
|
+
# of find() method when the value of "destination" of the object is "*.yahoodns.net".
|
5
5
|
# This class is called only Sisimai::Fact class.
|
6
6
|
module YahooInc
|
7
7
|
class << self
|
@@ -23,7 +23,7 @@ module Sisimai
|
|
23
23
|
# - 550 relaying denied for <***@yahoo.com>
|
24
24
|
'relaying denied for ',
|
25
25
|
],
|
26
|
-
'
|
26
|
+
'notcompliantrfc' => ['headers are not rfc compliant'],
|
27
27
|
'policyviolation' => [
|
28
28
|
# - 554 Message not allowed - [PH01] Email not accepted for policy reasons.
|
29
29
|
# Please visit https://postmaster.yahooinc.com/error-codes
|
@@ -87,7 +87,8 @@ module Sisimai
|
|
87
87
|
# https://smtpfieldmanual.com/provider/yahoo
|
88
88
|
# https://www.postmastery.com/yahoo-postmaster/
|
89
89
|
# @since v5.1.0
|
90
|
-
def
|
90
|
+
def find(argvs)
|
91
|
+
return argvs['reason'] unless argvs['reason'].empty?
|
91
92
|
issuedcode = argvs['diagnosticcode'].downcase
|
92
93
|
reasontext = ''
|
93
94
|
|
data/lib/sisimai/rhost.rb
CHANGED
@@ -1,54 +1,84 @@
|
|
1
1
|
module Sisimai
|
2
2
|
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
|
3
|
-
# of
|
3
|
+
# of find() method when the value of rhost of the object is listed in the results of Sisimai::Rhost
|
4
4
|
# ->list method. This class is called only Sisimai::Fact class.
|
5
5
|
module Rhost
|
6
6
|
class << self
|
7
7
|
RhostClass = {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
8
|
+
"Aol" => [".mail.aol.com", ".mx.aol.com"],
|
9
|
+
"Apple" => [".mail.icloud.com", ".apple.com", ".me.com"],
|
10
|
+
"Cox" => ["cox.net"],
|
11
|
+
"Facebook" => [".facebook.com"],
|
12
|
+
"FrancePTT" => [".laposte.net", ".orange.fr", ".wanadoo.fr"],
|
13
|
+
"GoDaddy" => ["smtp.secureserver.net", "mailstore1.secureserver.net"],
|
14
|
+
"Google" => ["aspmx.l.google.com", "gmail-smtp-in.l.google.com"],
|
15
|
+
"GSuite" => ["googlemail.com"],
|
16
|
+
"IUA" => [".email.ua"],
|
17
|
+
"KDDI" => [".ezweb.ne.jp", "msmx.au.com"],
|
18
|
+
"MessageLabs" => [".messagelabs.com"],
|
19
|
+
"Microsoft" => [".prod.outlook.com", ".protection.outlook.com", ".onmicrosoft.com", ".exchangelabs.com"],
|
20
|
+
"Mimecast" => [".mimecast.com"],
|
21
|
+
"NTTDOCOMO" => ["mfsmax.docomo.ne.jp"],
|
22
|
+
"Outlook" => [".hotmail.com"],
|
23
|
+
"Spectrum" => ["charter.net"],
|
24
|
+
"Tencent" => [".qq.com"],
|
25
|
+
"YahooInc" => [".yahoodns.net"],
|
21
26
|
}.freeze
|
22
27
|
|
28
|
+
# Returns the rhost class name
|
29
|
+
# @param [Hash] argvs Decoded email data
|
30
|
+
# @return [String] rhost class name
|
31
|
+
def name(argvs)
|
32
|
+
return "" if argvs.nil?
|
33
|
+
|
34
|
+
rhostclass = ""
|
35
|
+
clienthost = argvs["lhost"].downcase
|
36
|
+
remotehost = argvs["rhost"].downcase
|
37
|
+
domainpart = argvs["destination"].downcase
|
38
|
+
|
39
|
+
catch :FINDRHOST do
|
40
|
+
# Try to match the hostname patterns with the following order:
|
41
|
+
# 1. destination: The domain part of the recipient address
|
42
|
+
# 2. rhost: remote hostname
|
43
|
+
# 3. lhost: local MTA hostname
|
44
|
+
RhostClass.each_key do |e|
|
45
|
+
# Try to match the domain part of the recipient address with each value of RhostClass
|
46
|
+
next unless RhostClass[e].any? { |a| a.end_with?(domainpart) }
|
47
|
+
rhostclass = e
|
48
|
+
throw :FINDRHOST
|
49
|
+
end
|
50
|
+
|
51
|
+
RhostClass.each_key do |e|
|
52
|
+
# Try to match the remote host with each value of RhostClass
|
53
|
+
next unless RhostClass[e].any? { |a| remotehost.end_with?(a) }
|
54
|
+
rhostclass = e
|
55
|
+
throw :FINDRHOST
|
56
|
+
end
|
57
|
+
|
58
|
+
# Neither the remote host nor the destination did not matched with any value of RhostClass
|
59
|
+
RhostClass.each_key do |e|
|
60
|
+
# Try to match the client host with each value of RhostClass
|
61
|
+
next unless RhostClass[e].any? { |a| clienthost.end_with?(a) }
|
62
|
+
rhostclass = e
|
63
|
+
throw :FINDRHOST
|
64
|
+
end
|
65
|
+
end
|
66
|
+
return rhostclass
|
67
|
+
end
|
68
|
+
|
23
69
|
# Detect the bounce reason from certain remote hosts
|
24
70
|
# @param [Hash] argvs Decoded email data
|
25
71
|
# @return [String] The value of bounce reason
|
26
|
-
def
|
27
|
-
return
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
rhostmatch = nil
|
34
|
-
rhostclass = ''
|
35
|
-
modulename = ''
|
36
|
-
|
37
|
-
RhostClass.each_key do |e|
|
38
|
-
# Try to match with each value of RhostClass
|
39
|
-
rhostmatch = true if RhostClass[e].any? { |a| remotehost.end_with?(a) }
|
40
|
-
rhostmatch ||= true if RhostClass[e].any? { |a| domainpart.end_with?(a) }
|
41
|
-
next unless rhostmatch
|
42
|
-
|
43
|
-
modulename = 'Sisimai::Rhost::' << e
|
44
|
-
rhostclass = 'sisimai/rhost/' << e.downcase
|
45
|
-
break
|
46
|
-
end
|
47
|
-
return nil if rhostclass.empty?
|
72
|
+
def find(argvs)
|
73
|
+
return "" if argvs.nil?
|
74
|
+
|
75
|
+
rhostclass = name(argvs); return "" if rhostclass.empty?
|
76
|
+
modulepath = "sisimai/rhost/" << rhostclass.downcase; require modulepath
|
77
|
+
modulename = "Sisimai::Rhost::" << rhostclass
|
48
78
|
|
49
|
-
require rhostclass
|
50
|
-
reasontext = Module.const_get(modulename).
|
51
|
-
return
|
79
|
+
#rhostclass = "sisimai/rhost/" << modulename.downcase.split("::")[2]; require rhostclass
|
80
|
+
reasontext = Module.const_get(modulename).find(argvs)
|
81
|
+
return "" if reasontext.empty?
|
52
82
|
return reasontext
|
53
83
|
end
|
54
84
|
end
|
data/lib/sisimai/smtp/command.rb
CHANGED
@@ -3,9 +3,14 @@ module Sisimai
|
|
3
3
|
# Sisimai::SMTP::Transcript is an SMTP Command related utilities
|
4
4
|
module Command
|
5
5
|
class << self
|
6
|
+
Availables = [
|
7
|
+
"HELO", "EHLO", "MAIL", "RCPT", "DATA", "QUIT", "RSET", "NOOP", "VRFY", "ETRN", "EXPN",
|
8
|
+
"HELP", "AUTH", "STARTTLS", "XFORWARD",
|
9
|
+
"CONN", # CONN is a pseudo SMTP command used only in Sisimai
|
10
|
+
].freeze
|
6
11
|
Detectable = [
|
7
|
-
|
8
|
-
|
12
|
+
"HELO", "EHLO", "STARTTLS", "AUTH PLAIN", "AUTH LOGIN", "AUTH CRAM-", "AUTH DIGEST-",
|
13
|
+
"MAIL F", "RCPT", "RCPT T", "DATA", "QUIT", "XFORWARD",
|
9
14
|
].freeze
|
10
15
|
|
11
16
|
# Check that an SMTP command in the argument is valid or not
|
@@ -13,43 +18,48 @@ module Sisimai
|
|
13
18
|
# @return [Boolean] 0: Is not a valid SMTP command, 1: Is a valid SMTP command
|
14
19
|
# @since v5.0.0
|
15
20
|
def test(argv0 = '')
|
16
|
-
return
|
17
|
-
return
|
18
|
-
|
19
|
-
comm0 = %w[HELO EHLO MAIL RCPT DATA QUIT RSET NOOP VRFY ETRN EXPN HELP]
|
20
|
-
comm1 = %w[AUTH STARTTLS XFORWARD]
|
21
|
-
return true if comm0.any? { |a| argv0.include?(a) }
|
22
|
-
return true if comm1.any? { |a| argv0.include?(a) }
|
23
|
-
return true if argv0.include?('CONN') # CONN is a pseudo SMTP command used only in Sisimai
|
21
|
+
return false if argv0.nil? || argv0.empty? || argv0.size < 4
|
22
|
+
return true if Availables.any? { |a| argv0.include?(a) }
|
24
23
|
return false
|
25
24
|
end
|
26
25
|
|
27
26
|
# Pick an SMTP command from the given string
|
28
27
|
# @param [String] argv0 A transcript text MTA returned
|
29
28
|
# @return [String] An SMTP command
|
30
|
-
# @return [undef] Failed to find an SMTP command or the 1st argument is missing
|
31
29
|
# @since v5.0.0
|
32
30
|
def find(argv0 = '')
|
33
|
-
return
|
31
|
+
return "" unless Sisimai::SMTP::Command.test(argv0)
|
34
32
|
|
35
|
-
|
36
|
-
commandmap = {
|
33
|
+
issuedcode = " " + argv0.downcase + " "
|
34
|
+
commandmap = { "STAR" => "STARTTLS", "XFOR" => "XFORWARD" }
|
37
35
|
commandset = []
|
38
|
-
previouspp = 0
|
39
36
|
|
40
37
|
Detectable.each do |e|
|
41
38
|
# Find an SMTP command from the given string
|
42
|
-
p0 = argv0.index(e
|
43
|
-
|
44
|
-
|
45
|
-
|
39
|
+
p0 = argv0.index(e); next unless p0
|
40
|
+
if e.include?(" ") == false
|
41
|
+
# For example, "RCPT T" does not appear in an email address or a domain name
|
42
|
+
cx = true; while true do
|
43
|
+
# Exclude an SMTP command in the part of an email address, a domain name, such as
|
44
|
+
# DATABASE@EXAMPLE.JP, EMAIL.EXAMPLE.COM, and so on.
|
45
|
+
ca = issuedcode[p0, 1].ord
|
46
|
+
cz = issuedcode[p0 + e.size + 1, 1].ord
|
47
|
+
|
48
|
+
break if ca > 47 && ca < 58 || cz > 47 && cz < 58; # 0-9
|
49
|
+
break if ca > 63 && ca < 91 || cz > 63 && cz < 91; # @-Z
|
50
|
+
break if ca > 96 && ca < 123 || cz > 96 && cz < 123; # `-z
|
51
|
+
cx = false; break
|
52
|
+
end
|
53
|
+
next if cx == true
|
54
|
+
end
|
46
55
|
|
47
|
-
|
56
|
+
# There is the same command in the "commanset" or nor
|
57
|
+
cv = e[0, 4]; next if commandset.any? { |a| cv.start_with?(a) }
|
48
58
|
cv = commandmap[cv] if commandmap.has_key?(cv)
|
49
59
|
commandset << cv
|
50
60
|
end
|
51
61
|
|
52
|
-
return
|
62
|
+
return "" if commandset.empty?
|
53
63
|
return commandset.pop
|
54
64
|
end
|
55
65
|
end
|