sisimai 4.25.16 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/ANALYTICAL-PRECISION +2 -2
- data/Benchmarks.mk +3 -3
- data/CONTRIBUTING +1 -1
- data/ChangeLog.md +412 -393
- data/Developers.mk +5 -6
- data/Gemfile +1 -1
- data/Makefile +15 -15
- data/README-JA.md +140 -78
- data/README.md +290 -143
- data/Rakefile +9 -3
- data/Repository.mk +2 -3
- data/lib/sisimai/address.rb +118 -74
- data/lib/sisimai/arf.rb +84 -82
- data/lib/sisimai/datetime.rb +5 -52
- data/lib/sisimai/{data → fact}/json.rb +7 -9
- data/lib/sisimai/fact/yaml.rb +31 -0
- data/lib/sisimai/fact.rb +468 -0
- data/lib/sisimai/lhost/activehunter.rb +12 -14
- data/lib/sisimai/lhost/amavis.rb +11 -14
- data/lib/sisimai/lhost/amazonses.rb +37 -41
- data/lib/sisimai/lhost/amazonworkmail.rb +15 -18
- data/lib/sisimai/lhost/aol.rb +12 -14
- data/lib/sisimai/lhost/apachejames.rb +19 -21
- data/lib/sisimai/lhost/barracuda.rb +10 -12
- data/lib/sisimai/lhost/bigfoot.rb +21 -21
- data/lib/sisimai/lhost/biglobe.rb +15 -16
- data/lib/sisimai/lhost/courier.rb +20 -20
- data/lib/sisimai/lhost/domino.rb +23 -19
- data/lib/sisimai/lhost/einsundeins.rb +23 -18
- data/lib/sisimai/lhost/exchange2003.rb +30 -29
- data/lib/sisimai/lhost/exchange2007.rb +70 -58
- data/lib/sisimai/lhost/exim.rb +175 -161
- data/lib/sisimai/lhost/ezweb.rb +31 -56
- data/lib/sisimai/lhost/facebook.rb +21 -33
- data/lib/sisimai/lhost/fml.rb +43 -48
- data/lib/sisimai/lhost/gmail.rb +29 -29
- data/lib/sisimai/lhost/gmx.rb +18 -17
- data/lib/sisimai/lhost/googlegroups.rb +9 -10
- data/lib/sisimai/lhost/gsuite.rb +21 -27
- data/lib/sisimai/lhost/imailserver.rb +25 -39
- data/lib/sisimai/lhost/interscanmss.rb +28 -31
- data/lib/sisimai/lhost/kddi.rb +22 -28
- data/lib/sisimai/lhost/mailfoundry.rb +11 -12
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
- data/lib/sisimai/lhost/mailru.rb +33 -27
- data/lib/sisimai/lhost/mcafee.rb +21 -31
- data/lib/sisimai/lhost/messagelabs.rb +17 -20
- data/lib/sisimai/lhost/messagingserver.rb +40 -37
- data/lib/sisimai/lhost/mfilter.rb +15 -16
- data/lib/sisimai/lhost/mxlogic.rb +24 -23
- data/lib/sisimai/lhost/notes.rb +17 -17
- data/lib/sisimai/lhost/office365.rb +63 -27
- data/lib/sisimai/lhost/opensmtpd.rb +12 -13
- data/lib/sisimai/lhost/outlook.rb +12 -15
- data/lib/sisimai/lhost/postfix.rb +179 -129
- data/lib/sisimai/lhost/powermta.rb +12 -14
- data/lib/sisimai/lhost/qmail.rb +44 -47
- data/lib/sisimai/lhost/receivingses.rb +15 -20
- data/lib/sisimai/lhost/sendgrid.rb +34 -32
- data/lib/sisimai/lhost/sendmail.rb +66 -53
- data/lib/sisimai/lhost/surfcontrol.rb +19 -19
- data/lib/sisimai/lhost/v5sendmail.rb +45 -39
- data/lib/sisimai/lhost/verizon.rb +35 -39
- data/lib/sisimai/lhost/x1.rb +18 -17
- data/lib/sisimai/lhost/x2.rb +17 -14
- data/lib/sisimai/lhost/x3.rb +19 -19
- data/lib/sisimai/lhost/x4.rb +72 -57
- data/lib/sisimai/lhost/x5.rb +17 -19
- data/lib/sisimai/lhost/x6.rb +41 -17
- data/lib/sisimai/lhost/yahoo.rb +17 -16
- data/lib/sisimai/lhost/yandex.rb +16 -20
- data/lib/sisimai/lhost/zoho.rb +16 -15
- data/lib/sisimai/lhost.rb +8 -10
- data/lib/sisimai/mail/maildir.rb +1 -3
- data/lib/sisimai/mail/mbox.rb +3 -4
- data/lib/sisimai/mail/memory.rb +0 -1
- data/lib/sisimai/mail/stdin.rb +1 -3
- data/lib/sisimai/mail.rb +3 -7
- data/lib/sisimai/mda.rb +28 -42
- data/lib/sisimai/message.rb +435 -326
- data/lib/sisimai/order.rb +5 -5
- data/lib/sisimai/reason/authfailure.rb +64 -0
- data/lib/sisimai/reason/badreputation.rb +53 -0
- data/lib/sisimai/reason/blocked.rb +94 -160
- data/lib/sisimai/reason/contenterror.rb +8 -9
- data/lib/sisimai/reason/delivered.rb +4 -6
- data/lib/sisimai/reason/exceedlimit.rb +10 -12
- data/lib/sisimai/reason/expired.rb +6 -8
- data/lib/sisimai/reason/feedback.rb +2 -3
- data/lib/sisimai/reason/filtered.rb +17 -19
- data/lib/sisimai/reason/hasmoved.rb +9 -10
- data/lib/sisimai/reason/hostunknown.rb +15 -15
- data/lib/sisimai/reason/mailboxfull.rb +10 -12
- data/lib/sisimai/reason/mailererror.rb +18 -20
- data/lib/sisimai/reason/mesgtoobig.rb +9 -11
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +8 -11
- data/lib/sisimai/reason/notaccept.rb +13 -14
- data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +14 -12
- data/lib/sisimai/reason/rejected.rb +26 -24
- data/lib/sisimai/reason/requireptr.rb +69 -0
- data/lib/sisimai/reason/securityerror.rb +33 -36
- data/lib/sisimai/reason/spamdetected.rb +114 -147
- data/lib/sisimai/reason/speeding.rb +49 -0
- data/lib/sisimai/reason/suspend.rb +11 -11
- data/lib/sisimai/reason/syntaxerror.rb +11 -10
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +7 -8
- data/lib/sisimai/reason/toomanyconn.rb +9 -11
- data/lib/sisimai/reason/undefined.rb +2 -3
- data/lib/sisimai/reason/userunknown.rb +129 -146
- data/lib/sisimai/reason/vacation.rb +3 -4
- data/lib/sisimai/reason/virusdetected.rb +10 -11
- data/lib/sisimai/reason.rb +59 -64
- data/lib/sisimai/rfc1894.rb +55 -28
- data/lib/sisimai/rfc2045.rb +373 -0
- data/lib/sisimai/rfc3464.rb +250 -308
- data/lib/sisimai/rfc3834.rb +42 -45
- data/lib/sisimai/rfc5322.rb +75 -100
- data/lib/sisimai/rfc5965.rb +31 -0
- data/lib/sisimai/rhost/cox.rb +5 -6
- data/lib/sisimai/rhost/franceptt.rb +6 -8
- data/lib/sisimai/rhost/godaddy.rb +12 -12
- data/lib/sisimai/rhost/{googleapps.rb → google.rb} +80 -72
- data/lib/sisimai/rhost/iua.rb +9 -10
- data/lib/sisimai/rhost/kddi.rb +6 -8
- data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
- data/lib/sisimai/rhost/mimecast.rb +42 -40
- data/lib/sisimai/rhost/nttdocomo.rb +12 -12
- data/lib/sisimai/rhost/spectrum.rb +10 -12
- data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
- data/lib/sisimai/rhost.rb +23 -31
- data/lib/sisimai/smtp/command.rb +59 -0
- data/lib/sisimai/smtp/error.rb +4 -7
- data/lib/sisimai/smtp/reply.rb +161 -74
- data/lib/sisimai/smtp/status.rb +504 -393
- data/lib/sisimai/smtp/transcript.rb +124 -0
- data/lib/sisimai/smtp.rb +0 -1
- data/lib/sisimai/string.rb +74 -5
- data/lib/sisimai/time.rb +1 -2
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +35 -21
- data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
- data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
- data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
- data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
- data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
- data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
- data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
- data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +41 -20
- data/.rspec +0 -2
- data/lib/sisimai/data/yaml.rb +0 -33
- data/lib/sisimai/data.rb +0 -411
- data/lib/sisimai/mime.rb +0 -456
- /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
data/lib/sisimai/lhost/yandex.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Yandex parses a bounce email which created by Yandex.Mail.
|
3
|
-
#
|
2
|
+
# Sisimai::Lhost::Yandex parses a bounce email which created by Yandex.Mail. Methods in the module
|
3
|
+
# are called from only Sisimai::Message.
|
4
4
|
module Yandex
|
5
5
|
class << self
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/Yandex.pm
|
7
6
|
require 'sisimai/lhost'
|
8
7
|
|
9
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
-
|
9
|
+
Boundaries = ['Content-Type: message/rfc822'].freeze
|
11
10
|
StartingOf = { message: ['This is the mail system at host yandex.ru.'] }.freeze
|
12
11
|
|
13
12
|
# Parse bounce messages from Yandex.Mail
|
@@ -15,7 +14,7 @@ module Sisimai::Lhost
|
|
15
14
|
# @param [String] mbody Message body of a bounce email
|
16
15
|
# @return [Hash] Bounce data list and message/rfc822 part
|
17
16
|
# @return [Nil] it failed to parse or the arguments are missing
|
18
|
-
def
|
17
|
+
def inquire(mhead, mbody)
|
19
18
|
# X-Yandex-Front: mxback1h.mail.yandex.net
|
20
19
|
# X-Yandex-TimeMark: 1417885948
|
21
20
|
# X-Yandex-Uniq: 92309766-f1c8-4bd4-92bc-657c75766587
|
@@ -26,13 +25,12 @@ module Sisimai::Lhost
|
|
26
25
|
return nil unless mhead['x-yandex-uniq']
|
27
26
|
return nil unless mhead['from'] == 'mailer-daemon@yandex.ru'
|
28
27
|
|
29
|
-
require 'sisimai/rfc1894'
|
30
28
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
31
29
|
permessage = {} # (Hash) Store values of each Per-Message field
|
32
30
|
|
33
31
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
34
|
-
|
35
|
-
bodyslices =
|
32
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
33
|
+
bodyslices = emailparts[0].split("\n")
|
36
34
|
readslices = ['']
|
37
35
|
readcursor = 0 # (Integer) Points the current cursor position
|
38
36
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
@@ -40,8 +38,8 @@ module Sisimai::Lhost
|
|
40
38
|
v = nil
|
41
39
|
|
42
40
|
while e = bodyslices.shift do
|
43
|
-
# Read error messages and delivery status lines from the head of the email
|
44
|
-
#
|
41
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
42
|
+
# line of the beginning of the original message.
|
45
43
|
readslices << e # Save the current line for the next loop
|
46
44
|
|
47
45
|
if readcursor == 0
|
@@ -82,23 +80,21 @@ module Sisimai::Lhost
|
|
82
80
|
next unless fieldtable[o[0]]
|
83
81
|
v[fieldtable[o[0]]] = o[2]
|
84
82
|
|
85
|
-
next unless f
|
83
|
+
next unless f
|
86
84
|
permessage[fieldtable[o[0]]] = o[2]
|
87
85
|
end
|
88
86
|
else
|
89
87
|
# The line does not begin with a DSN field defined in RFC3464
|
90
|
-
if
|
88
|
+
if e.include?(' (in reply to ') || e.include?('command)')
|
91
89
|
# 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
|
92
|
-
|
90
|
+
cv = Sisimai::SMTP::Command.find(e)
|
91
|
+
commandset << cv if cv
|
93
92
|
|
94
|
-
elsif cv = e.match(/([A-Z]{4})[ \t]*.*command[)]\z/)
|
95
|
-
# to MAIL command)
|
96
|
-
commandset << cv[1]
|
97
93
|
else
|
98
94
|
# Continued line of the value of Diagnostic-Code field
|
99
95
|
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
100
|
-
next unless
|
101
|
-
v['diagnosis'] << ' ' <<
|
96
|
+
next unless e.start_with?(' ')
|
97
|
+
v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
|
102
98
|
readslices[-1] = 'Diagnostic-Code: ' << e
|
103
99
|
end
|
104
100
|
end
|
@@ -110,11 +106,11 @@ module Sisimai::Lhost
|
|
110
106
|
e['lhost'] ||= permessage['rhost']
|
111
107
|
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
112
108
|
|
113
|
-
e['command'] = commandset.shift || ''
|
114
109
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
|
110
|
+
e['command'] ||= commandset.shift || Sisimai::SMTP::Command.find(e['diagnosis']) || ''
|
115
111
|
end
|
116
112
|
|
117
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
113
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
118
114
|
end
|
119
115
|
def description; return 'Yandex.Mail: https://www.yandex.ru'; end
|
120
116
|
end
|
data/lib/sisimai/lhost/zoho.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Zoho parses a bounce email which created by Zoho Mail.
|
3
|
-
#
|
2
|
+
# Sisimai::Lhost::Zoho parses a bounce email which created by Zoho Mail. Methods in the module are
|
3
|
+
# called from only Sisimai::Message.
|
4
4
|
module Zoho
|
5
5
|
class << self
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/Zoho.pm
|
7
6
|
require 'sisimai/lhost'
|
8
7
|
|
9
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
10
|
-
|
9
|
+
Boundaries = ['Received: from mail.zoho.com by mx.zohomail.com'].freeze
|
11
10
|
StartingOf = { message: ['This message was created automatically by mail delivery'] }.freeze
|
12
11
|
MessagesOf = { 'expired' => ['Host not reachable'] }.freeze
|
13
12
|
|
@@ -16,23 +15,23 @@ module Sisimai::Lhost
|
|
16
15
|
# @param [String] mbody Message body of a bounce email
|
17
16
|
# @return [Hash] Bounce data list and message/rfc822 part
|
18
17
|
# @return [Nil] it failed to parse or the arguments are missing
|
19
|
-
def
|
18
|
+
def inquire(mhead, mbody)
|
20
19
|
# X-ZohoMail: Si CHF_MF_NL SS_10 UW48 UB48 FMWL UW48 UB48 SGR3_1_09124_42
|
21
20
|
# X-Zoho-Virus-Status: 2
|
22
21
|
# X-Mailer: Zoho Mail
|
23
22
|
return nil unless mhead['x-zohomail']
|
24
23
|
|
25
24
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
26
|
-
|
27
|
-
bodyslices =
|
25
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
26
|
+
bodyslices = emailparts[0].split("\n")
|
28
27
|
readcursor = 0 # (Integer) Points the current cursor position
|
29
28
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
30
29
|
qprintable = false
|
31
30
|
v = nil
|
32
31
|
|
33
32
|
while e = bodyslices.shift do
|
34
|
-
# Read error messages and delivery status lines from the head of the email
|
35
|
-
#
|
33
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
34
|
+
# line of the beginning of the original message.
|
36
35
|
if readcursor == 0
|
37
36
|
# Beginning of the bounce message or delivery status part
|
38
37
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
@@ -54,15 +53,15 @@ module Sisimai::Lhost
|
|
54
53
|
# shironeko@example.org Invalid Address, ERROR_CODE :550, ERROR_CODE :Requested action not taken: mailbox unavailable
|
55
54
|
v = dscontents[-1]
|
56
55
|
|
57
|
-
if
|
56
|
+
if Sisimai::String.aligned(e, ['@', ' ', 'ERROR_CODE :'])
|
58
57
|
# kijitora@example.co.jp Invalid Address, ERROR_CODE :550, ERROR_CODE :5.1.=
|
59
58
|
if v['recipient']
|
60
59
|
# There are multiple recipient addresses in the message body.
|
61
60
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
62
61
|
v = dscontents[-1]
|
63
62
|
end
|
64
|
-
v['recipient'] =
|
65
|
-
v['diagnosis'] =
|
63
|
+
v['recipient'] = e[0, e.index(' ')]
|
64
|
+
v['diagnosis'] = e[e.index(' ') + 1, e.size]
|
66
65
|
|
67
66
|
if v['diagnosis'].end_with?('=')
|
68
67
|
# Quoted printable
|
@@ -71,7 +70,7 @@ module Sisimai::Lhost
|
|
71
70
|
end
|
72
71
|
recipients += 1
|
73
72
|
|
74
|
-
elsif
|
73
|
+
elsif e.start_with?('[Status: ')
|
75
74
|
# Expired
|
76
75
|
# [Status: Error, Address: <kijitora@6kaku.example.co.jp>, ResponseCode 421, , Host not reachable.]
|
77
76
|
if v['recipient']
|
@@ -79,7 +78,9 @@ module Sisimai::Lhost
|
|
79
78
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
80
79
|
v = dscontents[-1]
|
81
80
|
end
|
82
|
-
|
81
|
+
p1 = e.index('<')
|
82
|
+
p2 = e.index('>', p1 + 2)
|
83
|
+
v['recipient'] = Sisimai::Address.s3s4(e[p1, p2 - p1])
|
83
84
|
v['diagnosis'] = e
|
84
85
|
recipients += 1
|
85
86
|
else
|
@@ -100,7 +101,7 @@ module Sisimai::Lhost
|
|
100
101
|
end
|
101
102
|
end
|
102
103
|
|
103
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
104
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
104
105
|
end
|
105
106
|
def description; return 'Zoho Mail: https://www.zoho.com'; end
|
106
107
|
end
|
data/lib/sisimai/lhost.rb
CHANGED
@@ -2,7 +2,6 @@ module Sisimai
|
|
2
2
|
# Sisimai::Lhost - Base class for Sisimai::Lhost::*
|
3
3
|
module Lhost
|
4
4
|
class << self
|
5
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost.pm
|
6
5
|
require 'sisimai/rfc5322'
|
7
6
|
|
8
7
|
# Data structure for parsed bounce messages
|
@@ -23,7 +22,7 @@ module Sisimai
|
|
23
22
|
'replycode' => nil, # SMTP Reply code
|
24
23
|
'diagnosis' => nil, # The value of Diagnostic-Code header
|
25
24
|
'recipient' => nil, # The value of Final-Recipient header
|
26
|
-
'
|
25
|
+
'hardbounce' => nil, # Hard bounce or not
|
27
26
|
'feedbacktype' => nil, # Feedback Type
|
28
27
|
}
|
29
28
|
end
|
@@ -42,13 +41,12 @@ module Sisimai
|
|
42
41
|
# @return [Array] MTA list with order
|
43
42
|
def index
|
44
43
|
return %w[
|
45
|
-
Activehunter Amavis AmazonSES AmazonWorkMail Aol ApacheJames Barracuda Bigfoot
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
Qmail
|
44
|
+
Activehunter Amavis AmazonSES AmazonWorkMail Aol ApacheJames Barracuda Bigfoot Biglobe
|
45
|
+
Courier Domino EZweb EinsUndEins Exchange2003 Exchange2007 Exim FML Facebook GMX GSuite
|
46
|
+
GoogleGroups Gmail IMailServer InterScanMSS KDDI MXLogic MailFoundry MailMarshalSMTP
|
47
|
+
MailRu McAfee MessageLabs MessagingServer Notes Office365 OpenSMTPD Outlook Postfix
|
48
|
+
PowerMTA ReceivingSES SendGrid Sendmail SurfControl V5sendmail Verizon X1 X2 X3 X4 X5 X6
|
49
|
+
Yahoo Yandex Zoho MFILTER Qmail
|
52
50
|
]
|
53
51
|
end
|
54
52
|
|
@@ -71,7 +69,7 @@ module Sisimai
|
|
71
69
|
# @param [String] mbody Message body of a bounce email
|
72
70
|
# @return [Hash] Bounce data list and message/rfc822 part
|
73
71
|
# @return [Nil] it failed to parse or the arguments are missing
|
74
|
-
def
|
72
|
+
def inquire; return nil; end
|
75
73
|
def description; return ''; end
|
76
74
|
end
|
77
75
|
end
|
data/lib/sisimai/mail/maildir.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
class Mail
|
3
|
-
# Sisimai::Mail::Maildir is a reader for getting contents of each email in
|
4
|
-
# the Maildir/ directory.
|
3
|
+
# Sisimai::Mail::Maildir is a reader for getting contents of each email in the Maildir/ directory.
|
5
4
|
class Maildir
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Mail/Maildir.pm
|
7
5
|
# :dir [String] Path to Maildir/
|
8
6
|
# :size [Integer] The number of files/directories in the Maildir/
|
9
7
|
# :path [String] Path to each file
|
data/lib/sisimai/mail/mbox.rb
CHANGED
@@ -2,7 +2,6 @@ module Sisimai
|
|
2
2
|
class Mail
|
3
3
|
# Sisimai::Mail::Mbox is a mailbox file (UNIX mbox) reader.
|
4
4
|
class Mbox
|
5
|
-
# Imported from p5-Sisimail/lib/Sisimai/Mail/Mbox.pm
|
6
5
|
# :dir [String] Directory name of the mbox
|
7
6
|
# :file [String] File name of the mbox
|
8
7
|
# :path [String] Path to mbox
|
@@ -13,9 +12,9 @@ module Sisimai
|
|
13
12
|
attr_accessor :offset, :handle
|
14
13
|
|
15
14
|
# Constructor of Sisimai::Mail::Mbox
|
16
|
-
# @param [String] argv1
|
17
|
-
# @return [Sisimai::Mail::Mbox
|
18
|
-
#
|
15
|
+
# @param [String] argv1 Path to mbox
|
16
|
+
# @return [Sisimai::Mail::Mbox] Object
|
17
|
+
# [Nil] is not specified or does not exist
|
19
18
|
def initialize(argv1)
|
20
19
|
raise Errno::ENOENT unless File.exist?(argv1)
|
21
20
|
raise 'is not a file' unless File.ftype(argv1) == 'file'
|
data/lib/sisimai/mail/memory.rb
CHANGED
@@ -2,7 +2,6 @@ module Sisimai
|
|
2
2
|
class Mail
|
3
3
|
# Sisimai::Mail::Memory is a class for reading an email string
|
4
4
|
class Memory
|
5
|
-
# Imported from p5-Sisimail/lib/Sisimai/Mail/Memory.pm
|
6
5
|
# :path [String] Fixed string "<MEMORY>"
|
7
6
|
# :size [Integer] data size of the email text
|
8
7
|
# :payload [Array] Entire bounce mail message
|
data/lib/sisimai/mail/stdin.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
2
|
class Mail
|
3
|
-
# Sisimai::Mail::STDIN is a reader for getting contents of each email from
|
4
|
-
# STDIN
|
3
|
+
# Sisimai::Mail::STDIN is a reader for getting contents of each email from STDIN
|
5
4
|
class STDIN
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Mail/STDIN.pm
|
7
5
|
# :path [String] Fixed string "<STDIN>"
|
8
6
|
# :size [Integer] Data size which has been read
|
9
7
|
# :offset [Integer] The number of emails which have neen read
|
data/lib/sisimai/mail.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
module Sisimai
|
2
|
-
# Sisimai::Mail is a handler of UNIX mbox or Maildir for reading each mail.
|
3
|
-
#
|
4
|
-
# Sisimai::Mail::Memory classes.
|
2
|
+
# Sisimai::Mail is a handler of UNIX mbox or Maildir for reading each mail. It is a wrapper class
|
3
|
+
# of Sisimai::Mail::Mbox, Sisimai::Mail::Maildir, and Sisimai::Mail::Memory classes.
|
5
4
|
class Mail
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Mail.pm
|
7
|
-
|
8
5
|
# :path [String] path to mbox or Maildir/
|
9
6
|
# :kind [String] Data type: mailbox, maildir, or stdin
|
10
7
|
# :data [Sisimai::Mail::[Mbox,Maildir,Memory,STDIN]] Object
|
@@ -47,8 +44,7 @@ module Sisimai
|
|
47
44
|
end
|
48
45
|
end
|
49
46
|
elsif argv1.is_a?(IO)
|
50
|
-
# Read from STDIN
|
51
|
-
# The argument neither a mailbox nor a Maildir/.
|
47
|
+
# Read from STDIN, The argument neither a mailbox nor a Maildir/.
|
52
48
|
classname = self.class.to_s << '::STDIN'
|
53
49
|
parameter['kind'] = 'stdin'
|
54
50
|
parameter['path'] = '<STDIN>'
|
data/lib/sisimai/mda.rb
CHANGED
@@ -1,25 +1,17 @@
|
|
1
1
|
module Sisimai
|
2
2
|
# Sisimai::MDA - Error message parser for MDA
|
3
3
|
module MDA
|
4
|
-
# Imported from p5-Sisimail/lib/Sisimai/MDA.pm
|
5
4
|
class << self
|
6
5
|
AgentNames = {
|
7
6
|
# dovecot/src/deliver/deliver.c
|
8
7
|
# 11: #define DEFAULT_MAIL_REJECTION_HUMAN_REASON \
|
9
8
|
# 12: "Your message to <%t> was automatically rejected:%n%r"
|
10
|
-
'dovecot' =>
|
11
|
-
'mail.local' =>
|
12
|
-
'procmail' =>
|
13
|
-
'maildrop' =>
|
14
|
-
'vpopmail' =>
|
15
|
-
'vmailmgr' =>
|
16
|
-
}.freeze
|
17
|
-
MarkingsOf = {
|
18
|
-
message: %r{\A(?>
|
19
|
-
Your[ ]message[ ]to[ ][^ ]+[ ]was[ ]automatically[ ]rejected:\z
|
20
|
-
|(?:mail[.]local|procmail|maildrop|vdelivermail|vdeliver):[ ]
|
21
|
-
)
|
22
|
-
}x
|
9
|
+
'dovecot' => ['Your message to ', ' was automatically rejected:'],
|
10
|
+
'mail.local' => ['mail.local: '],
|
11
|
+
'procmail' => ['procmail: '],
|
12
|
+
'maildrop' => ['maildrop: '],
|
13
|
+
'vpopmail' => ['vdelivermail: '],
|
14
|
+
'vmailmgr' => ['vdeliver: '],
|
23
15
|
}.freeze
|
24
16
|
|
25
17
|
# dovecot/src/deliver/mail-send.c:94
|
@@ -79,43 +71,37 @@ module Sisimai
|
|
79
71
|
# @param [String] mbody Message body of a bounce email
|
80
72
|
# @return [Hash] Bounce data list and message/rfc822 part
|
81
73
|
# @return [Nil] it failed to parse or the arguments are missing
|
82
|
-
def
|
74
|
+
def inquire(mhead, mbody)
|
75
|
+
return nil unless mhead
|
76
|
+
return nil unless mbody.size > 0
|
83
77
|
return nil unless mhead['from'].downcase.start_with?('mail delivery subsystem','mailer-daemon', 'postmaster')
|
84
78
|
|
85
|
-
|
79
|
+
deliversby = '' # [String] Mail Delivery Agent name
|
86
80
|
reasonname = '' # [String] Error reason
|
87
81
|
bouncemesg = '' # [String] Error message
|
88
|
-
|
89
|
-
linebuffer = []
|
82
|
+
linebuffer = mbody.split("\n")
|
90
83
|
|
91
|
-
|
92
|
-
#
|
93
|
-
|
94
|
-
|
95
|
-
next if e.empty?
|
96
|
-
next unless e =~ MarkingsOf[:message]
|
84
|
+
AgentNames.each_key do |e|
|
85
|
+
# Find a mail delivery agent name from the entire message body
|
86
|
+
p = mbody.index(AgentNames[e][0])
|
87
|
+
next unless p
|
97
88
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
89
|
+
if AgentNames[e].size > 1
|
90
|
+
# Try to find the 2nd argument
|
91
|
+
q = mbody.index(AgentNames[e][1])
|
92
|
+
next unless q
|
93
|
+
next if p > q
|
104
94
|
end
|
105
|
-
|
106
|
-
|
107
|
-
linebuffer << e
|
108
|
-
break if e.empty?
|
95
|
+
deliversby = e
|
96
|
+
break
|
109
97
|
end
|
110
|
-
return nil if
|
111
|
-
return nil if linebuffer.empty?
|
98
|
+
return nil if deliversby.empty?
|
112
99
|
|
113
|
-
MessagesOf[
|
100
|
+
MessagesOf[deliversby].each_key do |e|
|
114
101
|
# Detect an error reason from message patterns of the MDA.
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
next unless MessagesOf[agentname0][e].any? { |a| f.downcase.include?(a) }
|
102
|
+
linebuffer.each do |f|
|
103
|
+
# Whether the error message include each message defined in MessagesOf
|
104
|
+
next unless MessagesOf[deliversby][e].any? { |a| f.downcase.include?(a) }
|
119
105
|
reasonname = e
|
120
106
|
bouncemesg = f
|
121
107
|
break
|
@@ -124,7 +110,7 @@ module Sisimai
|
|
124
110
|
end
|
125
111
|
|
126
112
|
return {
|
127
|
-
'mda' =>
|
113
|
+
'mda' => deliversby,
|
128
114
|
'reason' => reasonname || '',
|
129
115
|
'message' => bouncemesg || '',
|
130
116
|
}
|