sisimai 4.16.0-java → 4.17.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/.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/postfix.rb
CHANGED
@@ -36,8 +36,6 @@ module Sisimai
|
|
36
36
|
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
37
37
|
}
|
38
38
|
Indicators = Sisimai::MTA.INDICATORS
|
39
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
40
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
41
39
|
|
42
40
|
def description; return 'Postfix'; end
|
43
41
|
def smtpagent; return 'Postfix'; end
|
@@ -60,12 +58,11 @@ module Sisimai
|
|
60
58
|
return nil unless mbody
|
61
59
|
return nil unless mhead['subject'] =~ Re0[:subject]
|
62
60
|
|
63
|
-
dscontents = [
|
61
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
64
62
|
hasdivided = mbody.split("\n")
|
65
63
|
havepassed = ['']
|
66
|
-
|
67
|
-
|
68
|
-
previousfn = '' # (String) Previous field name
|
64
|
+
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
65
|
+
blanklines = 0 # (Integer) The number of blank lines
|
69
66
|
readcursor = 0 # (Integer) Points the current cursor position
|
70
67
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
71
68
|
commandset = [] # (Array) ``in reply to * command'' list
|
@@ -79,12 +76,13 @@ module Sisimai
|
|
79
76
|
|
80
77
|
hasdivided.each do |e|
|
81
78
|
# Save the current line for the next loop
|
82
|
-
havepassed << e
|
79
|
+
havepassed << e
|
80
|
+
p = havepassed[-2]
|
83
81
|
|
84
82
|
if readcursor == 0
|
85
83
|
# Beginning of the bounce message or delivery status part
|
86
84
|
if e =~ Re1[:begin]
|
87
|
-
readcursor |= Indicators[:
|
85
|
+
readcursor |= Indicators[:deliverystatus]
|
88
86
|
next
|
89
87
|
end
|
90
88
|
end
|
@@ -99,30 +97,16 @@ module Sisimai
|
|
99
97
|
|
100
98
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
101
99
|
# After "message/rfc822"
|
102
|
-
if
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
next unless RFC822Head.key?(lhs)
|
107
|
-
|
108
|
-
previousfn = lhs
|
109
|
-
rfc822part += e + "\n"
|
110
|
-
|
111
|
-
elsif e =~ /\A[ \t]+/
|
112
|
-
# Continued line from the previous line
|
113
|
-
next if rfc822next[previousfn]
|
114
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
115
|
-
|
116
|
-
else
|
117
|
-
# Check the end of headers in rfc822 part
|
118
|
-
next unless LongFields.key?(previousfn)
|
119
|
-
next unless e.empty?
|
120
|
-
rfc822next[previousfn] = true
|
100
|
+
if e.empty?
|
101
|
+
blanklines += 1
|
102
|
+
break if blanklines > 1
|
103
|
+
next
|
121
104
|
end
|
105
|
+
rfc822list << e
|
122
106
|
|
123
107
|
else
|
124
108
|
# Before "message/rfc822"
|
125
|
-
next if readcursor & Indicators[:
|
109
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
126
110
|
next if e.empty?
|
127
111
|
|
128
112
|
if connvalues == connheader.keys.size
|
@@ -145,7 +129,7 @@ module Sisimai
|
|
145
129
|
recipients += 1
|
146
130
|
|
147
131
|
elsif cv = e.match(/\A[Xx]-[Aa]ctual-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/) ||
|
148
|
-
|
132
|
+
e.match(/\A[Oo]riginal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
|
149
133
|
# X-Actual-Recipient: RFC822; kijitora@example.co.jp
|
150
134
|
# Original-Recipient: rfc822;kijitora@example.co.jp
|
151
135
|
v['alias'] = cv[1]
|
@@ -222,7 +206,7 @@ module Sisimai
|
|
222
206
|
|
223
207
|
elsif cv = e.match(/\A(X-Postfix-Sender):[ ]*rfc822;[ ]*(.+)\z/)
|
224
208
|
# X-Postfix-Sender: rfc822; shironeko@example.org
|
225
|
-
|
209
|
+
rfc822list << sprintf('%s: %s', cv[1], cv[2])
|
226
210
|
|
227
211
|
else
|
228
212
|
# Alternative error message and recipient
|
@@ -279,24 +263,10 @@ module Sisimai
|
|
279
263
|
end
|
280
264
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
281
265
|
e['spec'] ||= 'SMTP' if e['diagnosis'] =~ /host .+ said:/
|
282
|
-
e['status'] ||= ''
|
283
|
-
|
284
|
-
if mhead['received'].size > 0
|
285
|
-
# Get localhost and remote host name from Received header.
|
286
|
-
r0 = mhead['received']
|
287
|
-
%w|lhost rhost|.each { |a| e[a] ||= '' }
|
288
|
-
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
289
|
-
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
290
|
-
end
|
291
|
-
|
292
|
-
if e['status'].empty? || e['status'] =~ /\A\d[.]0[.]0\z/
|
293
|
-
# There is no value of Status header or the value is 5.0.0, 4.0.0
|
294
|
-
r = Sisimai::SMTP::Status.find(e['diagnosis'])
|
295
|
-
e['status'] = r if r.size > 0
|
296
|
-
end
|
297
266
|
e.each_key { |a| e[a] ||= '' }
|
298
267
|
end
|
299
268
|
|
269
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
300
270
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
301
271
|
end
|
302
272
|
|
data/lib/sisimai/mta/qmail.rb
CHANGED
@@ -29,21 +29,21 @@ module Sisimai
|
|
29
29
|
ReSMTP = {
|
30
30
|
# Error text regular expressions which defined in qmail-remote.c
|
31
31
|
# qmail-remote.c:225| if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
|
32
|
-
|
32
|
+
conn: %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]greeting[ ]failed[.]/x,
|
33
33
|
# qmail-remote.c:231| if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
|
34
|
-
|
34
|
+
ehlo: %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]my[ ]name[ ]was[ ]rejected[.]/x,
|
35
35
|
# qmail-remote.c:238| if (code >= 500) quit("DConnected to "," but sender was rejected");
|
36
36
|
# reason = rejected
|
37
|
-
|
37
|
+
mail: %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]sender[ ]was[ ]rejected[.]/x,
|
38
38
|
# qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
|
39
39
|
# qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
|
40
40
|
# reason = userunknown
|
41
|
-
|
41
|
+
rcpt: %r/(?:Error:)?.+[ ]does[ ]not[ ]like[ ]recipient[.]/x,
|
42
42
|
# qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
|
43
43
|
# qmail-remote.c:266| if (code >= 400) quit("Z"," failed on DATA command");
|
44
44
|
# qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
|
45
45
|
# qmail-remote.c:272| if (code >= 400) quit("Z"," failed after I sent the message");
|
46
|
-
|
46
|
+
data: %r{(?:
|
47
47
|
(?:Error:)?.+[ ]failed[ ]on[ ]DATA[ ]command[.]
|
48
48
|
|(?:Error:)?.+[ ]failed[ ]after[ ]I[ ]sent[ ]the[ ]message[.]
|
49
49
|
)
|
@@ -58,10 +58,10 @@ module Sisimai
|
|
58
58
|
}x
|
59
59
|
ReLDAP = {
|
60
60
|
# qmail-ldap-1.03-20040101.patch:19817 - 19866
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
suspend: %r/Mailaddress is administrative?le?y disabled/, # 5.2.1
|
62
|
+
userunknown: %r/[Ss]orry, no mailbox here by that name/, # 5.1.1
|
63
|
+
exceedlimit: %r/The message exeeded the maximum size the user accepts/, # 5.2.3
|
64
|
+
systemerror: %r{(?>
|
65
65
|
Automatic[ ]homedir[ ]creator[ ]crashed # 4.3.0
|
66
66
|
|Illegal[ ]value[ ]in[ ]LDAP[ ]attribute # 5.3.5
|
67
67
|
|LDAP[ ]attribute[ ]is[ ]not[ ]given[ ]but[ ]mandatory # 5.3.5
|
@@ -89,40 +89,37 @@ module Sisimai
|
|
89
89
|
ReFailure = {
|
90
90
|
# qmail-local.c:589| strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)");
|
91
91
|
# qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
|
92
|
-
|
92
|
+
userunknown: %r{(?:
|
93
93
|
no[ ]mailbox[ ]here[ ]by[ ]that[ ]name
|
94
94
|
|[ ]does[ ]not[ ]like[ ]recipient[.]
|
95
95
|
)
|
96
96
|
}x,
|
97
97
|
# error_str.c:192| X(EDQUOT,"disk quota exceeded")
|
98
|
-
|
98
|
+
mailboxfull: %r/disk[ ]quota[ ]exceeded/x,
|
99
99
|
# qmail-qmtpd.c:233| ... result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)";
|
100
100
|
# qmail-smtpd.c:391| ... out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return;
|
101
|
-
|
101
|
+
mesgtoobig: %r/Message[ ]size[ ]exceeds[ ]fixed[ ]maximum[ ]message[ ]size:/x,
|
102
102
|
# qmail-remote.c:68| Sorry, I couldn't find any host by that name. (#4.1.2)\n"); zerodie();
|
103
103
|
# qmail-remote.c:78| Sorry, I couldn't find any host named ");
|
104
|
-
|
105
|
-
|
104
|
+
hostunknown: %r/\ASorry[,][ ]I[ ]couldn[']t[ ]find[ ]any[ ]host[ ]/x,
|
105
|
+
systemerror: %r{(?>
|
106
106
|
bad[ ]interpreter:[ ]No[ ]such[ ]file[ ]or[ ]directory
|
107
107
|
|system[ ]error
|
108
108
|
|Unable[ ]to\b
|
109
109
|
)
|
110
110
|
}x,
|
111
|
-
|
111
|
+
networkerror: %r{Sorry(?:
|
112
112
|
[,][ ]I[ ]wasn[']t[ ]able[ ]to[ ]establish[ ]an[ ]SMTP[ ]connection
|
113
113
|
|[,][ ]I[ ]couldn[']t[ ]find[ ]a[ ]mail[ ]exchanger[ ]or[ ]IP[ ]address
|
114
114
|
|[.][ ]Although[ ]I[']m[ ]listed[ ]as[ ]a[ ]best[-]preference[ ]MX[ ]
|
115
115
|
or[ ]A[ ]for[ ]that[ ]host
|
116
116
|
)
|
117
117
|
}x,
|
118
|
-
|
118
|
+
systemfull: %r/Requested action not taken: mailbox unavailable [(]not enough free space[)]/,
|
119
119
|
}
|
120
120
|
# qmail-send.c:922| ... (&dline[c],"I'm not going to try again; this message has been in the queue too long.\n")) nomem();
|
121
121
|
ReDelayed = %r/this[ ]message[ ]has[ ]been[ ]in[ ]the[ ]queue[ ]too[ ]long[.]\z/x
|
122
|
-
|
123
122
|
Indicators = Sisimai::MTA.INDICATORS
|
124
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
125
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
126
123
|
|
127
124
|
def description; return 'qmail'; end
|
128
125
|
def smtpagent; return 'qmail'; end
|
@@ -153,11 +150,10 @@ module Sisimai
|
|
153
150
|
match += 1 if mhead['received'].find { |a| a =~ Re0[:received] }
|
154
151
|
return nil if match == 0
|
155
152
|
|
156
|
-
dscontents = [
|
153
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
157
154
|
hasdivided = mbody.split("\n")
|
158
|
-
|
159
|
-
|
160
|
-
previousfn = '' # (String) Previous field name
|
155
|
+
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
156
|
+
blanklines = 0 # (Integer) The number of blank lines
|
161
157
|
readcursor = 0 # (Integer) Points the current cursor position
|
162
158
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
163
159
|
v = nil
|
@@ -166,7 +162,7 @@ module Sisimai
|
|
166
162
|
if readcursor == 0
|
167
163
|
# Beginning of the bounce message or delivery status part
|
168
164
|
if e =~ Re1[:begin]
|
169
|
-
readcursor |= Indicators[:
|
165
|
+
readcursor |= Indicators[:deliverystatus]
|
170
166
|
next
|
171
167
|
end
|
172
168
|
end
|
@@ -181,30 +177,16 @@ module Sisimai
|
|
181
177
|
|
182
178
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
183
179
|
# After "message/rfc822"
|
184
|
-
if
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
next unless RFC822Head.key?(lhs)
|
189
|
-
|
190
|
-
previousfn = lhs
|
191
|
-
rfc822part += e + "\n"
|
192
|
-
|
193
|
-
elsif e =~ /\A[ \t]+/
|
194
|
-
# Continued line from the previous line
|
195
|
-
next if rfc822next[previousfn]
|
196
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
197
|
-
|
198
|
-
else
|
199
|
-
# Check the end of headers in rfc822 part
|
200
|
-
next unless LongFields.key?(previousfn)
|
201
|
-
next unless e.empty?
|
202
|
-
rfc822next[previousfn] = true
|
180
|
+
if e.empty?
|
181
|
+
blanklines += 1
|
182
|
+
break if blanklines > 1
|
183
|
+
next
|
203
184
|
end
|
185
|
+
rfc822list << e
|
204
186
|
|
205
187
|
else
|
206
188
|
# Before "message/rfc822"
|
207
|
-
next if readcursor & Indicators[:
|
189
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
208
190
|
next if e.empty?
|
209
191
|
|
210
192
|
# <kijitora@example.jp>:
|
@@ -243,16 +225,7 @@ module Sisimai
|
|
243
225
|
require 'sisimai/smtp/status'
|
244
226
|
|
245
227
|
dscontents.map do |e|
|
246
|
-
|
247
|
-
e['agent'] = Sisimai::MTA::Qmail.smtpagent
|
248
|
-
|
249
|
-
if mhead['received'].size > 0
|
250
|
-
# Get localhost and remote host name from Received header.
|
251
|
-
r0 = mhead['received']
|
252
|
-
%w|lhost rhost|.each { |a| e[a] ||= '' }
|
253
|
-
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
254
|
-
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
255
|
-
end
|
228
|
+
e['agent'] = Sisimai::MTA::Qmail.smtpagent
|
256
229
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
|
257
230
|
|
258
231
|
unless e['command']
|
@@ -260,7 +233,7 @@ module Sisimai
|
|
260
233
|
ReSMTP.each_key do |r|
|
261
234
|
# Verify each regular expression of SMTP commands
|
262
235
|
next unless e['diagnosis'] =~ ReSMTP[r]
|
263
|
-
e['command'] = r.upcase
|
236
|
+
e['command'] = r.to_s.upcase
|
264
237
|
break
|
265
238
|
end
|
266
239
|
|
@@ -295,12 +268,12 @@ module Sisimai
|
|
295
268
|
if e['alterrors']
|
296
269
|
# Check the value of "alterrors"
|
297
270
|
next unless e['alterrors'] =~ ReFailure[r]
|
298
|
-
e['reason'] = r
|
271
|
+
e['reason'] = r.to_s
|
299
272
|
end
|
300
273
|
break if e['reason']
|
301
274
|
|
302
275
|
next unless e['diagnosis'] =~ ReFailure[r]
|
303
|
-
e['reason'] = r
|
276
|
+
e['reason'] = r.to_s
|
304
277
|
break
|
305
278
|
end
|
306
279
|
|
@@ -308,7 +281,7 @@ module Sisimai
|
|
308
281
|
ReLDAP.each_key do |r|
|
309
282
|
# Verify each regular expression of LDAP errors
|
310
283
|
next unless e['diagnosis'] =~ ReLDAP[r]
|
311
|
-
e['reason'] = r
|
284
|
+
e['reason'] = r.to_s
|
312
285
|
break
|
313
286
|
end
|
314
287
|
end
|
@@ -320,11 +293,10 @@ module Sisimai
|
|
320
293
|
end
|
321
294
|
|
322
295
|
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
323
|
-
e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
|
324
|
-
e['action'] = 'failed' if e['status'] =~ /\A[45]/
|
325
296
|
e.each_key { |a| e[a] ||= '' }
|
326
297
|
end
|
327
298
|
|
299
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
328
300
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
329
301
|
end
|
330
302
|
|
data/lib/sisimai/mta/sendmail.rb
CHANGED
@@ -24,8 +24,6 @@ module Sisimai
|
|
24
24
|
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
25
25
|
}
|
26
26
|
Indicators = Sisimai::MTA.INDICATORS
|
27
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
28
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
29
27
|
|
30
28
|
def description; return 'V8Sendmail: /usr/sbin/sendmail'; end
|
31
29
|
def smtpagent; return 'Sendmail'; end
|
@@ -54,12 +52,11 @@ module Sisimai
|
|
54
52
|
return nil unless mhead['from'] =~ Re0[:from]
|
55
53
|
end
|
56
54
|
|
57
|
-
dscontents = [
|
55
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
58
56
|
hasdivided = mbody.split("\n")
|
59
57
|
havepassed = ['']
|
60
|
-
|
61
|
-
|
62
|
-
previousfn = '' # (String) Previous field name
|
58
|
+
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
59
|
+
blanklines = 0 # (Integer) The number of blank lines
|
63
60
|
readcursor = 0 # (Integer) Points the current cursor position
|
64
61
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
65
62
|
commandtxt = '' # (String) SMTP Command name begin with the string '>>>'
|
@@ -75,12 +72,13 @@ module Sisimai
|
|
75
72
|
|
76
73
|
hasdivided.each do |e|
|
77
74
|
# Save the current line for the next loop
|
78
|
-
havepassed << e
|
75
|
+
havepassed << e
|
76
|
+
p = havepassed[-2]
|
79
77
|
|
80
78
|
if readcursor == 0
|
81
79
|
# Beginning of the bounce message or delivery status part
|
82
80
|
if e =~ Re1[:begin]
|
83
|
-
readcursor |= Indicators[:
|
81
|
+
readcursor |= Indicators[:deliverystatus]
|
84
82
|
next
|
85
83
|
end
|
86
84
|
end
|
@@ -95,30 +93,16 @@ module Sisimai
|
|
95
93
|
|
96
94
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
97
95
|
# After "message/rfc822"
|
98
|
-
if
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
next unless RFC822Head.key?(lhs)
|
103
|
-
|
104
|
-
previousfn = lhs
|
105
|
-
rfc822part += e + "\n"
|
106
|
-
|
107
|
-
elsif e =~ /\A[ \t]+/
|
108
|
-
# Continued line from the previous line
|
109
|
-
next if rfc822next[previousfn]
|
110
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
111
|
-
|
112
|
-
else
|
113
|
-
# Check the end of headers in rfc822 part
|
114
|
-
next unless LongFields.key?(previousfn)
|
115
|
-
next unless e.empty?
|
116
|
-
rfc822next[previousfn] = true
|
96
|
+
if e.empty?
|
97
|
+
blanklines += 1
|
98
|
+
break if blanklines > 1
|
99
|
+
next
|
117
100
|
end
|
101
|
+
rfc822list << e
|
118
102
|
|
119
103
|
else
|
120
104
|
# Before "message/rfc822"
|
121
|
-
next if readcursor & Indicators[:
|
105
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
122
106
|
next if e.empty?
|
123
107
|
|
124
108
|
if connvalues == connheader.keys.size
|
@@ -255,7 +239,6 @@ module Sisimai
|
|
255
239
|
end
|
256
240
|
end
|
257
241
|
end
|
258
|
-
|
259
242
|
return nil if recipients == 0
|
260
243
|
require 'sisimai/string'
|
261
244
|
|
@@ -263,15 +246,6 @@ module Sisimai
|
|
263
246
|
# Set default values if each value is empty.
|
264
247
|
connheader.each_key { |a| e[a] ||= connheader[a] || '' }
|
265
248
|
|
266
|
-
if mhead['received'].size > 0
|
267
|
-
# Get localhost and remote host name from Received header.
|
268
|
-
r0 = mhead['received']
|
269
|
-
%w|lhost rhost|.each { |a| e[a] ||= '' }
|
270
|
-
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
271
|
-
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
272
|
-
end
|
273
|
-
|
274
|
-
e['spec'] ||= 'SMTP'
|
275
249
|
e['agent'] = Sisimai::MTA::Sendmail.smtpagent
|
276
250
|
e['command'] ||= commandtxt
|
277
251
|
if e['command'].empty?
|
@@ -308,6 +282,7 @@ module Sisimai
|
|
308
282
|
e.each_key { |a| e[a] ||= '' }
|
309
283
|
end
|
310
284
|
|
285
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
311
286
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
312
287
|
end
|
313
288
|
|
@@ -19,8 +19,6 @@ module Sisimai
|
|
19
19
|
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
20
20
|
}
|
21
21
|
Indicators = Sisimai::MTA.INDICATORS
|
22
|
-
LongFields = Sisimai::RFC5322.LONGFIELDS
|
23
|
-
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
24
22
|
|
25
23
|
def description; return 'WebSense SurfControl'; end
|
26
24
|
def smtpagent; return 'SurfControl'; end
|
@@ -48,24 +46,24 @@ module Sisimai
|
|
48
46
|
return nil unless mhead['x-mailer']
|
49
47
|
return nil unless mhead['x-mailer'] =~ Re0[:'x-mailer']
|
50
48
|
|
51
|
-
dscontents = [
|
49
|
+
dscontents = [Sisimai::MTA.DELIVERYSTATUS]
|
52
50
|
hasdivided = mbody.split("\n")
|
53
|
-
havepassed = ['']
|
54
|
-
|
55
|
-
|
56
|
-
previousfn = '' # (String) Previous field name
|
51
|
+
havepassed = ['']
|
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
|
v = nil
|
60
57
|
|
61
58
|
hasdivided.each do |e|
|
62
59
|
# Save the current line for the next loop
|
63
|
-
havepassed << e
|
60
|
+
havepassed << e
|
61
|
+
p = havepassed[-2]
|
64
62
|
|
65
63
|
if readcursor == 0
|
66
64
|
# Beginning of the bounce message or delivery status part
|
67
65
|
if e =~ Re1[:begin]
|
68
|
-
readcursor |= Indicators[:
|
66
|
+
readcursor |= Indicators[:deliverystatus]
|
69
67
|
next
|
70
68
|
end
|
71
69
|
end
|
@@ -80,30 +78,16 @@ module Sisimai
|
|
80
78
|
|
81
79
|
if readcursor & Indicators[:'message-rfc822'] > 0
|
82
80
|
# After "message/rfc822"
|
83
|
-
if
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
next unless RFC822Head.key?(lhs)
|
88
|
-
|
89
|
-
previousfn = lhs
|
90
|
-
rfc822part += e + "\n"
|
91
|
-
|
92
|
-
elsif e =~ /\A[ \t]+/
|
93
|
-
# Continued line from the previous line
|
94
|
-
next if rfc822next[previousfn]
|
95
|
-
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
96
|
-
|
97
|
-
else
|
98
|
-
# Check the end of headers in rfc822 part
|
99
|
-
next unless LongFields.key?(previousfn)
|
100
|
-
next unless e.empty?
|
101
|
-
rfc822next[previousfn] = true
|
81
|
+
if e.empty?
|
82
|
+
blanklines += 1
|
83
|
+
break if blanklines > 1
|
84
|
+
next
|
102
85
|
end
|
86
|
+
rfc822list << e
|
103
87
|
|
104
88
|
else
|
105
89
|
# Before "message/rfc822"
|
106
|
-
next if readcursor & Indicators[:
|
90
|
+
next if readcursor & Indicators[:deliverystatus] == 0
|
107
91
|
next if e.empty?
|
108
92
|
|
109
93
|
# Your message could not be sent.
|
@@ -160,29 +144,16 @@ module Sisimai
|
|
160
144
|
end
|
161
145
|
end
|
162
146
|
end
|
163
|
-
|
164
147
|
return nil if recipients == 0
|
165
148
|
require 'sisimai/string'
|
166
|
-
require 'sisimai/smtp/status'
|
167
149
|
|
168
150
|
dscontents.map do |e|
|
169
|
-
e['agent']
|
170
|
-
|
171
|
-
if mhead['received'].size > 0
|
172
|
-
# Get localhost and remote host name from Received header.
|
173
|
-
r0 = mhead['received']
|
174
|
-
%w|lhost rhost|.each { |a| e[a] ||= '' }
|
175
|
-
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
176
|
-
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
177
|
-
end
|
151
|
+
e['agent'] = Sisimai::MTA::SurfControl.smtpagent
|
178
152
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
179
|
-
|
180
|
-
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
181
|
-
e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
|
182
|
-
e['action'] = 'failed' if e['status'] =~ /\A[45]/
|
183
153
|
e.each_key { |a| e[a] ||= '' }
|
184
154
|
end
|
185
155
|
|
156
|
+
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
186
157
|
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
187
158
|
end
|
188
159
|
|