sisimai 5.0.3 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/exim.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Exim
|
3
|
-
# from only Sisimai::Message.
|
2
|
+
# Sisimai::Lhost::Exim decodes a bounce email which created by Exim Internet Mailer https://www.exim.org/.
|
3
|
+
# Methods in the module are called from only Sisimai::Message.
|
4
4
|
module Exim
|
5
5
|
class << self
|
6
6
|
require 'sisimai/lhost'
|
7
|
+
require 'sisimai/rfc1894'
|
7
8
|
|
8
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
+
FieldTable = Sisimai::RFC1894.FIELDTABLE
|
9
11
|
Boundaries = [
|
10
12
|
# deliver.c:6423| if (bounce_return_body) fprintf(f,
|
11
13
|
# deliver.c:6424|"------ This is a copy of the message, including all the headers. ------\n");
|
12
14
|
# deliver.c:6425| else fprintf(f,
|
13
15
|
# deliver.c:6426|"------ This is a copy of the message's headers. ------\n");
|
14
|
-
|
15
|
-
|
16
|
+
"------ This is a copy of the message, including all the headers. ------",
|
17
|
+
"Content-Type: message/rfc822",
|
18
|
+
"Included is a copy of the message header:\n-----------------------------------------", # MXLogic
|
19
|
+
].freeze
|
20
|
+
EmailTitle = [
|
21
|
+
"Delivery Status Notification",
|
22
|
+
"Mail delivery failed",
|
23
|
+
"Mail failure",
|
24
|
+
"Message frozen",
|
25
|
+
"Warning: message ",
|
26
|
+
"error(s) in forwarding or filtering",
|
16
27
|
].freeze
|
17
28
|
StartingOf = {
|
18
29
|
# Error text strings which defined in exim/src/deliver.c
|
@@ -32,137 +43,155 @@ module Sisimai::Lhost
|
|
32
43
|
# deliver.c:6304|"could not be delivered to one or more of its recipients. The following\n"
|
33
44
|
# deliver.c:6305|"address(es) failed:\n", sender_address);
|
34
45
|
# deliver.c:6306| }
|
35
|
-
|
36
|
-
|
37
|
-
message
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
46
|
+
"alias" => [" an undisclosed address"],
|
47
|
+
"command" => ["SMTP error from remote ", "LMTP error after "],
|
48
|
+
"deliverystatus" => ["Content-Type: message/delivery-status"],
|
49
|
+
"frozen" => [" has been frozen", " was frozen on arrival"],
|
50
|
+
"message" => [
|
51
|
+
"This message was created automatically by mail delivery software.",
|
52
|
+
"A message that you sent was rejected by the local scannning code",
|
53
|
+
"A message that you sent contained one or more recipient addresses ",
|
54
|
+
"A message that you sent could not be delivered to all of its recipients",
|
55
|
+
" has been frozen",
|
56
|
+
" was frozen on arrival",
|
57
|
+
" router encountered the following error(s):",
|
45
58
|
],
|
46
59
|
}.freeze
|
47
|
-
MarkingsOf = { alias: ' an undisclosed address' }.freeze
|
48
|
-
ReCommands = [
|
49
|
-
# transports/smtp.c:564| *message = US string_sprintf("SMTP error from remote mail server after %s%s: "
|
50
|
-
# transports/smtp.c:837| string_sprintf("SMTP error from remote mail server after RCPT TO:<%s>: "
|
51
|
-
%r/SMTP error from remote (?:mail server|mailer) after ([A-Za-z]{4})/,
|
52
|
-
%r/SMTP error from remote (?:mail server|mailer) after end of ([A-Za-z]{4})/,
|
53
|
-
%r/LMTP error after ([A-Za-z]{4})/,
|
54
|
-
%r/LMTP error after end of ([A-Za-z]{4})/,
|
55
|
-
].freeze
|
56
60
|
MessagesOf = {
|
57
61
|
# find exim/ -type f -exec grep 'message = US' {} /dev/null \;
|
58
62
|
# route.c:1158| DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n");
|
59
|
-
'
|
63
|
+
# find exim/ -type f -exec grep 'message = US' {} /dev/null \;
|
64
|
+
# route.c:1158| DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n");
|
65
|
+
"userunknown" => ["user not found"],
|
60
66
|
# transports/smtp.c:3524| addr->message = US"all host address lookups failed permanently";
|
61
67
|
# routers/dnslookup.c:331| addr->message = US"all relevant MX records point to non-existent hosts";
|
62
68
|
# route.c:1826| uschar *message = US"Unrouteable address";
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
69
|
+
"hostunknown" => [
|
70
|
+
"all host address lookups failed permanently",
|
71
|
+
"all relevant MX records point to non-existent hosts",
|
72
|
+
"Unrouteable address",
|
67
73
|
],
|
68
74
|
# transports/appendfile.c:2567| addr->user_message = US"mailbox is full";
|
69
75
|
# transports/appendfile.c:3049| addr->message = string_sprintf("mailbox is full "
|
70
76
|
# transports/appendfile.c:3050| "(quota exceeded while writing to file %s)", filename);
|
71
|
-
|
77
|
+
"mailboxfull" => [
|
78
|
+
"mailbox is full",
|
79
|
+
"error: quota exceed",
|
80
|
+
],
|
72
81
|
# routers/dnslookup.c:328| addr->message = US"an MX or SRV record indicated no SMTP service";
|
73
82
|
# transports/smtp.c:3502| addr->message = US"no host found for existing SMTP connection";
|
74
|
-
|
75
|
-
|
76
|
-
|
83
|
+
"notaccept" => [
|
84
|
+
"an MX or SRV record indicated no SMTP service",
|
85
|
+
"no host found for existing SMTP connection",
|
77
86
|
],
|
78
87
|
# parser.c:666| *errorptr = string_sprintf("%s (expected word or \"<\")", *errorptr);
|
79
88
|
# parser.c:701| if(bracket_count++ > 5) FAILED(US"angle-brackets nested too deep");
|
80
89
|
# parser.c:738| FAILED(US"domain missing in source-routed address");
|
81
90
|
# parser.c:747| : string_sprintf("malformed address: %.32s may not follow %.*s",
|
82
|
-
|
83
|
-
|
91
|
+
"syntaxerror" => [
|
92
|
+
"angle-brackets nested too deep",
|
84
93
|
'expected word or "<"',
|
85
|
-
|
86
|
-
|
94
|
+
"domain missing in source-routed address",
|
95
|
+
"malformed address:",
|
87
96
|
],
|
88
97
|
# deliver.c:5614| addr->message = US"delivery to file forbidden";
|
89
98
|
# deliver.c:5624| addr->message = US"delivery to pipe forbidden";
|
90
99
|
# transports/pipe.c:1156| addr->user_message = US"local delivery failed";
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
100
|
+
"systemerror" => [
|
101
|
+
"delivery to file forbidden",
|
102
|
+
"delivery to pipe forbidden",
|
103
|
+
"local delivery failed",
|
104
|
+
"LMTP error after ",
|
96
105
|
],
|
97
106
|
# deliver.c:5425| new->message = US"Too many \"Received\" headers - suspected mail loop";
|
98
|
-
|
107
|
+
"contenterror" => ['Too many "Received" headers'],
|
99
108
|
}.freeze
|
100
|
-
|
101
|
-
# retry.c:902| addr->message = (addr->message == NULL)? US"retry timeout exceeded" :
|
102
|
-
# deliver.c:7475| "No action is required on your part. Delivery attempts will continue for\n"
|
103
|
-
# smtp.c:3508| US"retry time not reached for any host after a long failure period" :
|
104
|
-
# smtp.c:3508| US"all hosts have been failing for a long time and were last tried "
|
105
|
-
# "after this message arrived";
|
106
|
-
# deliver.c:7459| print_address_error(addr, f, US"Delay reason: ");
|
107
|
-
# deliver.c:7586| "Message %s has been frozen%s.\nThe sender is <%s>.\n", message_id,
|
108
|
-
# receive.c:4021| moan_tell_someone(freeze_tell, NULL, US"Message frozen on arrival",
|
109
|
-
# receive.c:4022| "Message %s was frozen on arrival by %s.\nThe sender is <%s>.\n",
|
110
109
|
DelayedFor = [
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
110
|
+
# retry.c:902| addr->message = (addr->message == NULL)? US"retry timeout exceeded" :
|
111
|
+
# deliver.c:7475| "No action is required on your part. Delivery attempts will continue for\n"
|
112
|
+
# smtp.c:3508| US"retry time not reached for any host after a long failure period" :
|
113
|
+
# smtp.c:3508| US"all hosts have been failing for a long time and were last tried "
|
114
|
+
# "after this message arrived";
|
115
|
+
# deliver.c:7459| print_address_error(addr, f, US"Delay reason: ");
|
116
|
+
# deliver.c:7586| "Message %s has been frozen%s.\nThe sender is <%s>.\n", message_id,
|
117
|
+
# receive.c:4021| moan_tell_someone(freeze_tell, NULL, US"Message frozen on arrival",
|
118
|
+
# receive.c:4022| "Message %s was frozen on arrival by %s.\nThe sender is <%s>.\n",
|
119
|
+
"retry timeout exceeded",
|
120
|
+
"No action is required on your part",
|
121
|
+
"retry time not reached for any host after a long failure period",
|
122
|
+
"all hosts have been failing for a long time and were last tried",
|
123
|
+
"Delay reason: ",
|
124
|
+
"has been frozen",
|
125
|
+
"was frozen on arrival by ",
|
118
126
|
].freeze
|
119
127
|
|
120
|
-
#
|
128
|
+
# @abstract Decodes the bounce message from Exim
|
121
129
|
# @param [Hash] mhead Message headers of a bounce email
|
122
130
|
# @param [String] mbody Message body of a bounce email
|
123
131
|
# @return [Hash] Bounce data list and message/rfc822 part
|
124
|
-
# @return [Nil] it failed to
|
132
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
125
133
|
def inquire(mhead, mbody)
|
126
|
-
return nil if mhead['from'].include?('.mail.ru')
|
127
|
-
|
128
134
|
# Message-Id: <E1P1YNN-0003AD-Ga@example.org>
|
129
135
|
# X-Failed-Recipients: kijitora@example.ed.jp
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
'
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
136
|
+
thirdparty = false
|
137
|
+
proceedsto = 0
|
138
|
+
messageidv = mhead["message-id"] || ""
|
139
|
+
|
140
|
+
proceedsto += 1 if mhead["from"].include?("Mail Delivery System")
|
141
|
+
while messageidv != "" do
|
142
|
+
# Message-Id: <E1P1YNN-0003AD-Ga@example.org>
|
143
|
+
break if messageidv.index("<") != 0
|
144
|
+
break if messageidv.index("-") != 8
|
145
|
+
break if messageidv.index('@') != 18
|
146
|
+
proceedsto += 1; break
|
147
|
+
end
|
148
|
+
EmailTitle.each do |e|
|
149
|
+
# Subject: Mail delivery failed: returning message to sender
|
150
|
+
# Subject: Mail delivery failed
|
151
|
+
# Subject: Message frozen
|
152
|
+
next if mhead["subject"].include?(e) == false
|
153
|
+
proceedsto += 1; break
|
154
|
+
end
|
155
|
+
|
156
|
+
while true
|
157
|
+
# Exim clones of the third Parties
|
158
|
+
# 1. McAfee Saas (Formerly MXLogic)
|
159
|
+
if mhead.has_key?("x-mx-bounce") then thirdparty = true; break; end
|
160
|
+
if mhead.has_key?("x-mxl-hash") then thirdparty = true; break; end
|
161
|
+
if mhead.has_key?("x-mxl-notehash") then thirdparty = true; break; end
|
162
|
+
if messageidv.include?("<mxl~") then thirdparty = true; break; end
|
163
|
+
break
|
164
|
+
end
|
165
|
+
return nil if proceedsto < 2 && thirdparty == false
|
166
|
+
|
167
|
+
require "sisimai/address"
|
168
|
+
require "sisimai/rfc2045"
|
169
|
+
require "sisimai/smtp/command"
|
170
|
+
|
144
171
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
145
172
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
146
173
|
bodyslices = emailparts[0].split("\n")
|
147
174
|
readcursor = 0 # (Integer) Points the current cursor position
|
148
|
-
nextcursor =
|
175
|
+
nextcursor = false
|
149
176
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
150
|
-
boundary00 =
|
177
|
+
boundary00 = "" # (String) Boundary string
|
151
178
|
v = nil
|
152
179
|
|
153
|
-
if mhead[
|
180
|
+
if mhead["content-type"]
|
154
181
|
# Get the boundary string and set regular expression for matching with the boundary string.
|
155
|
-
boundary00 = Sisimai::RFC2045.boundary(mhead[
|
182
|
+
boundary00 = Sisimai::RFC2045.boundary(mhead["content-type"]) || ""
|
156
183
|
end
|
157
184
|
|
185
|
+
p1 = -1; p2 = -1;
|
158
186
|
while e = bodyslices.shift do
|
159
187
|
# Read error messages and delivery status lines from the head of the email to the previous
|
160
188
|
# line of the beginning of the original message.
|
161
189
|
if readcursor == 0
|
162
190
|
# Beginning of the bounce message or message/delivery-status part
|
163
|
-
if StartingOf[
|
191
|
+
if StartingOf["message"].any? { |a| e.include?(a) }
|
192
|
+
# Check the message defined in StartingOf["message"], ["frozen"]
|
164
193
|
readcursor |= Indicators[:deliverystatus]
|
165
|
-
next unless StartingOf[
|
194
|
+
next unless StartingOf["frozen"].any? { |a| e.include?(a) }
|
166
195
|
end
|
167
196
|
end
|
168
197
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
@@ -182,26 +211,27 @@ module Sisimai::Lhost
|
|
182
211
|
ce = false
|
183
212
|
while true
|
184
213
|
# Check if the line matche the following patterns:
|
185
|
-
break
|
186
|
-
break
|
187
|
-
break
|
188
|
-
break
|
189
|
-
|
190
|
-
|
191
|
-
break
|
214
|
+
break if e.start_with?(" ") == false # The line should start with " " (2 spaces)
|
215
|
+
break if e.include?('@') == false # "@" should be included (email)
|
216
|
+
break if e.include?(".") == false # "." should be included (domain part)
|
217
|
+
break if e.include?("pipe to |") # Exclude "pipe to /path/to/prog" line
|
218
|
+
|
219
|
+
cx = e[2, 1]
|
220
|
+
break if cx == " " # The 3rd character is " "
|
221
|
+
break if thirdparty == false && cx == "<" # MXLogic returns " <neko@example.jp>:..."
|
192
222
|
ce = true
|
193
223
|
break
|
194
224
|
end
|
195
225
|
|
196
|
-
if ce || e.include?(
|
226
|
+
if ce == true || e.include?(StartingOf["alias"][0])
|
197
227
|
# The line is including an email address
|
198
|
-
if v[
|
228
|
+
if v["recipient"] != ""
|
199
229
|
# There are multiple recipient addresses in the message body.
|
200
230
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
201
231
|
v = dscontents[-1]
|
202
232
|
end
|
203
233
|
|
204
|
-
if e.include?(
|
234
|
+
if e.include?(StartingOf["alias"][0])
|
205
235
|
# The line does not include an email address
|
206
236
|
# deliver.c:4549| printed = US"an undisclosed address";
|
207
237
|
# an undisclosed address
|
@@ -211,8 +241,8 @@ module Sisimai::Lhost
|
|
211
241
|
# kijitora@example.jp
|
212
242
|
# sabineko@example.jp: forced freeze
|
213
243
|
# mikeneko@example.jp <nekochan@example.org>: ...
|
214
|
-
p1 = e.index(
|
215
|
-
p2 = e.index(
|
244
|
+
p1 = e.index("<") || -1
|
245
|
+
p2 = e.index(">:") || -1
|
216
246
|
|
217
247
|
if p1 > 1 && p2 > 1
|
218
248
|
# There are an email address and an error message in the line
|
@@ -224,85 +254,78 @@ module Sisimai::Lhost
|
|
224
254
|
# parser.c:748| s-1, (int)(s - US mailbox - 1), mailbox);
|
225
255
|
# parser.c:749| goto PARSE_FAILED;
|
226
256
|
# parser.c:750| }
|
227
|
-
cv = Sisimai::Address.s3s4(e[p1
|
228
|
-
v[
|
257
|
+
cv = Sisimai::Address.s3s4(e[p1, p2 - p1 - 1])
|
258
|
+
v["diagnosis"] = Sisimai::String.sweep(e[p2 + 1, e.size])
|
229
259
|
else
|
230
260
|
# There is an email address only in the line
|
231
261
|
# kijitora@example.jp
|
232
262
|
cv = Sisimai::Address.s3s4(e[2, e.size])
|
233
263
|
end
|
234
264
|
end
|
235
|
-
v[
|
265
|
+
v["recipient"] = cv
|
236
266
|
recipients += 1
|
237
267
|
|
238
|
-
elsif e.include?(
|
268
|
+
elsif e.include?(" (generated from ") || e.include?(" generated by ")
|
239
269
|
# (generated from kijitora@example.jp)
|
240
270
|
# pipe to |/bin/echo "Some pipe output"
|
241
271
|
# generated by userx@myhost.test.ex
|
242
|
-
|
243
|
-
|
272
|
+
e.split(" ").each do |f|
|
273
|
+
# Find the alias address
|
274
|
+
next unless f.include?('@')
|
275
|
+
v["alias"] = Sisimai::Address.s3s4(f)
|
276
|
+
end
|
244
277
|
else
|
245
|
-
|
246
|
-
|
247
|
-
if StartingOf[:frozen].any? { |a| e.include?(a) }
|
278
|
+
if StartingOf["frozen"].any? { |a| e.include?(a) }
|
248
279
|
# Message *** has been frozen by the system filter.
|
249
280
|
# Message *** was frozen on arrival by ACL.
|
250
|
-
v[
|
251
|
-
v[
|
252
|
-
elsif
|
281
|
+
v["alterrors"] ||= ""
|
282
|
+
v["alterrors"] << e + " "
|
283
|
+
elsif boundary00 != ""
|
253
284
|
# --NNNNNNNNNN-eximdsn-MMMMMMMMMM
|
254
285
|
# Content-type: message/delivery-status
|
255
286
|
# ...
|
256
|
-
if Sisimai::RFC1894.match(e)
|
287
|
+
if Sisimai::RFC1894.match(e) > 0
|
257
288
|
# "e" matched with any field defined in RFC3464
|
258
289
|
next unless o = Sisimai::RFC1894.field(e)
|
259
290
|
|
260
|
-
if o[
|
291
|
+
if o[3] == "addr"
|
261
292
|
# Final-Recipient: rfc822; kijitora@example.jp
|
262
293
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
263
|
-
next unless o[0] ==
|
264
|
-
v[
|
294
|
+
next unless o[0] == "final-recipient"
|
295
|
+
if v["spec"].empty?
|
296
|
+
v["spec"] = o[2].include?('@') ? "SMTP" : "X-UNIX"
|
297
|
+
end
|
265
298
|
|
266
|
-
elsif o[
|
299
|
+
elsif o[3] == "code"
|
267
300
|
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
268
|
-
v[
|
269
|
-
v[
|
301
|
+
v["spec"] = o[1].upcase
|
302
|
+
v["diagnosis"] = o[2]
|
270
303
|
|
271
304
|
else
|
272
305
|
# Other DSN fields defined in RFC3464
|
273
|
-
next unless
|
274
|
-
v[
|
306
|
+
next unless FieldTable[o[0]]
|
307
|
+
v[FieldTable[o[0]]] = o[2]
|
275
308
|
end
|
276
309
|
else
|
277
310
|
# Error message ?
|
278
|
-
next if nextcursor
|
311
|
+
next if nextcursor
|
279
312
|
|
280
313
|
# Content-type: message/delivery-status
|
281
|
-
nextcursor =
|
282
|
-
v[
|
283
|
-
if e.start_with?("
|
284
|
-
e.sub!(/\A[\s\t]+/, '')
|
285
|
-
v['alterrors'] << e + ' ' unless v['alterrors'].include?(e)
|
286
|
-
end
|
314
|
+
nextcursor = true if e.start_with?(StartingOf["deliverystatus"][0])
|
315
|
+
v["alterrors"] ||= ''
|
316
|
+
v["alterrors"] << e + " " unless v["alterrors"].include?(e) if e.start_with?(" ")
|
287
317
|
end
|
288
318
|
else
|
289
319
|
# There is no boundary string in $boundary00
|
290
320
|
if dscontents.size == recipients
|
291
321
|
# Error message
|
292
|
-
|
293
|
-
v['diagnosis'] ||= ''
|
294
|
-
v['diagnosis'] << e + ' '
|
322
|
+
v["diagnosis"] << e + " "
|
295
323
|
else
|
296
|
-
# Error message when email address above does not include '@' and domain part
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
else
|
302
|
-
next unless e.start_with?(' ')
|
303
|
-
v['alterrors'] ||= ''
|
304
|
-
v['alterrors'] << e + ' '
|
305
|
-
end
|
324
|
+
# Error message when email address above does not include '@' and domain part
|
325
|
+
# pipe to |/path/to/prog ...
|
326
|
+
# generated by kijitora@example.com
|
327
|
+
next unless e.start_with?(" ")
|
328
|
+
v["diagnosis"] << e + " "
|
306
329
|
end
|
307
330
|
end
|
308
331
|
end
|
@@ -312,128 +335,121 @@ module Sisimai::Lhost
|
|
312
335
|
# Check "an undisclosed address", "unroutable address"
|
313
336
|
dscontents.each do |q|
|
314
337
|
# Replace the recipient address with the value of "alias"
|
315
|
-
next
|
316
|
-
|
317
|
-
if q['recipient'].empty? || q['recipient'].include?('@') == false
|
338
|
+
next if q["alias"].empty?
|
339
|
+
if q["recipient"].empty? || q["recipient"].include?('@') == false
|
318
340
|
# The value of "recipient" is empty or does not include "@"
|
319
|
-
q[
|
341
|
+
q["recipient"] = q["alias"]
|
320
342
|
end
|
321
343
|
end
|
322
344
|
else
|
323
345
|
# Fallback for getting recipient addresses
|
324
|
-
if mhead[
|
346
|
+
if mhead["x-failed-recipients"]
|
325
347
|
# X-Failed-Recipients: kijitora@example.jp
|
326
|
-
rcptinhead = mhead[
|
327
|
-
rcptinhead.each do |
|
348
|
+
rcptinhead = mhead["x-failed-recipients"].split(",")
|
349
|
+
rcptinhead.each do |e|
|
328
350
|
# Remove space characters
|
329
|
-
|
330
|
-
|
351
|
+
e.lstrip!
|
352
|
+
e.rstrip!
|
331
353
|
end
|
332
354
|
recipients = rcptinhead.size
|
333
355
|
|
334
356
|
while e = rcptinhead.shift do
|
335
357
|
# Insert each recipient address into dscontents
|
336
|
-
dscontents[-1][
|
358
|
+
dscontents[-1]["recipient"] = e
|
337
359
|
next if dscontents.size == recipients
|
338
360
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
339
361
|
end
|
340
362
|
end
|
341
363
|
end
|
342
|
-
return nil
|
364
|
+
return nil if recipients == 0
|
343
365
|
|
344
366
|
# Get the name of the local MTA
|
345
367
|
# Received: from marutamachi.example.org (c192128.example.net [192.0.2.128])
|
346
|
-
receivedby = mhead[
|
368
|
+
receivedby = mhead["received"] || []
|
347
369
|
recvdtoken = Sisimai::RFC5322.received(receivedby[-1])
|
348
370
|
|
349
371
|
dscontents.each do |e|
|
350
372
|
# Check the error message, the rhost, the lhost, and the smtp command.
|
351
|
-
|
373
|
+
e["alterrors"] = "" if e["alterrors"].nil?
|
374
|
+
if e["diagnosis"].empty? && boundary00.size > 0
|
352
375
|
# Empty Diagnostic-Code: or error message
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
unless dscontents[0]['alterrors'].to_s.empty?
|
370
|
-
# The value of "alterrors" is also copied
|
371
|
-
e['alterrors'] = dscontents[0]['alterrors']
|
372
|
-
end
|
373
|
-
end
|
376
|
+
# --NNNNNNNNNN-eximdsn-MMMMMMMMMM
|
377
|
+
# Content-type: message/delivery-status
|
378
|
+
#
|
379
|
+
# Reporting-MTA: dns; the.local.host.name
|
380
|
+
#
|
381
|
+
# Action: failed
|
382
|
+
# Final-Recipient: rfc822;/a/b/c
|
383
|
+
# Status: 5.0.0
|
384
|
+
#
|
385
|
+
# Action: failed
|
386
|
+
# Final-Recipient: rfc822;|/p/q/r
|
387
|
+
# Status: 5.0.0
|
388
|
+
e["diagnosis"] = dscontents[0]["diagnosis"]
|
389
|
+
e["spec"] = dscontents[0]["spec"] if e["spec"].empty?
|
390
|
+
e["alterrors"] = dscontents[0]["alterrors"] if dscontents[0]["alterrors"] != ""
|
374
391
|
end
|
375
392
|
|
376
|
-
|
393
|
+
if e["alterrors"]
|
377
394
|
# Copy alternative error message
|
378
|
-
|
379
|
-
e['diagnosis'] = e['alterrors']
|
380
|
-
end
|
395
|
+
e["diagnosis"] = e["alterrors"] if e["diagnosis"].empty?
|
381
396
|
|
382
|
-
if e[
|
397
|
+
if e["diagnosis"].start_with?("-") || e["diagnosis"].end_with?("__")
|
383
398
|
# Override the value of diagnostic code message
|
384
|
-
e[
|
399
|
+
e["diagnosis"] = e["alterrors"]
|
385
400
|
|
386
|
-
elsif e[
|
387
|
-
# Override the value of diagnostic code message
|
388
|
-
# the
|
389
|
-
e[
|
401
|
+
elsif e["diagnosis"].size < e["alterrors"].size
|
402
|
+
# Override the value of diagnostic code message with the value of alterrors because
|
403
|
+
# the latter includes the former.
|
404
|
+
e["alterrors"].squeeze!(" ")
|
405
|
+
e["diagnosis"] = e["alterrors"] if e["alterrors"].downcase.include?(e["diagnosis"].downcase)
|
390
406
|
end
|
391
|
-
e.delete(
|
407
|
+
e.delete("alterrors")
|
392
408
|
end
|
393
|
-
e[
|
394
|
-
e[
|
409
|
+
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"]) || ""; p1 = e["diagnosis"].index("__") || -1
|
410
|
+
e["diagnosis"] = e["diagnosis"][0, p1] if p1 > 1
|
395
411
|
|
396
|
-
|
412
|
+
if e["rhost"].empty?
|
397
413
|
# Get the remote host name
|
398
414
|
# host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
|
399
|
-
p1 = e[
|
400
|
-
p2 = e[
|
401
|
-
e[
|
402
|
-
e[
|
415
|
+
p1 = e["diagnosis"].index("host ") || -1
|
416
|
+
p2 = e["diagnosis"].index(" ", p1 + 5) || -1
|
417
|
+
e["rhost"] = e["diagnosis"][p1 + 5, p2 - p1 - 5] if p1 > -1
|
418
|
+
e["rhost"] = recvdtoken[1] if e["rhost"].empty?
|
403
419
|
end
|
404
|
-
e[
|
420
|
+
e["lhost"] = recvdtoken[0] if e["lhost"].empty?
|
405
421
|
|
406
|
-
|
422
|
+
if e["command"].empty?
|
407
423
|
# Get the SMTP command name for the session
|
408
|
-
|
424
|
+
StartingOf["command"].each do |r|
|
409
425
|
# Verify each regular expression of SMTP commands
|
410
|
-
if
|
411
|
-
|
412
|
-
|
413
|
-
end
|
426
|
+
next if e["diagnosis"].include?(r) == false
|
427
|
+
e["command"] = Sisimai::SMTP::Command.find(e["diagnosis"]); next if e["command"].empty?
|
428
|
+
break
|
414
429
|
end
|
415
430
|
|
416
431
|
# Detect the reason of bounce
|
417
|
-
if %w[HELO EHLO].index(e[
|
432
|
+
if %w[HELO EHLO].index(e["command"])
|
418
433
|
# HELO | Connected to 192.0.2.135 but my name was rejected.
|
419
|
-
e[
|
434
|
+
e["reason"] = "blocked"
|
420
435
|
|
421
|
-
elsif e[
|
436
|
+
elsif e["command"] == "MAIL"
|
422
437
|
# MAIL | Connected to 192.0.2.135 but sender was rejected.
|
423
|
-
e[
|
438
|
+
e["reason"] = "onhold"
|
439
|
+
|
424
440
|
else
|
425
|
-
#
|
441
|
+
# Try to match the error message with each message pattern
|
426
442
|
MessagesOf.each_key do |r|
|
427
|
-
# Check each
|
428
|
-
next unless MessagesOf[r].any? { |a| e[
|
429
|
-
e[
|
443
|
+
# Check each message pattern
|
444
|
+
next unless MessagesOf[r].any? { |a| e["diagnosis"].include?(a) }
|
445
|
+
e["reason"] = r
|
430
446
|
break
|
431
447
|
end
|
432
448
|
|
433
|
-
|
434
|
-
# The reason "expired"
|
435
|
-
e[
|
436
|
-
e[
|
449
|
+
if e["reason"].empty?
|
450
|
+
# The reason "expired", or "mailererror"
|
451
|
+
e["reason"] = "expired" if DelayedFor.any? { |a| e["diagnosis"].include?(a) }
|
452
|
+
e["reason"] = "mailererror" if e["reason"].empty? && e["diagnosis"].include?("pipe to |")
|
437
453
|
end
|
438
454
|
end
|
439
455
|
end
|
@@ -447,52 +463,26 @@ module Sisimai::Lhost
|
|
447
463
|
#
|
448
464
|
# The value of "Status:" indicates permanent error but the value of SMTP reply code in
|
449
465
|
# Diagnostic-Code: field is "TEMPERROR"!!!!
|
450
|
-
|
451
|
-
cr =
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
while true
|
456
|
-
# "Status:" field did not exist in the bounce message
|
457
|
-
break if cs
|
458
|
-
break unless cr
|
459
|
-
|
460
|
-
# Check SMTP reply code, Generate pseudo DSN code from SMTP reply code
|
461
|
-
r1 = cr[0, 1].to_i
|
462
|
-
if r1 == 4
|
463
|
-
# Get the internal DSN(temporary error)
|
464
|
-
cs = Sisimai::SMTP::Status.code(e['reason'], true)
|
465
|
-
|
466
|
-
elsif r1 == 5
|
467
|
-
# Get the internal DSN(permanent error)
|
468
|
-
cs = Sisimai::SMTP::Status.code(e['reason'], false)
|
469
|
-
end
|
470
|
-
break
|
471
|
-
end
|
466
|
+
re = e["reason"]
|
467
|
+
cr = Sisimai::SMTP::Reply.find(e["diagnosis"], e["status"])
|
468
|
+
cs = Sisimai::SMTP::Status.find(e["diagnosis"], cr)
|
469
|
+
cv = ""
|
472
470
|
|
473
|
-
|
474
|
-
|
475
|
-
|
471
|
+
if cr[0,1] == "4" || re == "expired" || re == "mailboxfull"
|
472
|
+
# Set the pseudo status code as a temporary error
|
473
|
+
cv = Sisimai::SMTP::Status.code(re, true)
|
476
474
|
|
477
|
-
if v1 > 0
|
478
|
-
# Status or SMTP reply code exists, Set pseudo DSN into the value of "status" accessor
|
479
|
-
e['status'] = cs if r1 > 0
|
480
475
|
else
|
481
|
-
#
|
482
|
-
|
483
|
-
# Set pseudo DSN (temporary error)
|
484
|
-
Sisimai::SMTP::Status.code(e['reason'], true)
|
485
|
-
else
|
486
|
-
# Set pseudo DSN (permanent error)
|
487
|
-
Sisimai::SMTP::Status.code(e['reason'], false)
|
488
|
-
end
|
476
|
+
# Set the pseudo status code as a permanent error
|
477
|
+
cv = Sisimai::SMTP::Status.code(re, false)
|
489
478
|
end
|
490
|
-
e[
|
479
|
+
e["replycode"] = cr if e["replycode"].empty?
|
480
|
+
e["status"] = Sisimai::SMTP::Status.prefer(cs, cv, cr) if e["status"].empty?
|
491
481
|
end
|
492
482
|
|
493
|
-
return {
|
483
|
+
return { "ds" => dscontents, "rfc822" => emailparts[1] }
|
494
484
|
end
|
495
|
-
def description; return
|
485
|
+
def description; return "Exim"; end
|
496
486
|
end
|
497
487
|
end
|
498
488
|
end
|