sisimai 4.16.0 → 4.17.0
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/.rubocop.yml +3 -0
- data/ANALYTICAL-PRECISION +7 -7
- data/Changes +15 -0
- data/Makefile +1 -1
- data/README.md +30 -28
- data/lib/sisimai.rb +20 -1
- data/lib/sisimai/address.rb +28 -9
- data/lib/sisimai/arf.rb +37 -46
- data/lib/sisimai/data.rb +67 -43
- data/lib/sisimai/datetime.rb +210 -210
- data/lib/sisimai/mda.rb +30 -30
- data/lib/sisimai/message.rb +3 -5
- data/lib/sisimai/msp/de/einsundeins.rb +14 -42
- data/lib/sisimai/msp/de/gmx.rb +17 -44
- data/lib/sisimai/msp/jp/biglobe.rb +15 -44
- data/lib/sisimai/msp/jp/ezweb.rb +20 -50
- data/lib/sisimai/msp/jp/kddi.rb +16 -43
- data/lib/sisimai/msp/ru/mailru.rb +20 -48
- data/lib/sisimai/msp/ru/yandex.rb +16 -50
- data/lib/sisimai/msp/uk/messagelabs.rb +17 -51
- data/lib/sisimai/msp/us/amazonses.rb +18 -40
- data/lib/sisimai/msp/us/amazonworkmail.rb +17 -35
- data/lib/sisimai/msp/us/aol.rb +17 -41
- data/lib/sisimai/msp/us/bigfoot.rb +15 -48
- data/lib/sisimai/msp/us/facebook.rb +63 -90
- data/lib/sisimai/msp/us/google.rb +15 -44
- data/lib/sisimai/msp/us/office365.rb +21 -46
- data/lib/sisimai/msp/us/outlook.rb +17 -50
- data/lib/sisimai/msp/us/receivingses.rb +20 -43
- data/lib/sisimai/msp/us/sendgrid.rb +13 -37
- data/lib/sisimai/msp/us/verizon.rb +30 -74
- data/lib/sisimai/msp/us/yahoo.rb +12 -40
- data/lib/sisimai/msp/us/zoho.rb +14 -42
- data/lib/sisimai/mta/activehunter.rb +11 -40
- data/lib/sisimai/mta/apachejames.rb +18 -40
- data/lib/sisimai/mta/courier.rb +20 -57
- data/lib/sisimai/mta/domino.rb +24 -56
- data/lib/sisimai/mta/exchange.rb +26 -54
- data/lib/sisimai/mta/exim.rb +20 -39
- data/lib/sisimai/mta/imailserver.rb +26 -71
- data/lib/sisimai/mta/interscanmss.rb +26 -44
- data/lib/sisimai/mta/mailfoundry.rb +12 -42
- data/lib/sisimai/mta/mailmarshalsmtp.rb +13 -43
- data/lib/sisimai/mta/mcafee.rb +17 -46
- data/lib/sisimai/mta/messagingserver.rb +14 -47
- data/lib/sisimai/mta/mfilter.rb +12 -35
- data/lib/sisimai/mta/mxlogic.rb +18 -42
- data/lib/sisimai/mta/notes.rb +22 -45
- data/lib/sisimai/mta/opensmtpd.rb +18 -48
- data/lib/sisimai/mta/postfix.rb +15 -45
- data/lib/sisimai/mta/qmail.rb +32 -60
- data/lib/sisimai/mta/sendmail.rb +13 -38
- data/lib/sisimai/mta/surfcontrol.rb +15 -44
- data/lib/sisimai/mta/userdefined.rb +14 -30
- data/lib/sisimai/mta/v5sendmail.rb +18 -40
- data/lib/sisimai/mta/x1.rb +12 -41
- data/lib/sisimai/mta/x2.rb +12 -41
- data/lib/sisimai/mta/x3.rb +12 -39
- data/lib/sisimai/mta/x4.rb +33 -66
- data/lib/sisimai/mta/x5.rb +15 -42
- data/lib/sisimai/reason.rb +8 -71
- data/lib/sisimai/reason/blocked.rb +3 -0
- data/lib/sisimai/reason/contenterror.rb +3 -0
- data/lib/sisimai/reason/delivered.rb +27 -0
- data/lib/sisimai/reason/exceedlimit.rb +3 -0
- data/lib/sisimai/reason/expired.rb +3 -0
- data/lib/sisimai/reason/feedback.rb +18 -0
- data/lib/sisimai/reason/filtered.rb +4 -0
- data/lib/sisimai/reason/hasmoved.rb +3 -0
- data/lib/sisimai/reason/hostunknown.rb +3 -0
- data/lib/sisimai/reason/mailboxfull.rb +3 -0
- data/lib/sisimai/reason/mailererror.rb +3 -0
- data/lib/sisimai/reason/mesgtoobig.rb +3 -0
- data/lib/sisimai/reason/networkerror.rb +3 -0
- data/lib/sisimai/reason/norelaying.rb +3 -0
- data/lib/sisimai/reason/notaccept.rb +3 -0
- data/lib/sisimai/reason/onhold.rb +3 -0
- data/lib/sisimai/reason/rejected.rb +3 -0
- data/lib/sisimai/reason/securityerror.rb +3 -0
- data/lib/sisimai/reason/spamdetected.rb +3 -0
- data/lib/sisimai/reason/suspend.rb +3 -0
- data/lib/sisimai/reason/syntaxerror.rb +41 -0
- data/lib/sisimai/reason/systemerror.rb +3 -0
- data/lib/sisimai/reason/systemfull.rb +3 -0
- data/lib/sisimai/reason/toomanyconn.rb +3 -0
- data/lib/sisimai/reason/undefined.rb +18 -0
- data/lib/sisimai/reason/userunknown.rb +3 -0
- data/lib/sisimai/reason/vacation.rb +18 -0
- data/lib/sisimai/rfc3464.rb +15 -40
- data/lib/sisimai/rfc3834.rb +1 -10
- data/lib/sisimai/rfc5322.rb +57 -19
- data/lib/sisimai/rhost/googleapps.rb +82 -82
- data/lib/sisimai/smtp/reply.rb +2 -1
- data/lib/sisimai/smtp/status.rb +154 -152
- data/lib/sisimai/string.rb +2 -3
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/rfc3464-29.eml +60 -0
- data/set-of-emails/maildir/bsd/us-amazonworkmail-06.eml +156 -0
- data/set-of-emails/maildir/bsd/us-amazonworkmail-07.eml +158 -0
- data/set-of-emails/maildir/bsd/us-google-15.eml +97 -0
- data/set-of-emails/maildir/bsd/us-google-16.eml +99 -0
- data/set-of-emails/maildir/bsd/us-google-17.eml +104 -0
- data/set-of-emails/maildir/dos/apachejames-01.eml +4 -4
- data/set-of-emails/maildir/dos/us-amazonworkmail-01.eml +156 -0
- data/set-of-emails/maildir/dos/us-office365-01.eml +102 -0
- data/set-of-emails/maildir/mac/apachejames-01.eml +1 -9
- data/set-of-emails/maildir/mac/us-amazonworkmail-01.eml +1 -7
- data/set-of-emails/maildir/mac/us-office365-01.eml +1 -4
- metadata +17 -2
data/lib/sisimai/mta/mfilter.rb
CHANGED
@@ -21,8 +21,6 @@ module Sisimai
|
|
21
21
|
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
22
22
|
}
|
23
23
|
Indicators = Sisimai::MTA.INDICATORS
|
24
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
25
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
26
24
|
|
27
25
|
def description; return 'Digital Arts m-FILTER'; end
|
28
26
|
def smtpagent; return 'm-FILTER'; end
|
@@ -47,11 +45,10 @@ module Sisimai
|
|
47
45
|
return nil unless mhead['x-mailer'] =~ Re0[:'x-mailer']
|
48
46
|
return nil unless mhead['subject'] =~ Re0[:'subject']
|
49
47
|
|
50
|
-
dscontents = [
|
48
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
51
49
|
hasdivided = mbody.split("\n")
|
52
|
-
|
53
|
-
|
54
|
-
previousfn = '' # (String) Previous field name
|
50
|
+
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
51
|
+
blanklines = 0 # (Integer) The number of blank lines
|
55
52
|
readcursor = 0 # (Integer) Points the current cursor position
|
56
53
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
57
54
|
markingset = { 'diagnosis' => false, 'command' => false }
|
@@ -60,7 +57,7 @@ module Sisimai
|
|
60
57
|
hasdivided.each do |e|
|
61
58
|
if readcursor == 0
|
62
59
|
# Beginning of the bounce message or delivery status part
|
63
|
-
readcursor |= Indicators[:
|
60
|
+
readcursor |= Indicators[:deliverystatus] if e =~ Re1[:begin]
|
64
61
|
end
|
65
62
|
|
66
63
|
if readcursor & Indicators[:'message-rfc822'] == 0
|
@@ -73,30 +70,16 @@ module Sisimai
|
|
73
70
|
|
74
71
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
75
72
|
# After "message/rfc822"
|
76
|
-
if
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
next unless RFC822Head.key?(lhs)
|
81
|
-
|
82
|
-
previousfn = lhs
|
83
|
-
rfc822part += e + "\n"
|
84
|
-
|
85
|
-
elsif e =~ /\A[ \t]+/
|
86
|
-
# Continued line from the previous line
|
87
|
-
next if rfc822next[previousfn]
|
88
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
89
|
-
|
90
|
-
else
|
91
|
-
# Check the end of headers in rfc822 part
|
92
|
-
next unless LongFields.key?(previousfn)
|
93
|
-
next unless e.empty?
|
94
|
-
rfc822next[previousfn] = true
|
73
|
+
if e.empty?
|
74
|
+
blanklines += 1
|
75
|
+
break if blanklines > 1
|
76
|
+
next
|
95
77
|
end
|
78
|
+
rfc822list << e
|
96
79
|
|
97
80
|
else
|
98
81
|
# Before "message/rfc822"
|
99
|
-
next if readcursor & Indicators[:
|
82
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
100
83
|
next if e.empty?
|
101
84
|
|
102
85
|
# このメールは「m-FILTER」が自動的に生成して送信しています。
|
@@ -152,14 +135,10 @@ module Sisimai
|
|
152
135
|
end
|
153
136
|
end
|
154
137
|
end
|
155
|
-
|
156
138
|
return nil if recipients == 0
|
157
139
|
require 'sisimai/string'
|
158
|
-
require 'sisimai/smtp/status'
|
159
140
|
|
160
141
|
dscontents.map do |e|
|
161
|
-
e['agent'] = Sisimai::MTA::MFILTER.smtpagent
|
162
|
-
|
163
142
|
if mhead['received'].size > 0
|
164
143
|
# Get localhost and remote host name from Received header.
|
165
144
|
rheads = mhead['received']
|
@@ -172,14 +151,12 @@ module Sisimai
|
|
172
151
|
e['rhost'] = ee
|
173
152
|
end
|
174
153
|
end
|
175
|
-
|
176
154
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
177
|
-
e['
|
178
|
-
e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
|
179
|
-
e['action'] = 'failed' if e['status'] =~ /\A[45]/
|
155
|
+
e['agent'] = Sisimai::MTA::MFILTER.smtpagent
|
180
156
|
e.each_key { |a| e[a] ||= '' }
|
181
157
|
end
|
182
158
|
|
159
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
183
160
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
184
161
|
end
|
185
162
|
|
data/lib/sisimai/mta/mxlogic.rb
CHANGED
@@ -28,12 +28,11 @@ module Sisimai
|
|
28
28
|
%r/SMTP error from remote (?:mail server|mailer) after ([A-Za-z]{4})/,
|
29
29
|
%r/SMTP error from remote (?:mail server|mailer) after end of ([A-Za-z]{4})/,
|
30
30
|
]
|
31
|
-
|
32
31
|
ReFailure = {
|
33
|
-
|
32
|
+
userunknown: %r{
|
34
33
|
user[ ]not[ ]found
|
35
34
|
}x,
|
36
|
-
|
35
|
+
hostunknown: %r{(?>
|
37
36
|
all[ ](?:
|
38
37
|
host[ ]address[ ]lookups[ ]failed[ ]permanently
|
39
38
|
|relevant[ ]MX[ ]records[ ]point[ ]to[ ]non[-]existent[ ]hosts
|
@@ -41,27 +40,26 @@ module Sisimai
|
|
41
40
|
|Unrouteable[ ]address
|
42
41
|
)
|
43
42
|
}x,
|
44
|
-
|
43
|
+
mailboxfull: %r{(?:
|
45
44
|
mailbox[ ]is[ ]full:?
|
46
45
|
|error:[ ]quota[ ]exceed
|
47
46
|
)
|
48
47
|
}x,
|
49
|
-
|
48
|
+
notaccept: %r{(?:
|
50
49
|
an[ ]MX[ ]or[ ]SRV[ ]record[ ]indicated[ ]no[ ]SMTP[ ]service
|
51
50
|
|no[ ]host[ ]found[ ]for[ ]existing[ ]SMTP[ ]connection
|
52
51
|
)
|
53
52
|
}x,
|
54
|
-
|
53
|
+
systemerror: %r{(?>
|
55
54
|
delivery[ ]to[ ](?:file|pipe)[ ]forbidden
|
56
55
|
|local[ ]delivery[ ]failed
|
57
56
|
|LMTP[ ]error[ ]after[ ]
|
58
57
|
)
|
59
58
|
}x,
|
60
|
-
|
59
|
+
contenterror: %r{
|
61
60
|
Too[ ]many[ ]["]Received["][ ]headers
|
62
61
|
}x,
|
63
62
|
}
|
64
|
-
|
65
63
|
ReDelayed = %r{(?:
|
66
64
|
retry[ ]timeout[ ]exceeded
|
67
65
|
|No[ ]action[ ]is[ ]required[ ]on[ ]your[ ]part
|
@@ -72,8 +70,6 @@ module Sisimai
|
|
72
70
|
)
|
73
71
|
}x
|
74
72
|
Indicators = Sisimai::MTA.INDICATORS
|
75
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
76
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
77
73
|
|
78
74
|
def description; return 'McAfee SaaS'; end
|
79
75
|
def smtpagent; return 'MXLogic'; end
|
@@ -106,11 +102,10 @@ module Sisimai
|
|
106
102
|
match += 1 if mhead['from'] =~ Re0[:from]
|
107
103
|
return nil if match == 0
|
108
104
|
|
109
|
-
dscontents = [
|
105
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
110
106
|
hasdivided = mbody.split("\n")
|
111
|
-
|
112
|
-
|
113
|
-
previousfn = '' # (String) Previous field name
|
107
|
+
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
108
|
+
blanklines = 0 # (Integer) The number of blank lines
|
114
109
|
readcursor = 0 # (Integer) Points the current cursor position
|
115
110
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
116
111
|
localhost0 = '' # (String) Local MTA
|
@@ -120,7 +115,7 @@ module Sisimai
|
|
120
115
|
if readcursor == 0
|
121
116
|
# Beginning of the bounce message or delivery status part
|
122
117
|
if e =~ Re1[:begin]
|
123
|
-
readcursor |= Indicators[:
|
118
|
+
readcursor |= Indicators[:deliverystatus]
|
124
119
|
next
|
125
120
|
end
|
126
121
|
end
|
@@ -135,30 +130,16 @@ module Sisimai
|
|
135
130
|
|
136
131
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
137
132
|
# After "message/rfc822"
|
138
|
-
if
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
next unless RFC822Head.key?(lhs)
|
143
|
-
|
144
|
-
previousfn = lhs
|
145
|
-
rfc822part += e + "\n"
|
146
|
-
|
147
|
-
elsif e =~ /\A[ \t]+/
|
148
|
-
# Continued line from the previous line
|
149
|
-
next if rfc822next[previousfn]
|
150
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
151
|
-
|
152
|
-
else
|
153
|
-
# Check the end of headers in rfc822 part
|
154
|
-
next unless LongFields.key?(previousfn)
|
155
|
-
next unless e.empty?
|
156
|
-
rfc822next[previousfn] = true
|
133
|
+
if e.empty?
|
134
|
+
blanklines += 1
|
135
|
+
break if blanklines > 1
|
136
|
+
next
|
157
137
|
end
|
138
|
+
rfc822list << e
|
158
139
|
|
159
140
|
else
|
160
141
|
# Before "message/rfc822"
|
161
|
-
next if readcursor & Indicators[:
|
142
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
162
143
|
next if e.empty?
|
163
144
|
|
164
145
|
# This message was created automatically by mail delivery software.
|
@@ -208,8 +189,6 @@ module Sisimai
|
|
208
189
|
end
|
209
190
|
|
210
191
|
require 'sisimai/string'
|
211
|
-
require 'sisimai/smtp/status'
|
212
|
-
|
213
192
|
dscontents.map do |e|
|
214
193
|
e['agent'] = Sisimai::MTA::MXLogic.smtpagent
|
215
194
|
e['lhost'] = localhost0
|
@@ -256,7 +235,7 @@ module Sisimai
|
|
256
235
|
ReFailure.each_key do |r|
|
257
236
|
# Check each regular expression
|
258
237
|
next unless e['diagnosis'] =~ ReFailure[r]
|
259
|
-
e['reason'] = r
|
238
|
+
e['reason'] = r.to_s
|
260
239
|
break
|
261
240
|
end
|
262
241
|
|
@@ -266,13 +245,10 @@ module Sisimai
|
|
266
245
|
end
|
267
246
|
end
|
268
247
|
end
|
269
|
-
|
270
|
-
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
271
|
-
e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
|
272
|
-
e['action'] = 'failed' if e['status'] =~ /\A[45]/
|
273
248
|
e.each_key { |a| e[a] ||= '' }
|
274
249
|
end
|
275
250
|
|
251
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
276
252
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
277
253
|
end
|
278
254
|
|
data/lib/sisimai/mta/notes.rb
CHANGED
@@ -17,16 +17,14 @@ module Sisimai
|
|
17
17
|
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
18
18
|
}
|
19
19
|
ReFailure = {
|
20
|
-
|
20
|
+
userunknown: %r{(?:
|
21
21
|
User[ ]not[ ]listed[ ]in[ ]public[ ]Name[ ][&][ ]Address[ ]Book
|
22
22
|
|ディレクトリのリストにありません
|
23
23
|
)
|
24
24
|
}x,
|
25
|
-
|
25
|
+
networkerror: %r/Message has exceeded maximum hop count/,
|
26
26
|
}
|
27
27
|
Indicators = Sisimai::MTA.INDICATORS
|
28
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
29
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
30
28
|
|
31
29
|
def description; return 'Lotus Notes'; end
|
32
30
|
def smtpagent; return 'Notes'; end
|
@@ -49,11 +47,10 @@ module Sisimai
|
|
49
47
|
return nil unless mbody
|
50
48
|
return nil unless mhead['subject'] =~ Re0[:subject]
|
51
49
|
|
52
|
-
dscontents = [
|
50
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
53
51
|
hasdivided = mbody.split("\n")
|
54
|
-
|
55
|
-
|
56
|
-
previousfn = '' # (String) Previous field name
|
52
|
+
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
53
|
+
blanklines = 0 # (Integer) The number of blank lines
|
57
54
|
readcursor = 0 # (Integer) Points the current cursor position
|
58
55
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
59
56
|
characters = '' # (String) Character set name of the bounce mail
|
@@ -65,7 +62,7 @@ module Sisimai
|
|
65
62
|
if readcursor == 0
|
66
63
|
# Beginning of the bounce message or delivery status part
|
67
64
|
if e =~ Re1[:begin]
|
68
|
-
readcursor |= Indicators[:
|
65
|
+
readcursor |= Indicators[:deliverystatus]
|
69
66
|
next
|
70
67
|
end
|
71
68
|
end
|
@@ -88,30 +85,16 @@ module Sisimai
|
|
88
85
|
|
89
86
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
90
87
|
# After "message/rfc822"
|
91
|
-
if
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
next unless RFC822Head.key?(lhs)
|
96
|
-
|
97
|
-
previousfn = lhs
|
98
|
-
rfc822part += e + "\n"
|
99
|
-
|
100
|
-
elsif e =~ /\A[ \t]+/
|
101
|
-
# Continued line from the previous line
|
102
|
-
next if rfc822next[previousfn]
|
103
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
104
|
-
|
105
|
-
else
|
106
|
-
# Check the end of headers in rfc822 part
|
107
|
-
next unless LongFields.key?(previousfn)
|
108
|
-
next unless e.empty?
|
109
|
-
rfc822next[previousfn] = true
|
88
|
+
if e.empty?
|
89
|
+
blanklines += 1
|
90
|
+
break if blanklines > 1
|
91
|
+
next
|
110
92
|
end
|
93
|
+
rfc822list << e
|
111
94
|
|
112
95
|
else
|
113
96
|
# Before "message/rfc822"
|
114
|
-
next if readcursor & Indicators[:
|
97
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
115
98
|
|
116
99
|
# ------- Failure Reasons --------
|
117
100
|
#
|
@@ -161,9 +144,12 @@ module Sisimai
|
|
161
144
|
|
162
145
|
if recipients == 0
|
163
146
|
# Fallback: Get the recpient address from RFC822 part
|
164
|
-
|
165
|
-
|
166
|
-
|
147
|
+
rfc822list.each do |e|
|
148
|
+
if cv = e.match(/^To:[ ]*(.+)$/m)
|
149
|
+
v['recipient'] = Sisimai::Address.s3s4(cv[1])
|
150
|
+
recipients += 1 if v['recipient'].size > 0
|
151
|
+
break
|
152
|
+
end
|
167
153
|
end
|
168
154
|
end
|
169
155
|
|
@@ -172,31 +158,22 @@ module Sisimai
|
|
172
158
|
require 'sisimai/smtp/status'
|
173
159
|
|
174
160
|
dscontents.map do |e|
|
175
|
-
e['agent']
|
176
|
-
|
177
|
-
if mhead['received'].size > 0
|
178
|
-
# Get localhost and remote host name from Received header.
|
179
|
-
r0 = mhead['received']
|
180
|
-
%w|lhost rhost|.each { |a| e[a] ||= '' }
|
181
|
-
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
182
|
-
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
183
|
-
end
|
161
|
+
e['agent'] = Sisimai::MTA::Notes.smtpagent
|
184
162
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
185
163
|
e['recipient'] = Sisimai::Address.s3s4(e['recipient'])
|
186
164
|
|
187
165
|
ReFailure.each_key do |r|
|
188
166
|
# Check each regular expression of Notes error messages
|
189
167
|
next unless e['diagnosis'] =~ ReFailure[r]
|
190
|
-
e['reason'] = r
|
191
|
-
pseudostatus = Sisimai::SMTP::Status.code(r)
|
168
|
+
e['reason'] = r.to_s
|
169
|
+
pseudostatus = Sisimai::SMTP::Status.code(r.to_s)
|
192
170
|
e['status'] = pseudostatus if pseudostatus.size > 0
|
193
171
|
break
|
194
172
|
end
|
195
|
-
e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
|
196
|
-
e['action'] = 'failed' if e['status'] =~ /\A[45]/
|
197
173
|
e.each_key { |a| e[a] ||= '' }
|
198
174
|
end
|
199
175
|
|
176
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
200
177
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
201
178
|
end
|
202
179
|
|
@@ -44,22 +44,22 @@ module Sisimai
|
|
44
44
|
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
45
45
|
}
|
46
46
|
ReFailure = {
|
47
|
-
|
47
|
+
expired: %r{
|
48
48
|
# smtpd/queue.c:221| envelope_set_errormsg(&evp, "Envelope expired");
|
49
49
|
Envelope[ ]expired
|
50
50
|
}x,
|
51
|
-
|
51
|
+
hostunknown: %r{(?:
|
52
52
|
# smtpd/mta.c:976| relay->failstr = "Invalid domain name";
|
53
53
|
Invalid[ ]domain[ ]name
|
54
54
|
# smtpd/mta.c:980| relay->failstr = "Domain does not exist";
|
55
55
|
|Domain[ ]does[ ]not[ ]exist
|
56
56
|
)
|
57
57
|
}x,
|
58
|
-
|
58
|
+
notaccept: %r{
|
59
59
|
# smtp/mta.c:1085| relay->failstr = "Destination seem to reject all mails";
|
60
60
|
Destination[ ]seem[ ]to[ ]reject[ ]all[ ]mails
|
61
61
|
}x,
|
62
|
-
|
62
|
+
networkerror: %r{(?>
|
63
63
|
# smtpd/mta.c:972| relay->failstr = "Temporary failure in MX lookup";
|
64
64
|
Address[ ]family[ ]mismatch[ ]on[ ]destination[ ]MXs
|
65
65
|
|All[ ]routes[ ]to[ ]destination[ ]blocked
|
@@ -74,14 +74,12 @@ module Sisimai
|
|
74
74
|
|Temporary[ ]failure[ ]in[ ]MX[ ]lookup
|
75
75
|
)
|
76
76
|
}x,
|
77
|
-
|
77
|
+
securityerror: %r{
|
78
78
|
# smtpd/mta.c:1013| relay->failstr = "Could not retrieve credentials";
|
79
79
|
Could[ ]not[ ]retrieve[ ]credentials
|
80
80
|
}x,
|
81
81
|
}
|
82
82
|
Indicators = Sisimai::MTA.INDICATORS
|
83
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
84
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
85
83
|
|
86
84
|
def description; return 'OpenSMTPD'; end
|
87
85
|
def smtpagent; return 'OpenSMTPD'; end
|
@@ -106,11 +104,10 @@ module Sisimai
|
|
106
104
|
return nil unless mhead['from'] =~ Re0[:from]
|
107
105
|
return nil unless mhead['received'].find { |a| a =~ Re0[:received] }
|
108
106
|
|
109
|
-
dscontents = [
|
107
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
110
108
|
hasdivided = mbody.split("\n")
|
111
|
-
|
112
|
-
|
113
|
-
previousfn = '' # (String) Previous field name
|
109
|
+
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
110
|
+
blanklines = 0 # (Integer) The number of blank lines
|
114
111
|
readcursor = 0 # (Integer) Points the current cursor position
|
115
112
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
116
113
|
v = nil
|
@@ -119,7 +116,7 @@ module Sisimai
|
|
119
116
|
if readcursor == 0
|
120
117
|
# Beginning of the bounce message or delivery status part
|
121
118
|
if e =~ Re1[:begin]
|
122
|
-
readcursor |= Indicators[:
|
119
|
+
readcursor |= Indicators[:deliverystatus]
|
123
120
|
next
|
124
121
|
end
|
125
122
|
end
|
@@ -134,30 +131,16 @@ module Sisimai
|
|
134
131
|
|
135
132
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
136
133
|
# After "message/rfc822"
|
137
|
-
if
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
next unless RFC822Head.key?(lhs)
|
142
|
-
|
143
|
-
previousfn = lhs
|
144
|
-
rfc822part += e + "\n"
|
145
|
-
|
146
|
-
elsif e =~ /\A[ \t]+/
|
147
|
-
# Continued line from the previous line
|
148
|
-
next if rfc822next[previousfn]
|
149
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
150
|
-
|
151
|
-
else
|
152
|
-
# Check the end of headers in rfc822 part
|
153
|
-
next unless LongFields.key?(previousfn)
|
154
|
-
next unless e.empty?
|
155
|
-
rfc822next[previousfn] = true
|
134
|
+
if e.empty?
|
135
|
+
blanklines += 1
|
136
|
+
break if blanklines > 1
|
137
|
+
next
|
156
138
|
end
|
139
|
+
rfc822list << e
|
157
140
|
|
158
141
|
else
|
159
142
|
# Before "message/rfc822"
|
160
|
-
next if readcursor & Indicators[:
|
143
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
161
144
|
next if e.empty?
|
162
145
|
|
163
146
|
# Hi!
|
@@ -185,36 +168,23 @@ module Sisimai
|
|
185
168
|
end
|
186
169
|
end
|
187
170
|
end
|
188
|
-
|
189
171
|
return nil if recipients == 0
|
190
172
|
require 'sisimai/string'
|
191
|
-
require 'sisimai/smtp/status'
|
192
173
|
|
193
174
|
dscontents.map do |e|
|
194
|
-
e['agent']
|
195
|
-
|
196
|
-
if mhead['received'].size > 0
|
197
|
-
# Get localhost and remote host name from Received header.
|
198
|
-
r0 = mhead['received']
|
199
|
-
%w|lhost rhost|.each { |a| e[a] ||= '' }
|
200
|
-
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
201
|
-
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
202
|
-
end
|
175
|
+
e['agent'] = Sisimai::MTA::OpenSMTPD.smtpagent
|
203
176
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
204
177
|
|
205
178
|
ReFailure.each_key do |r|
|
206
179
|
# Verify each regular expression of session errors
|
207
180
|
next unless e['diagnosis'] =~ ReFailure[r]
|
208
|
-
e['reason'] = r
|
181
|
+
e['reason'] = r.to_s
|
209
182
|
break
|
210
183
|
end
|
211
|
-
|
212
|
-
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
213
|
-
e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
|
214
|
-
e['action'] = 'failed' if e['status'] =~ /\A[45]/
|
215
184
|
e.each_key { |a| e[a] ||= '' }
|
216
185
|
end
|
217
186
|
|
187
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
218
188
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
219
189
|
end
|
220
190
|
|