sisimai 5.0.3-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/codecovio.yml +3 -1
- data/.github/workflows/rake-test.yml +7 -3
- data/ChangeLog.md +136 -0
- data/Makefile +4 -2
- data/README-JA.md +32 -22
- data/README.md +31 -21
- data/lib/sisimai/arf.rb +124 -213
- data/lib/sisimai/fact/json.rb +2 -2
- data/lib/sisimai/fact/yaml.rb +2 -2
- data/lib/sisimai/fact.rb +208 -173
- data/lib/sisimai/lda.rb +98 -0
- data/lib/sisimai/lhost/activehunter.rb +5 -4
- data/lib/sisimai/lhost/amazonses.rb +189 -305
- data/lib/sisimai/lhost/apachejames.rb +52 -55
- data/lib/sisimai/lhost/biglobe.rb +5 -6
- data/lib/sisimai/lhost/courier.rb +14 -12
- data/lib/sisimai/lhost/domino.rb +29 -29
- data/lib/sisimai/lhost/dragonfly.rb +113 -0
- data/lib/sisimai/lhost/einsundeins.rb +7 -8
- data/lib/sisimai/lhost/exchange2003.rb +10 -11
- data/lib/sisimai/lhost/exchange2007.rb +115 -104
- data/lib/sisimai/lhost/exim.rb +236 -246
- data/lib/sisimai/lhost/ezweb.rb +47 -55
- data/lib/sisimai/lhost/fml.rb +6 -7
- data/lib/sisimai/lhost/gmail.rb +36 -32
- data/lib/sisimai/lhost/gmx.rb +8 -20
- data/lib/sisimai/lhost/googlegroups.rb +13 -12
- data/lib/sisimai/lhost/googleworkspace.rb +94 -0
- data/lib/sisimai/lhost/imailserver.rb +11 -19
- data/lib/sisimai/lhost/interscanmss.rb +6 -5
- data/lib/sisimai/lhost/kddi.rb +7 -8
- data/lib/sisimai/lhost/mailfoundry.rb +6 -9
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +6 -6
- data/lib/sisimai/lhost/messagingserver.rb +19 -17
- data/lib/sisimai/lhost/mfilter.rb +8 -7
- data/lib/sisimai/lhost/notes.rb +6 -8
- data/lib/sisimai/lhost/opensmtpd.rb +11 -9
- data/lib/sisimai/lhost/postfix.rb +29 -31
- data/lib/sisimai/lhost/qmail.rb +136 -112
- data/lib/sisimai/lhost/sendmail.rb +23 -22
- data/lib/sisimai/lhost/v5sendmail.rb +93 -64
- data/lib/sisimai/lhost/verizon.rb +6 -6
- data/lib/sisimai/lhost/x1.rb +4 -4
- data/lib/sisimai/lhost/x2.rb +4 -5
- data/lib/sisimai/lhost/x3.rb +5 -5
- data/lib/sisimai/lhost/x6.rb +4 -4
- data/lib/sisimai/lhost/zoho.rb +6 -6
- data/lib/sisimai/lhost.rb +21 -24
- data/lib/sisimai/mail/maildir.rb +1 -1
- data/lib/sisimai/mail/stdin.rb +1 -1
- data/lib/sisimai/message.rb +100 -153
- data/lib/sisimai/order.rb +22 -77
- data/lib/sisimai/reason/authfailure.rb +1 -4
- data/lib/sisimai/reason/badreputation.rb +3 -3
- 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 +3 -3
- data/lib/sisimai/reason/notaccept.rb +2 -3
- data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
- data/lib/sisimai/reason/rejected.rb +2 -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 +82 -78
- 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 +224 -345
- data/lib/sisimai/rfc3834.rb +3 -3
- 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 +95 -0
- data/lib/sisimai/rhost/cox.rb +84 -34
- data/lib/sisimai/rhost/facebook.rb +100 -0
- data/lib/sisimai/rhost/franceptt.rb +87 -83
- data/lib/sisimai/rhost/godaddy.rb +208 -45
- data/lib/sisimai/rhost/google.rb +22 -22
- data/lib/sisimai/rhost/gsuite.rb +42 -0
- data/lib/sisimai/rhost/iua.rb +5 -5
- data/lib/sisimai/rhost/kddi.rb +9 -7
- data/lib/sisimai/rhost/messagelabs.rb +37 -0
- data/lib/sisimai/rhost/microsoft.rb +60 -54
- data/lib/sisimai/rhost/mimecast.rb +44 -31
- data/lib/sisimai/rhost/nttdocomo.rb +5 -4
- data/lib/sisimai/rhost/outlook.rb +36 -0
- data/lib/sisimai/rhost/spectrum.rb +102 -41
- data/lib/sisimai/rhost/tencent.rb +48 -26
- data/lib/sisimai/rhost/yahooinc.rb +111 -0
- data/lib/sisimai/rhost.rb +65 -42
- data/lib/sisimai/smtp/command.rb +31 -21
- data/lib/sisimai/smtp/failure.rb +103 -0
- data/lib/sisimai/smtp/reply.rb +29 -24
- data/lib/sisimai/smtp/status.rb +36 -19
- data/lib/sisimai/smtp/transcript.rb +18 -18
- data/lib/sisimai/string.rb +0 -46
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +0 -6
- data/set-of-emails/maildir/bsd/lhost-dragonfly-01.eml +36 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-02.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-03.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-04.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-05.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-06.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-07.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-08.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-09.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-10.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-11.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-12.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-13.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-14.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-15.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-16.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-17.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-18.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-19.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-20.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-21.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-22.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-23.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-24.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-25.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-26.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-27.eml +47 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-28.eml +47 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-29.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-30.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-10.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-11.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-12.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-13.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-14.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-15.eml +63 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-16.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-17.eml +63 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
- data/set-of-emails/maildir/bsd/lhost-qmail-11.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-12.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-13.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-14.eml +34 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-15.eml +30 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-16.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-17.eml +38 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-18.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-19.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-20.eml +46 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-21.eml +41 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-22.eml +42 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-23.eml +43 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-24.eml +43 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-25.eml +54 -0
- 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-apple-01.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-apple-02.eml +81 -0
- data/set-of-emails/maildir/bsd/rhost-apple-03.eml +75 -0
- data/set-of-emails/maildir/bsd/rhost-apple-04.eml +74 -0
- 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/bsd/rhost-yahooinc-01.eml +80 -0
- data/set-of-emails/maildir/bsd/rhost-yahooinc-02.eml +83 -0
- data/set-of-emails/maildir/bsd/rhost-yahooinc-03.eml +125 -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 +136 -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 -119
- 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
data/lib/sisimai/lhost/qmail.rb
CHANGED
@@ -1,12 +1,27 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Qmail
|
3
|
-
#
|
2
|
+
# Sisimai::Lhost::Qmail decodes a bounce email which created by qmail https://cr.yp.to/qmail.html
|
3
|
+
# or qmail clones or notqmail https://notqmail.org/.
|
4
|
+
# Methods in the module are called from only Sisimai::Message.
|
4
5
|
module Qmail
|
5
6
|
class << self
|
6
7
|
require 'sisimai/lhost'
|
8
|
+
require 'sisimai/string'
|
7
9
|
|
8
10
|
Indicators = Sisimai::Lhost.INDICATORS
|
9
|
-
Boundaries = [
|
11
|
+
Boundaries = [
|
12
|
+
# qmail-send.c:qmail_puts(&qqt,*sender.s ? "--- Below this line is a copy of the message.\n\n" :...
|
13
|
+
"--- Below this line is a copy of the message.", # qmail-1.03
|
14
|
+
"--- Below this line is a copy of the mail header.",
|
15
|
+
"--- Below the next line is a copy of the message.", # The followings are the qmail clone
|
16
|
+
"--- Mensaje original adjunto.",
|
17
|
+
"Content-Type: message/rfc822",
|
18
|
+
"Original message follows.",
|
19
|
+
].freeze
|
20
|
+
RelayedVia = [["(qmail ", "invoked for bounce)"], ["(qmail ", "invoked from ", "network)"]].freeze
|
21
|
+
EmailTitle = [
|
22
|
+
"failure notice", # qmail-send.c:Subject: failure notice\n\
|
23
|
+
"Failure Notice", # Yahoo
|
24
|
+
].freeze
|
10
25
|
StartingOf = {
|
11
26
|
# qmail-remote.c:248| if (code >= 500) {
|
12
27
|
# qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
|
@@ -15,97 +30,119 @@ module Sisimai::Lhost
|
|
15
30
|
#
|
16
31
|
# Characters: K,Z,D in qmail-qmqpc.c, qmail-send.c, qmail-rspawn.c
|
17
32
|
# K = success, Z = temporary error, D = permanent error
|
18
|
-
error
|
19
|
-
message
|
20
|
-
|
33
|
+
"error" => ["Remote host said:"],
|
34
|
+
"message" => [
|
35
|
+
"Hi. This is the qmail", # qmail-send.c:Hi. This is the qmail-send program at ");
|
36
|
+
"He/Her is not ", # The followings are the qmail clone
|
37
|
+
"unable to deliver your message to the following addresses",
|
38
|
+
"Su mensaje no pudo ser entregado",
|
39
|
+
"Sorry, we were unable to deliver your message to the following address",
|
40
|
+
"This is the machine generated message from mail service",
|
41
|
+
"This is the mail delivery agent at",
|
42
|
+
"Unable to deliver message to the following address",
|
43
|
+
"unable to deliver your message to the following addresses",
|
44
|
+
"Unfortunately, your mail was not delivered to the following address:",
|
45
|
+
"Your mail message to the following address",
|
46
|
+
"Your message to the following addresses",
|
47
|
+
"We're sorry.",
|
48
|
+
],
|
49
|
+
"rhost" => ['Giving up on ', 'Connected to ', 'remote host '],
|
21
50
|
}.freeze
|
22
51
|
CommandSet = {
|
23
|
-
# Error text regular expressions which defined in qmail-remote.c
|
24
52
|
# qmail-remote.c:225| if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
|
25
|
-
|
53
|
+
"CONN" => [" but greeting failed."],
|
26
54
|
# qmail-remote.c:231| if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
|
27
|
-
|
55
|
+
"EHLO" => [" but my name was rejected."],
|
28
56
|
# qmail-remote.c:238| if (code >= 500) quit("DConnected to "," but sender was rejected");
|
29
57
|
# reason = rejected
|
30
|
-
|
58
|
+
"MAIL" => [" but sender was rejected."],
|
31
59
|
# qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
|
32
60
|
# qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
|
33
61
|
# reason = userunknown
|
34
|
-
|
62
|
+
"RCPT" => [" does not like recipient."],
|
35
63
|
# qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
|
36
64
|
# qmail-remote.c:266| if (code >= 400) quit("Z"," failed on DATA command");
|
37
65
|
# qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
|
38
66
|
# qmail-remote.c:272| if (code >= 400) quit("Z"," failed after I sent the message");
|
39
|
-
|
67
|
+
"DATA" => [" failed on DATA command", " failed after I sent the message"],
|
40
68
|
}.freeze
|
41
69
|
|
42
70
|
# qmail-send.c:922| ... (&dline[c],"I'm not going to try again; this message has been in the queue too long.\n")) nomem();
|
43
|
-
|
44
|
-
|
71
|
+
# qmail-remote-fallback.patch
|
72
|
+
HasExpired = "this message has been in the queue too long.".freeze
|
73
|
+
OnHoldPair = [" does not like recipient.", "this message has been in the queue too long."].freeze
|
45
74
|
FailOnLDAP = {
|
46
75
|
# qmail-ldap-1.03-20040101.patch:19817 - 19866
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
76
|
+
"exceedlimit" => ["The message exeeded the maximum size the user accepts"], # 5.2.3
|
77
|
+
"userunknown" => ["Sorry, no mailbox here by that name"], # 5.1.1
|
78
|
+
"suspend" => [ # 5.2.1
|
79
|
+
"Mailaddress is administrativly disabled",
|
80
|
+
"Mailaddress is administrativley disabled",
|
81
|
+
"Mailaddress is administratively disabled",
|
82
|
+
"Mailaddress is administrativeley disabled",
|
83
|
+
],
|
84
|
+
"systemerror" => [
|
85
|
+
"Automatic homedir creator crashed", # 4.3.0
|
86
|
+
"Illegal value in LDAP attribute", # 5.3.5
|
87
|
+
"LDAP attribute is not given but mandatory", # 5.3.5
|
88
|
+
"Timeout while performing search on LDAP server", # 4.4.3
|
89
|
+
"Too many results returned but needs to be unique", # 5.3.5
|
90
|
+
"Permanent error while executing qmail-forward", # 5.4.4
|
91
|
+
"Temporary error in automatic homedir creation", # 4.3.0 or 5.3.0
|
92
|
+
"Temporary error while executing qmail-forward", # 4.4.4
|
93
|
+
"Temporary failure in LDAP lookup", # 4.4.3
|
94
|
+
"Unable to contact LDAP server", # 4.4.3
|
95
|
+
"Unable to login into LDAP server, bad credentials",# 4.4.3
|
62
96
|
],
|
63
97
|
}.freeze
|
64
98
|
MessagesOf = {
|
65
|
-
# qmail-
|
66
|
-
# qmail-remote.c:
|
67
|
-
|
99
|
+
# qmail-remote.c:68| Sorry, I couldn't find any host by that name. (#4.1.2)\n"); zerodie();
|
100
|
+
# qmail-remote.c:78| Sorry, I couldn't find any host named ");
|
101
|
+
"hostunknown" => ["Sorry, I couldn't find any host "],
|
68
102
|
# error_str.c:192| X(EDQUOT,"disk quota exceeded")
|
69
|
-
|
103
|
+
"mailboxfull" => ["disk quota exceeded"],
|
70
104
|
# qmail-qmtpd.c:233| ... result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)";
|
71
105
|
# qmail-smtpd.c:391| ... out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return;
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
'Unable to',
|
106
|
+
"mesgtoobig" => ["Message size exceeds fixed maximum message size:"],
|
107
|
+
"networkerror"=> [
|
108
|
+
"Sorry, I wasn't able to establish an SMTP connection",
|
109
|
+
"Sorry. Although I'm listed as a best-preference MX or A for that host",
|
110
|
+
],
|
111
|
+
"notaccept" => [
|
112
|
+
# notqmail 1.08 returns the following error message when the destination MX is NullMX
|
113
|
+
"Sorry, I couldn't find a mail exchanger or IP address",
|
81
114
|
],
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
115
|
+
"systemerror" => [
|
116
|
+
"bad interpreter: No such file or directory",
|
117
|
+
"system error",
|
118
|
+
"Unable to",
|
86
119
|
],
|
120
|
+
"systemfull" => ["Requested action not taken: mailbox unavailable (not enough free space)"],
|
121
|
+
# qmail-local.c:589| strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)");
|
122
|
+
# qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
|
123
|
+
"userunknown" => ["no mailbox here by that name"],
|
87
124
|
}.freeze
|
88
125
|
|
89
|
-
#
|
126
|
+
# @abstract Decodes the bounce message from qmail
|
90
127
|
# @param [Hash] mhead Message headers of a bounce email
|
91
128
|
# @param [String] mbody Message body of a bounce email
|
92
129
|
# @return [Hash] Bounce data list and message/rfc822 part
|
93
|
-
# @return [Nil] it failed to
|
130
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
94
131
|
def inquire(mhead, mbody)
|
95
132
|
# Pre process email headers and the body part of the message which generated
|
96
133
|
# by qmail, see https://cr.yp.to/qmail.html
|
97
134
|
# e.g.) Received: (qmail 12345 invoked for bounce); 29 Apr 2009 12:34:56 -0000
|
98
135
|
# Subject: failure notice
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
mhead['received'].each do |e|
|
136
|
+
proceedsto = false
|
137
|
+
proceedsto = true if EmailTitle.any? { |a| mhead["subject"] == a }
|
138
|
+
mhead["received"].each do |e|
|
103
139
|
# Received: (qmail 2222 invoked for bounce);29 Apr 2017 23:34:45 +0900
|
104
140
|
# Received: (qmail 2202 invoked from network); 29 Apr 2018 00:00:00 +0900
|
105
|
-
|
141
|
+
proceedsto = true if RelayedVia.any? { |a| Sisimai::String.aligned(e, a) }
|
106
142
|
end
|
107
|
-
return nil
|
143
|
+
return nil if proceedsto == false
|
108
144
|
|
145
|
+
require "sisimai/smtp/command"
|
109
146
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
110
147
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
111
148
|
bodyslices = emailparts[0].split("\n")
|
@@ -118,7 +155,7 @@ module Sisimai::Lhost
|
|
118
155
|
# line of the beginning of the original message.
|
119
156
|
if readcursor == 0
|
120
157
|
# Beginning of the bounce message or delivery status part
|
121
|
-
readcursor |= Indicators[:deliverystatus] if e.
|
158
|
+
readcursor |= Indicators[:deliverystatus] if StartingOf["message"].any? { |a| e.include?(a) }
|
122
159
|
next
|
123
160
|
end
|
124
161
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
@@ -130,31 +167,29 @@ module Sisimai::Lhost
|
|
130
167
|
# Giving up on 192.0.2.153.
|
131
168
|
v = dscontents[-1]
|
132
169
|
|
133
|
-
if e.start_with?('<') && Sisimai::String.aligned(e, ['<', '@', '
|
170
|
+
if e.start_with?('<') && Sisimai::String.aligned(e, ['<', '@', '>:'])
|
134
171
|
# <kijitora@example.jp>:
|
135
|
-
if v[
|
172
|
+
if v["recipient"] != ""
|
136
173
|
# There are multiple recipient addresses in the message body.
|
137
174
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
138
175
|
v = dscontents[-1]
|
139
176
|
end
|
140
|
-
v[
|
177
|
+
v["recipient"] = Sisimai::Address.s3s4(e[e.index("<"), e.size])
|
141
178
|
recipients += 1
|
142
179
|
|
143
180
|
elsif dscontents.size == recipients
|
144
181
|
# Append error message
|
145
|
-
|
146
|
-
v[
|
147
|
-
v['diagnosis'] << e + ' '
|
148
|
-
v['alterrors'] = e if e.start_with?(StartingOf[:error][0])
|
182
|
+
v["diagnosis"] << e + " "
|
183
|
+
v["alterrors"] = e if e.start_with?(StartingOf["error"][0])
|
149
184
|
|
150
|
-
next if v[
|
151
|
-
StartingOf[
|
185
|
+
next if v["rhost"] != ""
|
186
|
+
StartingOf["rhost"].each do |r|
|
152
187
|
# Find a remote host name
|
153
188
|
p1 = e.index(r); next unless p1
|
154
189
|
cm = r.size
|
155
|
-
p2 = e.index(
|
190
|
+
p2 = e.index(" ", p1 + cm + 1) || p2 = e.rindex(".")
|
156
191
|
|
157
|
-
v[
|
192
|
+
v["rhost"] = Sisimai::String.sweep(e[p1 + cm, p2 - p1 - cm])
|
158
193
|
break
|
159
194
|
end
|
160
195
|
end
|
@@ -162,72 +197,61 @@ module Sisimai::Lhost
|
|
162
197
|
return nil unless recipients > 0
|
163
198
|
|
164
199
|
dscontents.each do |e|
|
165
|
-
e['
|
166
|
-
e[
|
167
|
-
|
168
|
-
unless e['command']
|
169
|
-
# Get the SMTP command name for the session
|
170
|
-
CommandSet.each_key do |r|
|
171
|
-
# Verify each regular expression of SMTP commands
|
172
|
-
next unless CommandSet[r].any? { |a| e['diagnosis'].include?(a) }
|
173
|
-
e['command'] = r.upcase
|
174
|
-
break
|
175
|
-
end
|
200
|
+
# Tidy up the error message in e['diagnosis'], Try to detect the bounce reason.
|
201
|
+
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
|
176
202
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
203
|
+
# Get the SMTP command name for the session
|
204
|
+
CommandSet.each_key do |r|
|
205
|
+
# Get the last SMTP command
|
206
|
+
next unless CommandSet[r].any? { |a| e["diagnosis"].include?(a) }
|
207
|
+
e["command"] = r
|
208
|
+
break
|
181
209
|
end
|
182
210
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
211
|
+
if e["diagnosis"].include?("Sorry, no SMTP connection got far enough")
|
212
|
+
# Sorry, no SMTP connection got far enough; most progress was RCPT TO response; ...
|
213
|
+
e["command"] = Sisimai::SMTP::Command.find(e["diagnosis"]) if e["command"].empty?
|
214
|
+
end
|
187
215
|
|
188
|
-
|
216
|
+
# Detect the reason of bounce
|
217
|
+
if %w[HELO EHLO].index(e["command"])
|
189
218
|
# HELO | Connected to 192.0.2.135 but my name was rejected.
|
190
|
-
e[
|
219
|
+
e["reason"] = "blocked"
|
191
220
|
else
|
192
221
|
# Try to match with each error message in the table
|
193
|
-
if Sisimai::String.aligned(e[
|
222
|
+
if Sisimai::String.aligned(e["diagnosis"], OnHoldPair)
|
194
223
|
# To decide the reason require pattern match with Sisimai::Reason::* modules
|
195
|
-
e[
|
224
|
+
e["reason"] = "onhold"
|
196
225
|
else
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
226
|
+
# Check that the error message includes any of message patterns or not
|
227
|
+
[e["alterrors"], e["diagnosis"]].each do |f|
|
228
|
+
# Try to detect an error reason
|
229
|
+
break if e["reason"] != ""
|
230
|
+
next unless f
|
231
|
+
MessagesOf.each_key do |r|
|
232
|
+
# The key is a bounce reason name
|
233
|
+
next unless MessagesOf[r].any? { |a| f.include?(a) }
|
234
|
+
e["reason"] = r
|
235
|
+
break
|
203
236
|
end
|
204
|
-
break if e[
|
205
|
-
|
206
|
-
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
207
|
-
e['reason'] = r
|
208
|
-
break
|
209
|
-
end
|
237
|
+
break if e["reason"]
|
210
238
|
|
211
|
-
unless e['reason']
|
212
239
|
FailOnLDAP.each_key do |r|
|
213
|
-
#
|
214
|
-
next unless FailOnLDAP[r].any? { |a|
|
215
|
-
e[
|
240
|
+
# The key is a bounce reason name
|
241
|
+
next unless FailOnLDAP[r].any? { |a| f.include?(a) }
|
242
|
+
e["reason"] = r
|
216
243
|
break
|
217
244
|
end
|
218
|
-
|
219
|
-
|
220
|
-
unless e['reason']
|
221
|
-
e['reason'] = 'expired' if e['diagnosis'].include?(HasExpired)
|
245
|
+
break if e["reason"]
|
246
|
+
e["reason"] = "expired" if e["diagnosis"].include?(HasExpired)
|
222
247
|
end
|
223
248
|
end
|
224
249
|
end
|
225
250
|
|
226
|
-
e[
|
227
|
-
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
|
251
|
+
e["command"] = Sisimai::SMTP::Command.find(e["diagnosis"]) if e["command"].empty?
|
228
252
|
end
|
229
253
|
|
230
|
-
return {
|
254
|
+
return { "ds" => dscontents, "rfc822" => emailparts[1] }
|
231
255
|
end
|
232
256
|
def description; return 'qmail'; end
|
233
257
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Sendmail
|
3
|
-
# are called from only Sisimai::Message.
|
2
|
+
# Sisimai::Lhost::Sendmail decodes a bounce email which created by Sendmail Open Source https://sendmail.org/.
|
3
|
+
# Methods in the module are called from only Sisimai::Message.
|
4
4
|
module Sendmail
|
5
5
|
class << self
|
6
6
|
require 'sisimai/lhost'
|
7
|
+
require 'sisimai/rfc1123'
|
7
8
|
require 'sisimai/smtp/reply'
|
8
9
|
require 'sisimai/smtp/status'
|
9
10
|
require 'sisimai/smtp/command'
|
@@ -23,11 +24,11 @@ module Sisimai::Lhost
|
|
23
24
|
error: ['... while talking to '],
|
24
25
|
}.freeze
|
25
26
|
|
26
|
-
#
|
27
|
+
# @abstract Decodes the bounce message from Sendmail Open Source
|
27
28
|
# @param [Hash] mhead Message headers of a bounce email
|
28
29
|
# @param [String] mbody Message body of a bounce email
|
29
30
|
# @return [Hash] Bounce data list and message/rfc822 part
|
30
|
-
# @return [Nil] it failed to
|
31
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
31
32
|
def inquire(mhead, mbody)
|
32
33
|
return nil if mhead['x-aol-ip']
|
33
34
|
match = nil
|
@@ -55,24 +56,25 @@ module Sisimai::Lhost
|
|
55
56
|
readslices << e # Save the current line for the next loop
|
56
57
|
|
57
58
|
if readcursor == 0
|
58
|
-
# Beginning of the bounce message or message/delivery-status part
|
59
|
+
# Beginning of the bounce message or the message/delivery-status part
|
59
60
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
60
61
|
next
|
61
62
|
end
|
62
63
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
63
64
|
next if e.empty?
|
64
65
|
|
65
|
-
|
66
|
+
f = Sisimai::RFC1894.match(e)
|
67
|
+
if f > 0
|
66
68
|
# "e" matched with any field defined in RFC3464
|
67
69
|
o = Sisimai::RFC1894.field(e) || next
|
68
70
|
v = dscontents[-1]
|
69
71
|
|
70
|
-
if o[
|
72
|
+
if o[3] == 'addr'
|
71
73
|
# Final-Recipient: rfc822; kijitora@example.jp
|
72
74
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
73
75
|
if o[0] == 'final-recipient'
|
74
76
|
# Final-Recipient: rfc822; kijitora@example.jp
|
75
|
-
if v[
|
77
|
+
if v["recipient"] != ""
|
76
78
|
# There are multiple recipient addresses in the message body.
|
77
79
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
78
80
|
v = dscontents[-1]
|
@@ -83,16 +85,17 @@ module Sisimai::Lhost
|
|
83
85
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
84
86
|
v['alias'] = o[2]
|
85
87
|
end
|
86
|
-
elsif o[
|
88
|
+
elsif o[3] == 'code'
|
87
89
|
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
88
90
|
v['spec'] = o[1]
|
89
91
|
v['diagnosis'] = o[2]
|
90
92
|
else
|
91
93
|
# Other DSN fields defined in RFC3464
|
92
94
|
next unless fieldtable[o[0]]
|
95
|
+
next if o[3] == "host" && Sisimai::RFC1123.is_internethost(o[2]) == false
|
93
96
|
v[fieldtable[o[0]]] = o[2]
|
94
97
|
|
95
|
-
next unless f
|
98
|
+
next unless f == 1
|
96
99
|
permessage[fieldtable[o[0]]] = o[2]
|
97
100
|
end
|
98
101
|
else
|
@@ -109,15 +112,15 @@ module Sisimai::Lhost
|
|
109
112
|
# Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
|
110
113
|
unless e.start_with?(' ')
|
111
114
|
if e.start_with?('>>> ')
|
112
|
-
# >>> DATA
|
113
|
-
thecommand = Sisimai::SMTP::Command.find(e)
|
115
|
+
# >>> DATA (Client Command)
|
116
|
+
thecommand = Sisimai::SMTP::Command.find(e) if thecommand.empty?
|
114
117
|
|
115
118
|
elsif e.start_with?('<<< ')
|
116
|
-
# <<< Response
|
119
|
+
# <<< Response from the SMTP server
|
117
120
|
cv = e[4, e.size - 4]
|
118
121
|
esmtpreply << cv unless esmtpreply.index(cv)
|
119
122
|
else
|
120
|
-
# Detect SMTP session error or connection error
|
123
|
+
# Detect an SMTP session error or a connection error
|
121
124
|
next if sessionerr
|
122
125
|
if e.start_with?(StartingOf[:error][0])
|
123
126
|
# ----- Transcript of session follows -----
|
@@ -134,8 +137,8 @@ module Sisimai::Lhost
|
|
134
137
|
# ----- Transcript of session follows -----
|
135
138
|
# Message could not be delivered for too long
|
136
139
|
# Message will be deleted from queue
|
137
|
-
cr = Sisimai::SMTP::Reply.find(e)
|
138
|
-
cs = Sisimai::SMTP::Status.find(e)
|
140
|
+
cr = Sisimai::SMTP::Reply.find(e)
|
141
|
+
cs = Sisimai::SMTP::Status.find(e)
|
139
142
|
|
140
143
|
if cr.size + cs.size > 7
|
141
144
|
# 550 5.1.2 <kijitora@example.org>... Message
|
@@ -167,13 +170,12 @@ module Sisimai::Lhost
|
|
167
170
|
|
168
171
|
dscontents.each do |e|
|
169
172
|
# Set default values if each value is empty.
|
170
|
-
e['diagnosis'] ||= ''
|
171
173
|
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
172
174
|
|
173
175
|
if anotherset['diagnosis']
|
174
176
|
# Copy alternative error message
|
175
177
|
e['diagnosis'] = anotherset['diagnosis'] if e['diagnosis'].start_with?(' ')
|
176
|
-
e['diagnosis'] = anotherset['diagnosis'] if e['diagnosis']
|
178
|
+
e['diagnosis'] = anotherset['diagnosis'] if e['diagnosis'] =~ /\A\d+\z/
|
177
179
|
e['diagnosis'] = anotherset['diagnosis'] if e['diagnosis'].empty?
|
178
180
|
end
|
179
181
|
|
@@ -188,10 +190,9 @@ module Sisimai::Lhost
|
|
188
190
|
end
|
189
191
|
|
190
192
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
191
|
-
e[
|
192
|
-
|
193
|
-
|
194
|
-
end
|
193
|
+
e["command"] = thecommand if e["command"].empty?
|
194
|
+
e["command"] = Sisimai::SMTP::Command.find(e['diagnosis']) if e["command"].empty?
|
195
|
+
e["command"] = "EHLO" if e["command"].empty? && esmtpreply.size > 0
|
195
196
|
|
196
197
|
while true
|
197
198
|
# Check alternative status code and override it
|