sisimai 4.24.1-java → 4.25.0-java
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sisimai might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/ANALYTICAL-PRECISION +16 -25
- data/ChangeLog.md +41 -0
- data/Developers.mk +2 -2
- data/README-JA.md +13 -13
- data/README.md +13 -13
- data/lib/sisimai.rb +3 -7
- data/lib/sisimai/address.rb +25 -41
- data/lib/sisimai/arf.rb +58 -59
- data/lib/sisimai/bite.rb +0 -1
- data/lib/sisimai/bite/email.rb +7 -7
- data/lib/sisimai/bite/email/activehunter.rb +4 -3
- data/lib/sisimai/bite/email/amavis.rb +133 -0
- data/lib/sisimai/bite/email/amazonses.rb +53 -87
- data/lib/sisimai/bite/email/amazonworkmail.rb +51 -57
- data/lib/sisimai/bite/email/aol.rb +50 -76
- data/lib/sisimai/bite/email/apachejames.rb +2 -2
- data/lib/sisimai/bite/email/bigfoot.rb +47 -74
- data/lib/sisimai/bite/email/biglobe.rb +8 -9
- data/lib/sisimai/bite/email/courier.rb +56 -101
- data/lib/sisimai/bite/email/domino.rb +7 -8
- data/lib/sisimai/bite/email/einsundeins.rb +4 -5
- data/lib/sisimai/bite/email/exchange2003.rb +21 -22
- data/lib/sisimai/bite/email/exchange2007.rb +26 -28
- data/lib/sisimai/bite/email/exim.rb +48 -47
- data/lib/sisimai/bite/email/ezweb.rb +24 -36
- data/lib/sisimai/bite/email/facebook.rb +54 -79
- data/lib/sisimai/bite/email/fml.rb +10 -10
- data/lib/sisimai/bite/email/gmx.rb +6 -6
- data/lib/sisimai/bite/email/google.rb +12 -13
- data/lib/sisimai/bite/email/gsuite.rb +80 -108
- data/lib/sisimai/bite/email/imailserver.rb +16 -16
- data/lib/sisimai/bite/email/interscanmss.rb +4 -6
- data/lib/sisimai/bite/email/kddi.rb +9 -11
- data/lib/sisimai/bite/email/mailfoundry.rb +2 -2
- data/lib/sisimai/bite/email/mailmarshalsmtp.rb +2 -2
- data/lib/sisimai/bite/email/mailru.rb +12 -13
- data/lib/sisimai/bite/email/mcafee.rb +31 -25
- data/lib/sisimai/bite/email/messagelabs.rb +48 -87
- data/lib/sisimai/bite/email/messagingserver.rb +9 -10
- data/lib/sisimai/bite/email/mfilter.rb +16 -16
- data/lib/sisimai/bite/email/mxlogic.rb +11 -11
- data/lib/sisimai/bite/email/notes.rb +5 -6
- data/lib/sisimai/bite/email/office365.rb +25 -42
- data/lib/sisimai/bite/email/opensmtpd.rb +8 -8
- data/lib/sisimai/bite/email/outlook.rb +49 -67
- data/lib/sisimai/bite/email/postfix.rb +78 -112
- data/lib/sisimai/bite/email/qmail.rb +23 -23
- data/lib/sisimai/bite/email/receivingses.rb +53 -86
- data/lib/sisimai/bite/email/sendgrid.rb +65 -84
- data/lib/sisimai/bite/email/sendmail.rb +89 -117
- data/lib/sisimai/bite/email/surfcontrol.rb +15 -18
- data/lib/sisimai/bite/email/userdefined.rb +1 -1
- data/lib/sisimai/bite/email/v5sendmail.rb +3 -4
- data/lib/sisimai/bite/email/verizon.rb +7 -8
- data/lib/sisimai/bite/email/x1.rb +2 -2
- data/lib/sisimai/bite/email/x2.rb +2 -2
- data/lib/sisimai/bite/email/x3.rb +3 -3
- data/lib/sisimai/bite/email/x4.rb +22 -22
- data/lib/sisimai/bite/email/x5.rb +40 -49
- data/lib/sisimai/bite/email/yahoo.rb +3 -3
- data/lib/sisimai/bite/email/yandex.rb +54 -82
- data/lib/sisimai/bite/email/zoho.rb +6 -6
- data/lib/sisimai/bite/json/amazonses.rb +20 -20
- data/lib/sisimai/bite/json/sendgrid.rb +2 -2
- data/lib/sisimai/data.rb +27 -40
- data/lib/sisimai/datetime.rb +146 -162
- data/lib/sisimai/mda.rb +30 -31
- data/lib/sisimai/message/email.rb +83 -123
- data/lib/sisimai/message/json.rb +2 -4
- data/lib/sisimai/mime.rb +31 -34
- data/lib/sisimai/order/email.rb +23 -22
- data/lib/sisimai/reason.rb +61 -61
- data/lib/sisimai/reason/blocked.rb +139 -135
- data/lib/sisimai/reason/contenterror.rb +11 -10
- data/lib/sisimai/reason/exceedlimit.rb +4 -4
- data/lib/sisimai/reason/expired.rb +20 -20
- data/lib/sisimai/reason/filtered.rb +19 -18
- data/lib/sisimai/reason/hasmoved.rb +3 -3
- data/lib/sisimai/reason/hostunknown.rb +19 -19
- data/lib/sisimai/reason/mailboxfull.rb +49 -49
- data/lib/sisimai/reason/mailererror.rb +16 -16
- data/lib/sisimai/reason/mesgtoobig.rb +17 -17
- data/lib/sisimai/reason/networkerror.rb +19 -19
- data/lib/sisimai/reason/norelaying.rb +16 -16
- data/lib/sisimai/reason/notaccept.rb +9 -10
- data/lib/sisimai/reason/onhold.rb +1 -1
- data/lib/sisimai/reason/policyviolation.rb +21 -20
- data/lib/sisimai/reason/rejected.rb +53 -53
- data/lib/sisimai/reason/securityerror.rb +29 -29
- data/lib/sisimai/reason/spamdetected.rb +127 -127
- data/lib/sisimai/reason/suspend.rb +17 -17
- data/lib/sisimai/reason/systemerror.rb +22 -21
- data/lib/sisimai/reason/systemfull.rb +6 -6
- data/lib/sisimai/reason/toomanyconn.rb +19 -18
- data/lib/sisimai/reason/userunknown.rb +122 -121
- data/lib/sisimai/reason/vacation.rb +8 -8
- data/lib/sisimai/reason/virusdetected.rb +8 -8
- data/lib/sisimai/rfc1894.rb +142 -0
- data/lib/sisimai/rfc3464.rb +70 -70
- data/lib/sisimai/rfc3834.rb +15 -15
- data/lib/sisimai/rfc5322.rb +20 -36
- data/lib/sisimai/rhost.rb +1 -0
- data/lib/sisimai/rhost/exchangeonline.rb +31 -33
- data/lib/sisimai/rhost/franceptt.rb +23 -23
- data/lib/sisimai/rhost/godaddy.rb +28 -28
- data/lib/sisimai/rhost/googleapps.rb +39 -41
- data/lib/sisimai/rhost/kddi.rb +3 -3
- data/lib/sisimai/rhost/tencentqq.rb +51 -0
- data/lib/sisimai/smtp/error.rb +14 -21
- data/lib/sisimai/smtp/reply.rb +14 -13
- data/lib/sisimai/smtp/status.rb +178 -179
- data/lib/sisimai/string.rb +13 -12
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/README.md +1 -5
- data/set-of-emails/maildir/bsd/arf-23.eml +49 -0
- data/set-of-emails/maildir/bsd/email-amavis-01.eml +78 -0
- data/set-of-emails/maildir/bsd/email-amavis-02.eml +78 -0
- data/set-of-emails/maildir/bsd/email-exchange2007-04.eml +146 -0
- data/set-of-emails/maildir/bsd/email-exim-60.eml +94 -0
- data/set-of-emails/maildir/bsd/email-ezweb-08.eml +49 -0
- data/set-of-emails/maildir/bsd/email-google-19.eml +67 -0
- data/set-of-emails/maildir/bsd/email-mcafee-05.eml +74 -0
- data/set-of-emails/maildir/bsd/email-messagingserver-12.eml +99 -0
- data/set-of-emails/maildir/bsd/email-postfix-46.eml +81 -0
- data/set-of-emails/maildir/bsd/email-postfix-47.eml +79 -0
- data/set-of-emails/maildir/bsd/email-postfix-48.eml +79 -0
- data/set-of-emails/maildir/bsd/email-postfix-49.eml +141 -0
- data/set-of-emails/maildir/bsd/email-postfix-50.eml +143 -0
- data/set-of-emails/maildir/bsd/email-postfix-51.eml +73 -0
- data/set-of-emails/maildir/bsd/email-postfix-52.eml +79 -0
- data/set-of-emails/maildir/bsd/email-postfix-53.eml +76 -0
- data/set-of-emails/maildir/bsd/email-postfix-54.eml +73 -0
- data/set-of-emails/maildir/bsd/email-postfix-55.eml +74 -0
- data/set-of-emails/maildir/bsd/email-postfix-56.eml +78 -0
- data/set-of-emails/maildir/bsd/email-qmail-10.eml +50 -0
- data/set-of-emails/maildir/bsd/email-x2-05.eml +38 -0
- data/set-of-emails/maildir/bsd/rhost-google-apps-02.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-tencentqq-01.eml +84 -0
- data/set-of-emails/maildir/bsd/rhost-tencentqq-02.eml +84 -0
- data/set-of-emails/maildir/bsd/rhost-tencentqq-03.eml +81 -0
- data/set-of-emails/maildir/dos/email-amavis-01.eml +78 -0
- data/set-of-emails/maildir/dos/email-apachejames-01.eml +1 -2
- data/set-of-emails/maildir/dos/email-messagelabs-01.eml +67 -50
- data/set-of-emails/maildir/dos/email-x4-01.eml +31 -76
- data/set-of-emails/maildir/dos/rhost-tencentqq-01.eml +84 -0
- data/set-of-emails/maildir/mac/email-amavis-01.eml +1 -4
- data/set-of-emails/maildir/mac/email-apachejames-01.eml +1 -9
- data/set-of-emails/maildir/mac/email-messagelabs-01.eml +1 -9
- data/set-of-emails/maildir/mac/email-x4-01.eml +1 -5
- data/set-of-emails/maildir/mac/rhost-tencentqq-01.eml +1 -4
- metadata +35 -4
- data/set-of-emails/logo/horizontalversions.png +0 -0
- data/set-of-emails/logo/icon.png +0 -0
@@ -67,7 +67,7 @@ module Sisimai::Bite::Email
|
|
67
67
|
end
|
68
68
|
|
69
69
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
70
|
-
#
|
70
|
+
# Inside of the original message part
|
71
71
|
if e.empty?
|
72
72
|
blanklines += 1
|
73
73
|
break if blanklines > 1
|
@@ -75,7 +75,7 @@ module Sisimai::Bite::Email
|
|
75
75
|
end
|
76
76
|
rfc822list << e
|
77
77
|
else
|
78
|
-
#
|
78
|
+
# Error message part
|
79
79
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
80
80
|
next if e.empty?
|
81
81
|
|
@@ -32,6 +32,10 @@ module Sisimai::Bite::Email
|
|
32
32
|
match += 1 if mhead['received'].any? { |a| a.include?('.bigfoot.com') }
|
33
33
|
return nil unless match > 0
|
34
34
|
|
35
|
+
require 'sisimai/rfc1894'
|
36
|
+
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
37
|
+
permessage = {} # (Hash) Store values of each Per-Message field
|
38
|
+
|
35
39
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
36
40
|
hasdivided = mbody.split("\n")
|
37
41
|
havepassed = ['']
|
@@ -41,11 +45,6 @@ module Sisimai::Bite::Email
|
|
41
45
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
42
46
|
commandtxt = '' # (String) SMTP Command name begin with the string '>>>'
|
43
47
|
esmtpreply = '' # (String) Reply from remote server on SMTP session
|
44
|
-
connvalues = 0 # (Integer) Flag, 1 if all the value of connheader have been set
|
45
|
-
connheader = {
|
46
|
-
'date' => '', # The value of Arrival-Date header
|
47
|
-
'lhost' => '', # The value of Reporting-MTA header
|
48
|
-
}
|
49
48
|
v = nil
|
50
49
|
|
51
50
|
while e = hasdivided.shift do
|
@@ -54,7 +53,7 @@ module Sisimai::Bite::Email
|
|
54
53
|
p = havepassed[-2]
|
55
54
|
|
56
55
|
if readcursor == 0
|
57
|
-
# Beginning of the bounce message or delivery
|
56
|
+
# Beginning of the bounce message or message/delivery-status part
|
58
57
|
if e =~ MarkingsOf[:message]
|
59
58
|
readcursor |= Indicators[:deliverystatus]
|
60
59
|
next
|
@@ -62,7 +61,7 @@ module Sisimai::Bite::Email
|
|
62
61
|
end
|
63
62
|
|
64
63
|
if (readcursor & Indicators[:'message-rfc822']) == 0
|
65
|
-
# Beginning of the original message part
|
64
|
+
# Beginning of the original message part(message/rfc822)
|
66
65
|
if e.start_with?(StartingOf[:rfc822][0])
|
67
66
|
readcursor |= Indicators[:'message-rfc822']
|
68
67
|
next
|
@@ -70,7 +69,7 @@ module Sisimai::Bite::Email
|
|
70
69
|
end
|
71
70
|
|
72
71
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
73
|
-
#
|
72
|
+
# message/rfc822 OR text/rfc822-headers part
|
74
73
|
if e.empty?
|
75
74
|
blanklines += 1
|
76
75
|
break if blanklines > 1
|
@@ -78,98 +77,72 @@ module Sisimai::Bite::Email
|
|
78
77
|
end
|
79
78
|
rfc822list << e
|
80
79
|
else
|
81
|
-
#
|
80
|
+
# message/delivery-status part
|
82
81
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
83
82
|
next if e.empty?
|
84
83
|
|
85
|
-
if
|
86
|
-
#
|
87
|
-
|
88
|
-
# Status: 5.7.1
|
89
|
-
# Remote-MTA: DNS; p01c11m075.mx.example.net
|
90
|
-
# Diagnostic-Code: SMTP; 553 Invalid recipient destinaion@example.net (Mode: normal)
|
91
|
-
# Last-Attempt-Date: Sun, 28 Dec 2014 18:17:16 -0800
|
84
|
+
if f = Sisimai::RFC1894.match(e)
|
85
|
+
# "e" matched with any field defined in RFC3464
|
86
|
+
next unless o = Sisimai::RFC1894.field(e)
|
92
87
|
v = dscontents[-1]
|
93
88
|
|
94
|
-
if
|
95
|
-
# Final-Recipient:
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
v
|
89
|
+
if o[-1] == 'addr'
|
90
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
91
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
92
|
+
if o[0] == 'final-recipient'
|
93
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
94
|
+
if v['recipient']
|
95
|
+
# There are multiple recipient addresses in the message body.
|
96
|
+
dscontents << Sisimai::Bite.DELIVERYSTATUS
|
97
|
+
v = dscontents[-1]
|
98
|
+
end
|
99
|
+
v['recipient'] = o[2]
|
100
|
+
recipients += 1
|
101
|
+
else
|
102
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
103
|
+
v['alias'] = o[2]
|
100
104
|
end
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
# Action: failed
|
106
|
-
v['action'] = cv[1].downcase
|
107
|
-
|
108
|
-
elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
|
109
|
-
# Status: 5.7.1
|
110
|
-
v['status'] = cv[1]
|
111
|
-
|
112
|
-
elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
113
|
-
# Remote-MTA: DNS; p01c11m075.mx.example.net
|
114
|
-
v['rhost'] = cv[1].downcase
|
105
|
+
elsif o[-1] == 'code'
|
106
|
+
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
107
|
+
v['spec'] = o[1]
|
108
|
+
v['diagnosis'] = o[2]
|
115
109
|
else
|
116
|
-
#
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
elsif p.start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
|
123
|
-
# Continued line of the value of Diagnostic-Code header
|
124
|
-
v['diagnosis'] << ' ' << cv[1]
|
125
|
-
havepassed[-1] = 'Diagnostic-Code: ' << e
|
126
|
-
end
|
110
|
+
# Other DSN fields defined in RFC3464
|
111
|
+
next unless fieldtable.key?(o[0])
|
112
|
+
v[fieldtable[o[0]]] = o[2]
|
113
|
+
|
114
|
+
next unless f == 1
|
115
|
+
permessage[fieldtable[o[0]]] = o[2]
|
127
116
|
end
|
128
117
|
else
|
129
|
-
#
|
130
|
-
|
131
|
-
# <<< 553 Invalid recipient destinaion@example.net (Mode: normal)
|
132
|
-
#
|
133
|
-
# --201412281816847
|
134
|
-
# Content-Type: message/delivery-status
|
135
|
-
#
|
136
|
-
# Reporting-MTA: dns; litemail57.bigfoot.com
|
137
|
-
# Arrival-Date: Sun, 28 Dec 2014 18:17:16 -0800
|
138
|
-
#
|
139
|
-
if cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
140
|
-
# Reporting-MTA: dns; mx.example.jp
|
141
|
-
next unless connheader['lhost'].empty?
|
142
|
-
connheader['lhost'] = cv[1].downcase
|
143
|
-
connvalues += 1
|
144
|
-
|
145
|
-
elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
|
146
|
-
# Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
|
147
|
-
next unless connheader['date'].empty?
|
148
|
-
connheader['date'] = cv[1]
|
149
|
-
connvalues += 1
|
150
|
-
else
|
118
|
+
# The line does not begin with a DSN field defined in RFC3464
|
119
|
+
unless e.start_with?(' ')
|
151
120
|
# ----- Transcript of session follows -----
|
152
121
|
# >>> RCPT TO:<destinaion@example.net>
|
153
122
|
# <<< 553 Invalid recipient destinaion@example.net (Mode: normal)
|
154
123
|
if cv = e.match(/\A[>]{3}[ ]+([A-Z]{4})[ ]?/)
|
155
124
|
# >>> DATA
|
156
125
|
commandtxt = cv[1]
|
157
|
-
|
158
126
|
elsif cv = e.match(/\A[<]{3}[ ]+(.+)\z/)
|
159
127
|
# <<< Response
|
160
128
|
esmtpreply = cv[1]
|
161
129
|
end
|
162
|
-
|
130
|
+
else
|
131
|
+
# Continued line of the value of Diagnostic-Code field
|
132
|
+
next unless p.start_with?('Diagnostic-Code:')
|
133
|
+
next unless cv = e.match(/\A[ \t]+(.+)\z/)
|
134
|
+
v['diagnosis'] << ' ' << cv[1]
|
135
|
+
havepassed[-1] = 'Diagnostic-Code: ' << e
|
163
136
|
end
|
164
|
-
|
165
137
|
end
|
166
|
-
end
|
138
|
+
end # End of message/delivery-status
|
167
139
|
end
|
168
140
|
return nil unless recipients > 0
|
169
141
|
|
170
142
|
dscontents.each do |e|
|
171
143
|
# Set default values if each value is empty.
|
172
|
-
|
144
|
+
e['lhost'] ||= permessage['rhost']
|
145
|
+
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
173
146
|
|
174
147
|
e['agent'] = self.smtpagent
|
175
148
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
@@ -13,8 +13,8 @@ module Sisimai::Bite::Email
|
|
13
13
|
rfc822: ['Content-Type: message/rfc822'],
|
14
14
|
}.freeze
|
15
15
|
MessagesOf = {
|
16
|
-
filtered
|
17
|
-
mailboxfull
|
16
|
+
'filtered' => ['Mail Delivery Failed... User unknown'],
|
17
|
+
'mailboxfull' => ["The number of messages in recipient's mailbox exceeded the local limit."],
|
18
18
|
}.freeze
|
19
19
|
|
20
20
|
def description; return 'BIGLOBE: http://www.biglobe.ne.jp'; end
|
@@ -62,7 +62,7 @@ module Sisimai::Bite::Email
|
|
62
62
|
end
|
63
63
|
|
64
64
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
65
|
-
#
|
65
|
+
# Inside of the original message part
|
66
66
|
if e.empty?
|
67
67
|
blanklines += 1
|
68
68
|
break if blanklines > 1
|
@@ -70,7 +70,7 @@ module Sisimai::Bite::Email
|
|
70
70
|
end
|
71
71
|
rfc822list << e
|
72
72
|
else
|
73
|
-
#
|
73
|
+
# Error message part
|
74
74
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
75
75
|
next if e.empty?
|
76
76
|
|
@@ -100,10 +100,9 @@ module Sisimai::Bite::Email
|
|
100
100
|
end
|
101
101
|
|
102
102
|
r = Sisimai::Address.s3s4(cv[1])
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
103
|
+
next unless Sisimai::RFC5322.is_emailaddress(r)
|
104
|
+
v['recipient'] = r
|
105
|
+
recipients += 1
|
107
106
|
else
|
108
107
|
next if e =~ /\A[^\w]/
|
109
108
|
v['diagnosis'] ||= ''
|
@@ -120,7 +119,7 @@ module Sisimai::Bite::Email
|
|
120
119
|
MessagesOf.each_key do |r|
|
121
120
|
# Verify each regular expression of session errors
|
122
121
|
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
123
|
-
e['reason'] = r
|
122
|
+
e['reason'] = r
|
124
123
|
break
|
125
124
|
end
|
126
125
|
end
|
@@ -16,12 +16,12 @@ module Sisimai::Bite::Email
|
|
16
16
|
|
17
17
|
MessagesOf = {
|
18
18
|
# courier/module.esmtp/esmtpclient.c:526| hard_error(del, ctf, "No such domain.");
|
19
|
-
hostunknown
|
19
|
+
'hostunknown' => ['No such domain.'],
|
20
20
|
# courier/module.esmtp/esmtpclient.c:531| hard_error(del, ctf,
|
21
21
|
# courier/module.esmtp/esmtpclient.c:532| "This domain's DNS violates RFC 1035.");
|
22
|
-
systemerror
|
22
|
+
'systemerror' => ["This domain's DNS violates RFC 1035."],
|
23
23
|
# courier/module.esmtp/esmtpclient.c:535| soft_error(del, ctf, "DNS lookup failed.");
|
24
|
-
networkerror
|
24
|
+
'networkerror' => ['DNS lookup failed.'],
|
25
25
|
}.freeze
|
26
26
|
|
27
27
|
def description; return 'Courier MTA'; end
|
@@ -49,6 +49,10 @@ module Sisimai::Bite::Email
|
|
49
49
|
end
|
50
50
|
return nil unless match > 0
|
51
51
|
|
52
|
+
require 'sisimai/rfc1894'
|
53
|
+
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
54
|
+
permessage = {} # (Hash) Store values of each Per-Message field
|
55
|
+
|
52
56
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
53
57
|
hasdivided = mbody.split("\n")
|
54
58
|
havepassed = ['']
|
@@ -57,12 +61,6 @@ module Sisimai::Bite::Email
|
|
57
61
|
readcursor = 0 # (Integer) Points the current cursor position
|
58
62
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
59
63
|
commandtxt = '' # (String) SMTP Command name begin with the string '>>>'
|
60
|
-
connvalues = 0 # (Integer) Flag, 1 if all the value of connheader have been set
|
61
|
-
connheader = {
|
62
|
-
'date' => '', # The value of Arrival-Date header
|
63
|
-
'rhost' => '', # The value of Reporting-MTA header
|
64
|
-
'lhost' => '', # The value of Received-From-MTA header
|
65
|
-
}
|
66
64
|
v = nil
|
67
65
|
|
68
66
|
while e = hasdivided.shift do
|
@@ -71,7 +69,7 @@ module Sisimai::Bite::Email
|
|
71
69
|
p = havepassed[-2]
|
72
70
|
|
73
71
|
if readcursor == 0
|
74
|
-
# Beginning of the bounce message or delivery
|
72
|
+
# Beginning of the bounce message or message/delivery-status part
|
75
73
|
if e.include?(StartingOf[:message][0]) || e.include?(StartingOf[:message][1])
|
76
74
|
readcursor |= Indicators[:deliverystatus]
|
77
75
|
next
|
@@ -79,7 +77,7 @@ module Sisimai::Bite::Email
|
|
79
77
|
end
|
80
78
|
|
81
79
|
if (readcursor & Indicators[:'message-rfc822']) == 0
|
82
|
-
# Beginning of the original message part
|
80
|
+
# Beginning of the original message part(message/rfc822)
|
83
81
|
if e.start_with?(StartingOf[:rfc822][0], StartingOf[:rfc822][1])
|
84
82
|
readcursor |= Indicators[:'message-rfc822']
|
85
83
|
next
|
@@ -87,7 +85,7 @@ module Sisimai::Bite::Email
|
|
87
85
|
end
|
88
86
|
|
89
87
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
90
|
-
#
|
88
|
+
# message/rfc822 OR text/rfc822-headers part
|
91
89
|
if e.empty?
|
92
90
|
blanklines += 1
|
93
91
|
break if blanklines > 1
|
@@ -95,119 +93,76 @@ module Sisimai::Bite::Email
|
|
95
93
|
end
|
96
94
|
rfc822list << e
|
97
95
|
else
|
98
|
-
#
|
96
|
+
# message/delivery-status part
|
99
97
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
100
98
|
next if e.empty?
|
101
99
|
|
102
|
-
if
|
103
|
-
#
|
104
|
-
|
105
|
-
# Status: 5.0.0
|
106
|
-
# Remote-MTA: dns; mx.example.co.jp [192.0.2.95]
|
107
|
-
# Diagnostic-Code: smtp; 550 5.1.1 <kijitora@example.co.jp>... User Unknown
|
100
|
+
if f = Sisimai::RFC1894.match(e)
|
101
|
+
# "e" matched with any field defined in RFC3464
|
102
|
+
next unless o = Sisimai::RFC1894.field(e)
|
108
103
|
v = dscontents[-1]
|
109
104
|
|
110
|
-
if
|
111
|
-
# Final-Recipient: rfc822; kijitora@example.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
v
|
105
|
+
if o[-1] == 'addr'
|
106
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
107
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
108
|
+
if o[0] == 'final-recipient'
|
109
|
+
# Final-Recipient: rfc822; kijitora@example.jp
|
110
|
+
if v['recipient']
|
111
|
+
# There are multiple recipient addresses in the message body.
|
112
|
+
dscontents << Sisimai::Bite.DELIVERYSTATUS
|
113
|
+
v = dscontents[-1]
|
114
|
+
end
|
115
|
+
v['recipient'] = o[2]
|
116
|
+
recipients += 1
|
117
|
+
else
|
118
|
+
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
119
|
+
v['alias'] = o[2]
|
116
120
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
# X-Actual-Recipient: RFC822; kijitora@example.co.jp
|
122
|
-
v['alias'] = cv[1]
|
123
|
-
|
124
|
-
elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
|
125
|
-
# Action: failed
|
126
|
-
v['action'] = cv[1].downcase
|
127
|
-
|
128
|
-
elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
|
129
|
-
# Status: 5.1.1
|
130
|
-
# Status:5.2.0
|
131
|
-
# Status: 5.1.0 (permanent failure)
|
132
|
-
v['status'] = cv[1]
|
133
|
-
|
134
|
-
elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
135
|
-
# Remote-MTA: DNS; mx.example.jp
|
136
|
-
# Get the first element
|
137
|
-
v['rhost'] = cv[1].downcase
|
138
|
-
v['rhost'] = v['rhost'].split(' ').shift if v['rhost'].include?(' ')
|
139
|
-
|
140
|
-
elsif cv = e.match(/\ALast-Attempt-Date:[ ]*(.+)\z/)
|
141
|
-
# Last-Attempt-Date: Fri, 14 Feb 2014 12:30:08 -0500
|
142
|
-
v['date'] = cv[1]
|
121
|
+
elsif o[-1] == 'code'
|
122
|
+
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
123
|
+
v['spec'] = o[1]
|
124
|
+
v['diagnosis'] = o[2]
|
143
125
|
else
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
# Continued line of the value of Diagnostic-Code header
|
151
|
-
v['diagnosis'] << ' ' << cv[1]
|
152
|
-
havepassed[-1] = 'Diagnostic-Code: ' << e
|
153
|
-
end
|
126
|
+
# Other DSN fields defined in RFC3464
|
127
|
+
next unless fieldtable.key?(o[0])
|
128
|
+
v[fieldtable[o[0]]] = o[2]
|
129
|
+
|
130
|
+
next unless f == 1
|
131
|
+
permessage[fieldtable[o[0]]] = o[2]
|
154
132
|
end
|
155
133
|
else
|
156
|
-
#
|
157
|
-
# running the Courier mail server, version 0.65.2.
|
158
|
-
#
|
159
|
-
# The original message was received on Sat, 11 Dec 2010 12:19:57 +0900
|
160
|
-
# from [127.0.0.1] (c10920.example.com [192.0.2.20])
|
161
|
-
#
|
162
|
-
# ---------------------------------------------------------------------------
|
163
|
-
#
|
164
|
-
# UNDELIVERABLE MAIL
|
165
|
-
#
|
166
|
-
# Your message to the following recipients cannot be delivered:
|
167
|
-
#
|
168
|
-
# <kijitora@example.co.jp>:
|
169
|
-
# mx.example.co.jp [74.207.247.95]:
|
170
|
-
# >>> RCPT TO:<kijitora@example.co.jp>
|
171
|
-
# <<< 550 5.1.1 <kijitora@example.co.jp>... User Unknown
|
172
|
-
#
|
173
|
-
# ---------------------------------------------------------------------------
|
134
|
+
# The line does not begin with a DSN field defined in RFC3464
|
174
135
|
if cv = e.match(/\A[>]{3}[ ]+([A-Z]{4})[ ]?/)
|
175
|
-
#
|
136
|
+
# Your message to the following recipients cannot be delivered:
|
137
|
+
#
|
138
|
+
# <kijitora@example.co.jp>:
|
139
|
+
# mx.example.co.jp [74.207.247.95]:
|
140
|
+
# >>> RCPT TO:<kijitora@example.co.jp>
|
141
|
+
# <<< 550 5.1.1 <kijitora@example.co.jp>... User Unknown
|
142
|
+
#
|
176
143
|
next unless commandtxt.empty?
|
177
144
|
commandtxt = cv[1]
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
next unless
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
elsif cv = e.match(/\AReceived-From-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
186
|
-
# Received-From-MTA: DNS; x1x2x3x4.dhcp.example.ne.jp
|
187
|
-
next unless connheader['lhost'].empty?
|
188
|
-
connheader['lhost'] = cv[1].downcase
|
189
|
-
connvalues += 1
|
190
|
-
|
191
|
-
elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
|
192
|
-
# Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
|
193
|
-
next unless connheader['date'].empty?
|
194
|
-
connheader['date'] = cv[1]
|
195
|
-
connvalues += 1
|
145
|
+
else
|
146
|
+
# Continued line of the value of Diagnostic-Code field
|
147
|
+
next unless p.start_with?('Diagnostic-Code:')
|
148
|
+
next unless cv = e.match(/\A[ \t]+(.+)\z/)
|
149
|
+
v['diagnosis'] << ' ' << cv[1]
|
150
|
+
havepassed[-1] = 'Diagnostic-Code: ' << e
|
196
151
|
end
|
197
152
|
end
|
198
|
-
end
|
153
|
+
end # End of message/delivery-status
|
199
154
|
end
|
200
155
|
return nil unless recipients > 0
|
201
156
|
|
202
157
|
dscontents.each do |e|
|
203
158
|
# Set default values if each value is empty.
|
204
|
-
|
159
|
+
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
205
160
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
206
161
|
|
207
162
|
MessagesOf.each_key do |r|
|
208
163
|
# Verify each regular expression of session errors
|
209
164
|
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
210
|
-
e['reason'] = r
|
165
|
+
e['reason'] = r
|
211
166
|
break
|
212
167
|
end
|
213
168
|
|