sisimai 4.22.3-java → 4.22.4-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 +1 -1
- data/Benchmarks.mk +54 -0
- data/ChangeLog.md +23 -2
- data/Developers.mk +42 -35
- data/Makefile +10 -0
- data/README-JA.md +13 -13
- data/README.md +14 -14
- data/lib/sisimai.rb +12 -18
- data/lib/sisimai/address.rb +64 -82
- data/lib/sisimai/arf.rb +27 -42
- data/lib/sisimai/bite/email.rb +2 -4
- data/lib/sisimai/bite/email/activehunter.rb +12 -17
- data/lib/sisimai/bite/email/amazonses.rb +30 -48
- data/lib/sisimai/bite/email/amazonworkmail.rb +20 -27
- data/lib/sisimai/bite/email/aol.rb +27 -35
- data/lib/sisimai/bite/email/apachejames.rb +17 -28
- data/lib/sisimai/bite/email/bigfoot.rb +20 -33
- data/lib/sisimai/bite/email/biglobe.rb +15 -24
- data/lib/sisimai/bite/email/courier.rb +37 -61
- data/lib/sisimai/bite/email/domino.rb +19 -28
- data/lib/sisimai/bite/email/einsundeins.rb +20 -34
- data/lib/sisimai/bite/email/exchange2003.rb +25 -43
- data/lib/sisimai/bite/email/exchange2007.rb +15 -23
- data/lib/sisimai/bite/email/exim.rb +101 -120
- data/lib/sisimai/bite/email/ezweb.rb +28 -44
- data/lib/sisimai/bite/email/facebook.rb +26 -37
- data/lib/sisimai/bite/email/fml.rb +11 -20
- data/lib/sisimai/bite/email/gmx.rb +17 -27
- data/lib/sisimai/bite/email/google.rb +19 -29
- data/lib/sisimai/bite/email/gsuite.rb +39 -48
- data/lib/sisimai/bite/email/imailserver.rb +25 -39
- data/lib/sisimai/bite/email/interscanmss.rb +19 -26
- data/lib/sisimai/bite/email/kddi.rb +20 -33
- data/lib/sisimai/bite/email/mailfoundry.rb +14 -24
- data/lib/sisimai/bite/email/mailmarshalsmtp.rb +15 -24
- data/lib/sisimai/bite/email/mailru.rb +40 -59
- data/lib/sisimai/bite/email/mcafee.rb +21 -35
- data/lib/sisimai/bite/email/messagelabs.rb +23 -38
- data/lib/sisimai/bite/email/messagingserver.rb +15 -27
- data/lib/sisimai/bite/email/mfilter.rb +19 -28
- data/lib/sisimai/bite/email/mxlogic.rb +31 -49
- data/lib/sisimai/bite/email/notes.rb +16 -24
- data/lib/sisimai/bite/email/office365.rb +29 -38
- data/lib/sisimai/bite/email/opensmtpd.rb +50 -67
- data/lib/sisimai/bite/email/outlook.rb +24 -36
- data/lib/sisimai/bite/email/postfix.rb +33 -42
- data/lib/sisimai/bite/email/qmail.rb +44 -59
- data/lib/sisimai/bite/email/receivingses.rb +28 -36
- data/lib/sisimai/bite/email/sendgrid.rb +28 -37
- data/lib/sisimai/bite/email/sendmail.rb +35 -51
- data/lib/sisimai/bite/email/surfcontrol.rb +17 -25
- data/lib/sisimai/bite/email/userdefined.rb +17 -28
- data/lib/sisimai/bite/email/v5sendmail.rb +32 -41
- data/lib/sisimai/bite/email/verizon.rb +31 -56
- data/lib/sisimai/bite/email/x1.rb +11 -18
- data/lib/sisimai/bite/email/x2.rb +11 -23
- data/lib/sisimai/bite/email/x3.rb +10 -19
- data/lib/sisimai/bite/email/x4.rb +46 -65
- data/lib/sisimai/bite/email/x5.rb +26 -37
- data/lib/sisimai/bite/email/yahoo.rb +11 -19
- data/lib/sisimai/bite/email/yandex.rb +19 -30
- data/lib/sisimai/bite/email/zoho.rb +21 -30
- data/lib/sisimai/bite/json.rb +1 -2
- data/lib/sisimai/bite/json/amazonses.rb +20 -25
- data/lib/sisimai/bite/json/sendgrid.rb +1 -1
- data/lib/sisimai/data.rb +36 -55
- data/lib/sisimai/data/json.rb +3 -3
- data/lib/sisimai/data/yaml.rb +1 -1
- data/lib/sisimai/datetime.rb +5 -21
- data/lib/sisimai/mail.rb +4 -6
- data/lib/sisimai/mail/maildir.rb +1 -1
- data/lib/sisimai/mda.rb +41 -44
- data/lib/sisimai/message.rb +2 -3
- data/lib/sisimai/message/email.rb +42 -52
- data/lib/sisimai/message/json.rb +7 -7
- data/lib/sisimai/mime.rb +25 -23
- data/lib/sisimai/order/email.rb +2 -2
- data/lib/sisimai/order/json.rb +2 -7
- data/lib/sisimai/reason.rb +41 -46
- data/lib/sisimai/reason/blocked.rb +60 -71
- data/lib/sisimai/reason/contenterror.rb +4 -8
- data/lib/sisimai/reason/delivered.rb +1 -3
- data/lib/sisimai/reason/exceedlimit.rb +10 -20
- data/lib/sisimai/reason/expired.rb +5 -9
- data/lib/sisimai/reason/feedback.rb +1 -3
- data/lib/sisimai/reason/filtered.rb +19 -38
- data/lib/sisimai/reason/hasmoved.rb +5 -8
- data/lib/sisimai/reason/hostunknown.rb +11 -18
- data/lib/sisimai/reason/mailboxfull.rb +14 -24
- data/lib/sisimai/reason/mailererror.rb +3 -5
- data/lib/sisimai/reason/mesgtoobig.rb +15 -25
- data/lib/sisimai/reason/networkerror.rb +8 -10
- data/lib/sisimai/reason/norelaying.rb +9 -14
- data/lib/sisimai/reason/notaccept.rb +9 -21
- data/lib/sisimai/reason/onhold.rb +3 -8
- data/lib/sisimai/reason/policyviolation.rb +8 -10
- data/lib/sisimai/reason/rejected.rb +36 -49
- data/lib/sisimai/reason/securityerror.rb +11 -13
- data/lib/sisimai/reason/spamdetected.rb +23 -37
- data/lib/sisimai/reason/suspend.rb +9 -10
- data/lib/sisimai/reason/syntaxerror.rb +3 -4
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +2 -4
- data/lib/sisimai/reason/toomanyconn.rb +17 -30
- data/lib/sisimai/reason/undefined.rb +1 -3
- data/lib/sisimai/reason/userunknown.rb +28 -38
- data/lib/sisimai/reason/vacation.rb +4 -6
- data/lib/sisimai/reason/virusdetected.rb +4 -6
- data/lib/sisimai/rfc2606.rb +1 -2
- data/lib/sisimai/rfc3464.rb +87 -101
- data/lib/sisimai/rfc3834.rb +29 -39
- data/lib/sisimai/rfc5322.rb +17 -24
- data/lib/sisimai/rhost.rb +10 -7
- data/lib/sisimai/rhost/exchangeonline.rb +124 -255
- data/lib/sisimai/rhost/franceptt.rb +2 -2
- data/lib/sisimai/rhost/godaddy.rb +12 -25
- data/lib/sisimai/rhost/googleapps.rb +82 -183
- data/lib/sisimai/smtp.rb +4 -4
- data/lib/sisimai/smtp/error.rb +8 -8
- data/lib/sisimai/smtp/reply.rb +1 -1
- data/lib/sisimai/smtp/status.rb +1 -0
- data/lib/sisimai/string.rb +5 -7
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/README.md +1 -1
- data/set-of-emails/maildir/bsd/README.md +50 -50
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +4 -4
- data/lib/sisimai/skeleton.rb +0 -43
@@ -6,26 +6,19 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/ApacheJames.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
:'received' => %r/JAMES SMTP Server/,
|
12
|
-
:'message-id' => %r/\d+[.]JavaMail[.].+[@]/,
|
13
|
-
}.freeze
|
14
|
-
Re1 = {
|
9
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
StartingOf = {
|
15
11
|
# apache-james-2.3.2/src/java/org/apache/james/transport/mailets/
|
16
12
|
# AbstractNotify.java|124: out.println("Error message below:");
|
17
13
|
# AbstractNotify.java|128: out.println("Message details:");
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
14
|
+
message: ['Content-Disposition: inline'],
|
15
|
+
rfc822: ['Content-Type: message/rfc822'],
|
16
|
+
error: ['Error message below:'],
|
22
17
|
}.freeze
|
23
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
24
18
|
|
25
19
|
def description; return 'Java Apache Mail Enterprise Server'; end
|
26
20
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
27
21
|
def headerlist; return []; end
|
28
|
-
def pattern; return Re0; end
|
29
22
|
|
30
23
|
# Parse bounce messages from Apache James
|
31
24
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -43,9 +36,9 @@ module Sisimai::Bite::Email
|
|
43
36
|
return nil unless mbody
|
44
37
|
|
45
38
|
match = 0
|
46
|
-
match += 1 if mhead['subject']
|
47
|
-
match += 1 if mhead['message-id']
|
48
|
-
match += 1 if mhead['received'].find { |a| a
|
39
|
+
match += 1 if mhead['subject'] == '[BOUNCE]'
|
40
|
+
match += 1 if mhead['message-id'].to_s.include?('.JavaMail.')
|
41
|
+
match += 1 if mhead['received'].find { |a| a.include?('JAMES SMTP Server') }
|
49
42
|
return if match.zero?
|
50
43
|
|
51
44
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
@@ -59,10 +52,10 @@ module Sisimai::Bite::Email
|
|
59
52
|
gotmessage = -1 # (Integer) Flag for error message
|
60
53
|
v = nil
|
61
54
|
|
62
|
-
hasdivided.
|
55
|
+
while e = hasdivided.shift do
|
63
56
|
if readcursor.zero?
|
64
57
|
# Beginning of the bounce message or delivery status part
|
65
|
-
if e
|
58
|
+
if e.start_with?(StartingOf[:message][0])
|
66
59
|
readcursor |= Indicators[:deliverystatus]
|
67
60
|
next
|
68
61
|
end
|
@@ -70,7 +63,7 @@ module Sisimai::Bite::Email
|
|
70
63
|
|
71
64
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
72
65
|
# Beginning of the original message part
|
73
|
-
if e
|
66
|
+
if e.start_with?(StartingOf[:rfc822][0])
|
74
67
|
readcursor |= Indicators[:'message-rfc822']
|
75
68
|
next
|
76
69
|
end
|
@@ -84,7 +77,6 @@ module Sisimai::Bite::Email
|
|
84
77
|
next
|
85
78
|
end
|
86
79
|
rfc822list << e
|
87
|
-
|
88
80
|
else
|
89
81
|
# Before "message/rfc822"
|
90
82
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -118,12 +110,11 @@ module Sisimai::Bite::Email
|
|
118
110
|
elsif cv = e.match(/\A[ ][ ]Subject:[ ](.+)\z/)
|
119
111
|
# Subject: Nyaaan
|
120
112
|
subjecttxt = cv[1]
|
121
|
-
|
122
113
|
else
|
123
114
|
next if gotmessage == 1
|
124
115
|
if v['diagnosis']
|
125
116
|
# Get an error message text
|
126
|
-
if e
|
117
|
+
if e.start_with?('Message details:')
|
127
118
|
# Message details:
|
128
119
|
# Subject: nyaan
|
129
120
|
# ...
|
@@ -132,27 +123,25 @@ module Sisimai::Bite::Email
|
|
132
123
|
# Append error message text like the followng:
|
133
124
|
# Error message below:
|
134
125
|
# 550 - Requested action not taken: no such user here
|
135
|
-
v['diagnosis']
|
136
|
-
v['diagnosis'] += ' ' + e
|
126
|
+
v['diagnosis'] << ' ' << e
|
137
127
|
end
|
138
|
-
|
139
128
|
else
|
140
129
|
# Error message below:
|
141
130
|
# 550 - Requested action not taken: no such user here
|
142
|
-
v['diagnosis'] = e if e
|
131
|
+
v['diagnosis'] = e if e == StartingOf[:error][0]
|
143
132
|
end
|
144
133
|
end
|
145
134
|
end
|
146
135
|
end
|
147
136
|
return nil if recipients.zero?
|
148
|
-
require 'sisimai/string'
|
149
137
|
|
150
|
-
unless rfc822list.find { |a| a
|
138
|
+
unless rfc822list.find { |a| a.start_with?('Subject:') }
|
151
139
|
# Set the value of subjecttxt as a Subject if there is no original
|
152
140
|
# message in the bounce mail.
|
153
|
-
rfc822list <<
|
141
|
+
rfc822list << ('Subject: ' << subjecttxt)
|
154
142
|
end
|
155
143
|
|
144
|
+
require 'sisimai/string'
|
156
145
|
dscontents.map do |e|
|
157
146
|
e['agent'] = self.smtpagent
|
158
147
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'] || diagnostic)
|
@@ -6,22 +6,13 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Bigfoot.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
Re0 = {
|
10
|
-
:from => %r/[@]bigfoot[.]com[>]/,
|
11
|
-
:subject => %r/\AReturned mail: /,
|
12
|
-
:received => %r/\w+[.]bigfoot[.]com\b/,
|
13
|
-
}.freeze
|
14
|
-
Re1 = {
|
15
|
-
:begin => %r/\A[ \t]+[-]+[ \t]*Transcript of session follows/,
|
16
|
-
:rfc822 => %r|\AContent-Type: message/partial|,
|
17
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
18
|
-
}.freeze
|
19
9
|
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
StartingOf = { rfc822: ['Content-Type: message/partial'] }.freeze
|
11
|
+
MarkingsOf = { message: %r/\A[ \t]+[-]+[ \t]*Transcript of session follows/ }.freeze
|
20
12
|
|
21
13
|
def description; return 'Bigfoot: http://www.bigfoot.com'; end
|
22
14
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
23
15
|
def headerlist; return []; end
|
24
|
-
def pattern; return Re0; end
|
25
16
|
|
26
17
|
# Parse bounce messages from Bigfoot
|
27
18
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -37,10 +28,11 @@ module Sisimai::Bite::Email
|
|
37
28
|
def scan(mhead, mbody)
|
38
29
|
return nil unless mhead
|
39
30
|
return nil unless mbody
|
40
|
-
|
31
|
+
|
32
|
+
# :subject => %r/\AReturned mail: /,
|
41
33
|
match = 0
|
42
|
-
match += 1 if mhead['from']
|
43
|
-
match += 1 if mhead['received'].find { |a| a
|
34
|
+
match += 1 if mhead['from'].include?('@bigfoot.com>')
|
35
|
+
match += 1 if mhead['received'].find { |a| a.include?('.bigfoot.com') }
|
44
36
|
return nil if match.zero?
|
45
37
|
|
46
38
|
require 'sisimai/address'
|
@@ -60,14 +52,14 @@ module Sisimai::Bite::Email
|
|
60
52
|
}
|
61
53
|
v = nil
|
62
54
|
|
63
|
-
hasdivided.
|
55
|
+
while e = hasdivided.shift do
|
64
56
|
# Save the current line for the next loop
|
65
57
|
havepassed << e
|
66
58
|
p = havepassed[-2]
|
67
59
|
|
68
60
|
if readcursor.zero?
|
69
61
|
# Beginning of the bounce message or delivery status part
|
70
|
-
if e =~
|
62
|
+
if e =~ MarkingsOf[:message]
|
71
63
|
readcursor |= Indicators[:deliverystatus]
|
72
64
|
next
|
73
65
|
end
|
@@ -75,7 +67,7 @@ module Sisimai::Bite::Email
|
|
75
67
|
|
76
68
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
77
69
|
# Beginning of the original message part
|
78
|
-
if e
|
70
|
+
if e.start_with?(StartingOf[:rfc822][0])
|
79
71
|
readcursor |= Indicators[:'message-rfc822']
|
80
72
|
next
|
81
73
|
end
|
@@ -89,7 +81,6 @@ module Sisimai::Bite::Email
|
|
89
81
|
next
|
90
82
|
end
|
91
83
|
rfc822list << e
|
92
|
-
|
93
84
|
else
|
94
85
|
# Before "message/rfc822"
|
95
86
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -104,7 +95,7 @@ module Sisimai::Bite::Email
|
|
104
95
|
# Last-Attempt-Date: Sun, 28 Dec 2014 18:17:16 -0800
|
105
96
|
v = dscontents[-1]
|
106
97
|
|
107
|
-
if cv = e.match(/\
|
98
|
+
if cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
|
108
99
|
# Final-Recipient: RFC822; <destinaion@example.net>
|
109
100
|
if v['recipient']
|
110
101
|
# There are multiple recipient addresses in the message body.
|
@@ -114,33 +105,30 @@ module Sisimai::Bite::Email
|
|
114
105
|
v['recipient'] = Sisimai::Address.s3s4(cv[1])
|
115
106
|
recipients += 1
|
116
107
|
|
117
|
-
elsif cv = e.match(/\
|
108
|
+
elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
|
118
109
|
# Action: failed
|
119
110
|
v['action'] = cv[1].downcase
|
120
111
|
|
121
|
-
elsif cv = e.match(/\
|
112
|
+
elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
|
122
113
|
# Status: 5.7.1
|
123
114
|
v['status'] = cv[1]
|
124
115
|
|
125
|
-
elsif cv = e.match(/\
|
116
|
+
elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
126
117
|
# Remote-MTA: DNS; p01c11m075.mx.example.net
|
127
118
|
v['rhost'] = cv[1].downcase
|
128
|
-
|
129
119
|
else
|
130
120
|
# Get error message
|
131
|
-
if cv = e.match(/\
|
121
|
+
if cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
|
132
122
|
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
133
123
|
v['spec'] = cv[1].upcase
|
134
124
|
v['diagnosis'] = cv[2]
|
135
125
|
|
136
|
-
elsif p
|
126
|
+
elsif p.start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
|
137
127
|
# Continued line of the value of Diagnostic-Code header
|
138
|
-
v['diagnosis']
|
139
|
-
|
140
|
-
havepassed[-1] = 'Diagnostic-Code: ' + e
|
128
|
+
v['diagnosis'] << ' ' << cv[1]
|
129
|
+
havepassed[-1] = 'Diagnostic-Code: ' << e
|
141
130
|
end
|
142
131
|
end
|
143
|
-
|
144
132
|
else
|
145
133
|
# ----- Transcript of session follows -----
|
146
134
|
# >>> RCPT TO:<destinaion@example.net>
|
@@ -152,18 +140,17 @@ module Sisimai::Bite::Email
|
|
152
140
|
# Reporting-MTA: dns; litemail57.bigfoot.com
|
153
141
|
# Arrival-Date: Sun, 28 Dec 2014 18:17:16 -0800
|
154
142
|
#
|
155
|
-
if cv = e.match(/\
|
143
|
+
if cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
156
144
|
# Reporting-MTA: dns; mx.example.jp
|
157
145
|
next if connheader['lhost'].size > 0
|
158
146
|
connheader['lhost'] = cv[1].downcase
|
159
147
|
connvalues += 1
|
160
148
|
|
161
|
-
elsif cv = e.match(/\
|
149
|
+
elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
|
162
150
|
# Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
|
163
151
|
next if connheader['date'].size > 0
|
164
152
|
connheader['date'] = cv[1]
|
165
153
|
connvalues += 1
|
166
|
-
|
167
154
|
else
|
168
155
|
# ----- Transcript of session follows -----
|
169
156
|
# >>> RCPT TO:<destinaion@example.net>
|
@@ -183,8 +170,8 @@ module Sisimai::Bite::Email
|
|
183
170
|
end
|
184
171
|
end
|
185
172
|
return nil if recipients.zero?
|
186
|
-
require 'sisimai/string'
|
187
173
|
|
174
|
+
require 'sisimai/string'
|
188
175
|
dscontents.map do |e|
|
189
176
|
# Set default values if each value is empty.
|
190
177
|
connheader.each_key { |a| e[a] ||= connheader[a] || '' }
|
@@ -6,26 +6,20 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Biglobe.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
:
|
12
|
-
|
13
|
-
|
14
|
-
:begin => %r/\A ----- The following addresses had delivery problems -----\z/,
|
15
|
-
:error => %r/\A ----- Non-delivered information -----\z/,
|
16
|
-
:rfc822 => %r|\AContent-Type: message/rfc822\z|,
|
17
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
9
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
StartingOf = {
|
11
|
+
message: [' ----- The following addresses had delivery problems -----'],
|
12
|
+
error: [' ----- Non-delivered information -----'],
|
13
|
+
rfc822: ['Content-Type: message/rfc822'],
|
18
14
|
}.freeze
|
19
|
-
|
15
|
+
ReFailures = {
|
20
16
|
filtered: %r/Mail Delivery Failed[.]+ User unknown/,
|
21
17
|
mailboxfull: %r/The number of messages in recipient's mailbox exceeded the local limit[.]/,
|
22
18
|
}.freeze
|
23
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
24
19
|
|
25
20
|
def description; return 'BIGLOBE: http://www.biglobe.ne.jp'; end
|
26
21
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
27
22
|
def headerlist; return []; end
|
28
|
-
def pattern; return Re0; end
|
29
23
|
|
30
24
|
# Parse bounce messages from Biglobe
|
31
25
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -41,8 +35,8 @@ module Sisimai::Bite::Email
|
|
41
35
|
def scan(mhead, mbody)
|
42
36
|
return nil unless mhead
|
43
37
|
return nil unless mbody
|
44
|
-
return nil unless mhead['from']
|
45
|
-
return nil unless mhead['subject']
|
38
|
+
return nil unless mhead['from'] =~ /postmaster[@](?:biglobe|inacatv|tmtv|ttv)[.]ne[.]jp/
|
39
|
+
return nil unless mhead['subject'].start_with?('Returned mail:')
|
46
40
|
|
47
41
|
require 'sisimai/address'
|
48
42
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
@@ -53,10 +47,10 @@ module Sisimai::Bite::Email
|
|
53
47
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
54
48
|
v = nil
|
55
49
|
|
56
|
-
hasdivided.
|
50
|
+
while e = hasdivided.shift do
|
57
51
|
if readcursor.zero?
|
58
52
|
# Beginning of the bounce message or delivery status part
|
59
|
-
if e
|
53
|
+
if e == StartingOf[:message][0]
|
60
54
|
readcursor |= Indicators[:deliverystatus]
|
61
55
|
next
|
62
56
|
end
|
@@ -64,7 +58,7 @@ module Sisimai::Bite::Email
|
|
64
58
|
|
65
59
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
66
60
|
# Beginning of the original message part
|
67
|
-
if e
|
61
|
+
if e == StartingOf[:rfc822][0]
|
68
62
|
readcursor |= Indicators[:'message-rfc822']
|
69
63
|
next
|
70
64
|
end
|
@@ -78,7 +72,6 @@ module Sisimai::Bite::Email
|
|
78
72
|
next
|
79
73
|
end
|
80
74
|
rfc822list << e
|
81
|
-
|
82
75
|
else
|
83
76
|
# Before "message/rfc822"
|
84
77
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -114,25 +107,23 @@ module Sisimai::Bite::Email
|
|
114
107
|
v['recipient'] = r
|
115
108
|
recipients += 1
|
116
109
|
end
|
117
|
-
|
118
110
|
else
|
119
111
|
next if e =~ /\A[^\w]/
|
120
112
|
v['diagnosis'] ||= ''
|
121
|
-
v['diagnosis']
|
113
|
+
v['diagnosis'] << e + ' '
|
122
114
|
end
|
123
115
|
end
|
124
116
|
end
|
125
|
-
|
126
117
|
return nil if recipients.zero?
|
127
|
-
require 'sisimai/string'
|
128
118
|
|
119
|
+
require 'sisimai/string'
|
129
120
|
dscontents.map do |e|
|
130
121
|
e['agent'] = self.smtpagent
|
131
122
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
132
123
|
|
133
|
-
|
124
|
+
ReFailures.each_key do |r|
|
134
125
|
# Verify each regular expression of session errors
|
135
|
-
next unless e['diagnosis'] =~
|
126
|
+
next unless e['diagnosis'] =~ ReFailures[r]
|
136
127
|
e['reason'] = r.to_s
|
137
128
|
break
|
138
129
|
end
|
@@ -7,46 +7,28 @@ module Sisimai::Bite::Email
|
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
9
|
# http://www.courier-mta.org/courierdsn.html
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:'
|
14
|
-
|
15
|
-
|WARNING:[ ]delayed[ ]mail[.]
|
16
|
-
)
|
17
|
-
}x,
|
18
|
-
:'message-id' => %r/\A[<]courier[.][0-9A-F]+[.]/,
|
19
|
-
}.freeze
|
20
|
-
Re1 = {
|
21
|
-
:begin => %r{(?:
|
22
|
-
DELAYS[ ]IN[ ]DELIVERING[ ]YOUR[ ]MESSAGE
|
23
|
-
|UNDELIVERABLE[ ]MAIL
|
24
|
-
)
|
25
|
-
}x,
|
26
|
-
:rfc822 => %r{\AContent-Type:[ ]*(?:
|
27
|
-
message/rfc822
|
28
|
-
|text/rfc822-headers
|
29
|
-
)\z
|
30
|
-
}x,
|
31
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
10
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
11
|
+
StartingOf = {
|
12
|
+
# courier/module.dsn/dsn*.txt
|
13
|
+
message: ['DELAYS IN DELIVERING YOUR MESSAGE', 'UNDELIVERABLE MAIL'],
|
14
|
+
rfc822: ['Content-Type: message/rfc822', 'Content-Type: text/rfc822-headers'],
|
32
15
|
}.freeze
|
33
|
-
|
16
|
+
|
17
|
+
ReFailures = {
|
34
18
|
# courier/module.esmtp/esmtpclient.c:526| hard_error(del, ctf, "No such domain.");
|
35
|
-
hostunknown: %r/\ANo
|
19
|
+
hostunknown: %r/\ANo such domain[.]\z/,
|
36
20
|
# courier/module.esmtp/esmtpclient.c:531| hard_error(del, ctf,
|
37
21
|
# courier/module.esmtp/esmtpclient.c:532| "This domain's DNS violates RFC 1035.");
|
38
|
-
systemerror: %r/\AThis
|
22
|
+
systemerror: %r/\AThis domain's DNS violates RFC 1035[.]\z/,
|
39
23
|
}.freeze
|
40
|
-
|
24
|
+
ReDelaying = {
|
41
25
|
# courier/module.esmtp/esmtpclient.c:535| soft_error(del, ctf, "DNS lookup failed.");
|
42
|
-
networkerror: %r/\ADNS
|
26
|
+
networkerror: %r/\ADNS lookup failed[.]\z/,
|
43
27
|
}.freeze
|
44
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
45
28
|
|
46
29
|
def description; return 'Courier MTA'; end
|
47
30
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
48
31
|
def headerlist; return []; end
|
49
|
-
def pattern; return Re0; end
|
50
32
|
|
51
33
|
# Parse bounce messages from Courier MTA
|
52
34
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -64,11 +46,11 @@ module Sisimai::Bite::Email
|
|
64
46
|
return nil unless mbody
|
65
47
|
|
66
48
|
match = 0
|
67
|
-
match += 1 if mhead['from']
|
68
|
-
match += 1 if mhead['subject'] =~
|
49
|
+
match += 1 if mhead['from'].include?('Courier mail server at ')
|
50
|
+
match += 1 if mhead['subject'] =~ /(?:NOTICE: mail delivery status[.]|WARNING: delayed mail[.])/
|
69
51
|
if mhead['message-id']
|
70
52
|
# Message-ID: <courier.4D025E3A.00001792@5jo.example.org>
|
71
|
-
match += 1 if mhead['message-id'] =~
|
53
|
+
match += 1 if mhead['message-id'] =~ /\A[<]courier[.][0-9A-F]+[.]/
|
72
54
|
end
|
73
55
|
return nil if match.zero?
|
74
56
|
|
@@ -88,14 +70,14 @@ module Sisimai::Bite::Email
|
|
88
70
|
}
|
89
71
|
v = nil
|
90
72
|
|
91
|
-
hasdivided.
|
73
|
+
while e = hasdivided.shift do
|
92
74
|
# Save the current line for the next loop
|
93
75
|
havepassed << e
|
94
76
|
p = havepassed[-2]
|
95
77
|
|
96
78
|
if readcursor.zero?
|
97
79
|
# Beginning of the bounce message or delivery status part
|
98
|
-
if e
|
80
|
+
if e.include?(StartingOf[:message][0]) || e.include?(StartingOf[:message][1])
|
99
81
|
readcursor |= Indicators[:deliverystatus]
|
100
82
|
next
|
101
83
|
end
|
@@ -103,7 +85,7 @@ module Sisimai::Bite::Email
|
|
103
85
|
|
104
86
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
105
87
|
# Beginning of the original message part
|
106
|
-
if e
|
88
|
+
if e.start_with?(StartingOf[:rfc822][0], StartingOf[:rfc822][1])
|
107
89
|
readcursor |= Indicators[:'message-rfc822']
|
108
90
|
next
|
109
91
|
end
|
@@ -117,7 +99,6 @@ module Sisimai::Bite::Email
|
|
117
99
|
next
|
118
100
|
end
|
119
101
|
rfc822list << e
|
120
|
-
|
121
102
|
else
|
122
103
|
# Before "message/rfc822"
|
123
104
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -131,7 +112,7 @@ module Sisimai::Bite::Email
|
|
131
112
|
# Diagnostic-Code: smtp; 550 5.1.1 <kijitora@example.co.jp>... User Unknown
|
132
113
|
v = dscontents[-1]
|
133
114
|
|
134
|
-
if cv = e.match(/\
|
115
|
+
if cv = e.match(/\AFinal-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
|
135
116
|
# Final-Recipient: rfc822; kijitora@example.co.jp
|
136
117
|
if v['recipient']
|
137
118
|
# There are multiple recipient addresses in the message body.
|
@@ -141,46 +122,41 @@ module Sisimai::Bite::Email
|
|
141
122
|
v['recipient'] = cv[1]
|
142
123
|
recipients += 1
|
143
124
|
|
144
|
-
elsif cv = e.match(/\
|
125
|
+
elsif cv = e.match(/\AX-Actual-Recipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
|
145
126
|
# X-Actual-Recipient: RFC822; kijitora@example.co.jp
|
146
127
|
v['alias'] = cv[1]
|
147
128
|
|
148
|
-
elsif cv = e.match(/\
|
129
|
+
elsif cv = e.match(/\AAction:[ ]*(.+)\z/)
|
149
130
|
# Action: failed
|
150
131
|
v['action'] = cv[1].downcase
|
151
132
|
|
152
|
-
elsif cv = e.match(/\
|
133
|
+
elsif cv = e.match(/\AStatus:[ ]*(\d[.]\d+[.]\d+)/)
|
153
134
|
# Status: 5.1.1
|
154
135
|
# Status:5.2.0
|
155
136
|
# Status: 5.1.0 (permanent failure)
|
156
137
|
v['status'] = cv[1]
|
157
138
|
|
158
|
-
elsif cv = e.match(/\
|
139
|
+
elsif cv = e.match(/\ARemote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
159
140
|
# Remote-MTA: DNS; mx.example.jp
|
141
|
+
# Get the first element
|
160
142
|
v['rhost'] = cv[1].downcase
|
161
|
-
|
162
|
-
# Get the first element
|
163
|
-
v['rhost'] = v['rhost'].split(' ').shift
|
164
|
-
end
|
143
|
+
v['rhost'] = v['rhost'].split(' ').shift if v['rhost'].include?(' ')
|
165
144
|
|
166
|
-
elsif cv = e.match(/\
|
145
|
+
elsif cv = e.match(/\ALast-Attempt-Date:[ ]*(.+)\z/)
|
167
146
|
# Last-Attempt-Date: Fri, 14 Feb 2014 12:30:08 -0500
|
168
147
|
v['date'] = cv[1]
|
169
|
-
|
170
148
|
else
|
171
|
-
if cv = e.match(/\
|
149
|
+
if cv = e.match(/\ADiagnostic-Code:[ ]*(.+?);[ ]*(.+)\z/)
|
172
150
|
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
173
151
|
v['spec'] = cv[1].upcase
|
174
152
|
v['diagnosis'] = cv[2]
|
175
153
|
|
176
|
-
elsif p
|
154
|
+
elsif p.start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
|
177
155
|
# Continued line of the value of Diagnostic-Code header
|
178
|
-
v['diagnosis']
|
179
|
-
|
180
|
-
havepassed[-1] = 'Diagnostic-Code: ' + e
|
156
|
+
v['diagnosis'] << ' ' << cv[1]
|
157
|
+
havepassed[-1] = 'Diagnostic-Code: ' << e
|
181
158
|
end
|
182
159
|
end
|
183
|
-
|
184
160
|
else
|
185
161
|
# This is a delivery status notification from marutamachi.example.org,
|
186
162
|
# running the Courier mail server, version 0.65.2.
|
@@ -205,19 +181,19 @@ module Sisimai::Bite::Email
|
|
205
181
|
next if commandtxt.size > 0
|
206
182
|
commandtxt = cv[1]
|
207
183
|
|
208
|
-
elsif cv = e.match(/\
|
184
|
+
elsif cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
209
185
|
# Reporting-MTA: dns; mx.example.jp
|
210
186
|
next if connheader['rhost'].size > 0
|
211
187
|
connheader['rhost'] = cv[1].downcase
|
212
188
|
connvalues += 1
|
213
189
|
|
214
|
-
elsif cv = e.match(/\
|
190
|
+
elsif cv = e.match(/\AReceived-From-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
|
215
191
|
# Received-From-MTA: DNS; x1x2x3x4.dhcp.example.ne.jp
|
216
192
|
next if connheader['lhost'].size > 0
|
217
193
|
connheader['lhost'] = cv[1].downcase
|
218
194
|
connvalues += 1
|
219
195
|
|
220
|
-
elsif cv = e.match(/\
|
196
|
+
elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
|
221
197
|
# Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
|
222
198
|
next if connheader['date'].size > 0
|
223
199
|
connheader['date'] = cv[1]
|
@@ -227,24 +203,24 @@ module Sisimai::Bite::Email
|
|
227
203
|
end
|
228
204
|
end
|
229
205
|
return nil if recipients.zero?
|
230
|
-
require 'sisimai/string'
|
231
206
|
|
207
|
+
require 'sisimai/string'
|
232
208
|
dscontents.map do |e|
|
233
209
|
# Set default values if each value is empty.
|
234
210
|
connheader.each_key { |a| e[a] ||= connheader[a] || '' }
|
235
211
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
236
212
|
|
237
|
-
|
213
|
+
ReFailures.each_key do |r|
|
238
214
|
# Verify each regular expression of session errors
|
239
|
-
next unless e['diagnosis'] =~
|
215
|
+
next unless e['diagnosis'] =~ ReFailures[r]
|
240
216
|
e['reason'] = r.to_s
|
241
217
|
break
|
242
218
|
end
|
243
219
|
|
244
220
|
unless e['reason']
|
245
|
-
|
221
|
+
ReDelaying.each_key do |r|
|
246
222
|
# Verify each regular expression of session errors
|
247
|
-
next unless e['diagnosis'] =~
|
223
|
+
next unless e['diagnosis'] =~ ReDelaying[r]
|
248
224
|
e['reason'] = r.to_s
|
249
225
|
break
|
250
226
|
end
|