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,15 +6,12 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Domino.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:begin => %r/\AYour message/,
|
14
|
-
:rfc822 => %r|\AContent-Type: message/delivery-status\z|,
|
15
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
9
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
StartingOf = {
|
11
|
+
message: ['Your message'],
|
12
|
+
rfc822: ['Content-Type: message/delivery-status'],
|
16
13
|
}.freeze
|
17
|
-
|
14
|
+
ReFailures = {
|
18
15
|
userunknown: %r{(?>
|
19
16
|
not[ ]listed[ ]in[ ](?:
|
20
17
|
Domino[ ]Directory
|
@@ -23,15 +20,13 @@ module Sisimai::Bite::Email
|
|
23
20
|
|Domino[ ]ディレクトリには見つかりません
|
24
21
|
)
|
25
22
|
}x,
|
26
|
-
filtered: %r/Cannot
|
27
|
-
systemerror: %r/Several
|
23
|
+
filtered: %r/Cannot route mail to user/,
|
24
|
+
systemerror: %r/Several matches found in Domino Directory/,
|
28
25
|
}.freeze
|
29
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
30
26
|
|
31
27
|
def description; return 'IBM Domino Server'; end
|
32
28
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
33
29
|
def headerlist; return []; end
|
34
|
-
def pattern; return Re0; end
|
35
30
|
|
36
31
|
# Parse bounce messages from IBM Domino Server
|
37
32
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -47,7 +42,7 @@ module Sisimai::Bite::Email
|
|
47
42
|
def scan(mhead, mbody)
|
48
43
|
return nil unless mhead
|
49
44
|
return nil unless mbody
|
50
|
-
return nil unless mhead['subject']
|
45
|
+
return nil unless mhead['subject'].start_with?('DELIVERY FAILURE:')
|
51
46
|
|
52
47
|
require 'sisimai/address'
|
53
48
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
@@ -59,12 +54,12 @@ module Sisimai::Bite::Email
|
|
59
54
|
subjecttxt = '' # (String) The value of Subject:
|
60
55
|
v = nil
|
61
56
|
|
62
|
-
hasdivided.
|
57
|
+
while e = hasdivided.shift do
|
63
58
|
next if e.empty?
|
64
59
|
|
65
60
|
if readcursor.zero?
|
66
61
|
# Beginning of the bounce message or delivery status part
|
67
|
-
if e
|
62
|
+
if e.start_with?(StartingOf[:message][0])
|
68
63
|
readcursor |= Indicators[:deliverystatus]
|
69
64
|
next
|
70
65
|
end
|
@@ -72,7 +67,7 @@ module Sisimai::Bite::Email
|
|
72
67
|
|
73
68
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
74
69
|
# Beginning of the original message part
|
75
|
-
if e
|
70
|
+
if e == StartingOf[:rfc822][0]
|
76
71
|
readcursor |= Indicators[:'message-rfc822']
|
77
72
|
next
|
78
73
|
end
|
@@ -86,7 +81,6 @@ module Sisimai::Bite::Email
|
|
86
81
|
next
|
87
82
|
end
|
88
83
|
rfc822list << e
|
89
|
-
|
90
84
|
else
|
91
85
|
# Before "message/rfc822"
|
92
86
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -105,7 +99,7 @@ module Sisimai::Bite::Email
|
|
105
99
|
#
|
106
100
|
v = dscontents[-1]
|
107
101
|
|
108
|
-
if e
|
102
|
+
if e.start_with?('was not delivered to:')
|
109
103
|
# was not delivered to:
|
110
104
|
if v['recipient']
|
111
105
|
# There are multiple recipient addresses in the message body.
|
@@ -120,13 +114,11 @@ module Sisimai::Bite::Email
|
|
120
114
|
# kijitora@example.net
|
121
115
|
v['recipient'] = Sisimai::Address.s3s4(cv[1])
|
122
116
|
|
123
|
-
elsif e
|
117
|
+
elsif e.start_with?('because:')
|
124
118
|
# because:
|
125
119
|
v['diagnosis'] = e
|
126
|
-
|
127
120
|
else
|
128
|
-
|
129
|
-
if v['diagnosis'] && v['diagnosis'] == 'because:'
|
121
|
+
if v['diagnosis'].to_s == 'because:'
|
130
122
|
# Error message, continued from the line "because:"
|
131
123
|
v['diagnosis'] = e
|
132
124
|
|
@@ -137,19 +129,18 @@ module Sisimai::Bite::Email
|
|
137
129
|
end
|
138
130
|
end
|
139
131
|
end
|
140
|
-
|
141
132
|
return nil if recipients.zero?
|
133
|
+
|
142
134
|
require 'sisimai/string'
|
143
135
|
require 'sisimai/smtp/status'
|
144
|
-
|
145
136
|
dscontents.map do |e|
|
146
137
|
e['agent'] = self.smtpagent
|
147
138
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
148
139
|
e['recipient'] = Sisimai::Address.s3s4(e['recipient'])
|
149
140
|
|
150
|
-
|
141
|
+
ReFailures.each_key do |r|
|
151
142
|
# Check each regular expression of Domino error messages
|
152
|
-
next unless e['diagnosis'] =~
|
143
|
+
next unless e['diagnosis'] =~ ReFailures[r]
|
153
144
|
e['reason'] = r.to_s
|
154
145
|
pseudostatus = Sisimai::SMTP::Status.code(r.to_s, false)
|
155
146
|
e['status'] = pseudostatus if pseudostatus.size > 0
|
@@ -158,10 +149,10 @@ module Sisimai::Bite::Email
|
|
158
149
|
e.each_key { |a| e[a] ||= '' }
|
159
150
|
end
|
160
151
|
|
161
|
-
unless rfc822list.find { |a| a
|
152
|
+
unless rfc822list.find { |a| a.start_with?('Subject:') }
|
162
153
|
# Set the value of subjecttxt as a Subject if there is no original
|
163
154
|
# message in the bounce mail.
|
164
|
-
rfc822list <<
|
155
|
+
rfc822list << ('Subject: ' << subjecttxt)
|
165
156
|
end
|
166
157
|
|
167
158
|
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
@@ -6,26 +6,18 @@ module Sisimai::Bite::Email
|
|
6
6
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/EinsUndEins.pm
|
7
7
|
require 'sisimai/bite/email'
|
8
8
|
|
9
|
-
Re0 = {
|
10
|
-
:from => %r/\A["]Mail Delivery System["]/,
|
11
|
-
:subject => %r/\AMail delivery failed: returning message to sender\z/,
|
12
|
-
}.freeze
|
13
|
-
Re1 = {
|
14
|
-
:begin => %r/\AThis message was created automatically by mail delivery software/,
|
15
|
-
:error => %r/\AFor the following reason:/,
|
16
|
-
:rfc822 => %r/\A--- The header of the original message is following/,
|
17
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
18
|
-
}.freeze
|
19
|
-
ReFailure = {
|
20
|
-
mesgtoobig: %r/Mail[ ]size[ ]limit[ ]exceeded/x,
|
21
|
-
}.freeze
|
22
9
|
Indicators = Sisimai::Bite::Email.INDICATORS
|
10
|
+
StartingOf = {
|
11
|
+
message: ['This message was created automatically by mail delivery software'],
|
12
|
+
error: ['For the following reason:'],
|
13
|
+
rfc822: ['--- The header of the original message is following'],
|
14
|
+
}.freeze
|
15
|
+
ReFailures = { mesgtoobig: %r/Mail size limit exceeded/ }.freeze
|
23
16
|
|
24
17
|
def description; return '1&1: http://www.1and1.de'; end
|
25
18
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
26
19
|
# X-UI-Out-Filterresults: unknown:0;
|
27
20
|
def headerlist; return []; end
|
28
|
-
def pattern; return Re0; end
|
29
21
|
|
30
22
|
# Parse bounce messages from 1&1
|
31
23
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -41,8 +33,8 @@ module Sisimai::Bite::Email
|
|
41
33
|
def scan(mhead, mbody)
|
42
34
|
return nil unless mhead
|
43
35
|
return nil unless mbody
|
44
|
-
return nil unless mhead['from']
|
45
|
-
return nil unless mhead['subject']
|
36
|
+
return nil unless mhead['from'].start_with?('"Mail Delivery System"')
|
37
|
+
return nil unless mhead['subject'] == 'Mail delivery failed: returning message to sender'
|
46
38
|
|
47
39
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
48
40
|
hasdivided = mbody.split("\n")
|
@@ -52,10 +44,10 @@ module Sisimai::Bite::Email
|
|
52
44
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
53
45
|
v = nil
|
54
46
|
|
55
|
-
hasdivided.
|
47
|
+
while e = hasdivided.shift do
|
56
48
|
if readcursor.zero?
|
57
49
|
# Beginning of the bounce message or delivery status part
|
58
|
-
if e
|
50
|
+
if e.start_with?(StartingOf[:message][0])
|
59
51
|
readcursor |= Indicators[:deliverystatus]
|
60
52
|
next
|
61
53
|
end
|
@@ -63,7 +55,7 @@ module Sisimai::Bite::Email
|
|
63
55
|
|
64
56
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
65
57
|
# Beginning of the original message part
|
66
|
-
if e
|
58
|
+
if e.start_with?(StartingOf[:rfc822][0])
|
67
59
|
readcursor |= Indicators[:'message-rfc822']
|
68
60
|
next
|
69
61
|
end
|
@@ -77,7 +69,6 @@ module Sisimai::Bite::Email
|
|
77
69
|
next
|
78
70
|
end
|
79
71
|
rfc822list << e
|
80
|
-
|
81
72
|
else
|
82
73
|
# Before "message/rfc822"
|
83
74
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -103,31 +94,26 @@ module Sisimai::Bite::Email
|
|
103
94
|
v['recipient'] = cv[1]
|
104
95
|
recipients += 1
|
105
96
|
|
106
|
-
elsif e
|
97
|
+
elsif e.start_with?(StartingOf[:error][0])
|
107
98
|
# For the following reason:
|
108
99
|
v['diagnosis'] = e
|
109
|
-
|
110
100
|
else
|
111
|
-
# Get error message
|
112
|
-
if v['diagnosis']
|
113
|
-
# Append error message strings
|
114
|
-
v['diagnosis'] += ' ' + e
|
115
|
-
end
|
101
|
+
# Get error message and append error message strings
|
102
|
+
v['diagnosis'] << ' ' << e if v['diagnosis']
|
116
103
|
end
|
117
104
|
end
|
118
105
|
end
|
119
106
|
return nil if recipients.zero?
|
120
|
-
require 'sisimai/string'
|
121
107
|
|
108
|
+
require 'sisimai/string'
|
122
109
|
dscontents.map do |e|
|
123
|
-
e['agent']
|
124
|
-
e['diagnosis']
|
125
|
-
e['diagnosis']
|
126
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
110
|
+
e['agent'] = self.smtpagent
|
111
|
+
e['diagnosis'] = e['diagnosis'].to_s.gsub(/\A#{StartingOf[:error][0]}/, '')
|
112
|
+
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
127
113
|
|
128
|
-
|
114
|
+
ReFailures.each_key do |r|
|
129
115
|
# Verify each regular expression of session errors
|
130
|
-
next unless e['diagnosis'] =~
|
116
|
+
next unless e['diagnosis'] =~ ReFailures[r]
|
131
117
|
e['reason'] = r.to_s
|
132
118
|
break
|
133
119
|
end
|
@@ -7,25 +7,13 @@ module Sisimai::Bite::Email
|
|
7
7
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Exchange2003.pm
|
8
8
|
require 'sisimai/bite/email'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:'
|
14
|
-
|
15
|
-
|Microsoft[ ]Exchange[ ]Server[ ]Internet[ ]Mail[ ]Connector
|
16
|
-
)
|
17
|
-
}x,
|
18
|
-
:'x-mimeole' => %r/\AProduced By Microsoft Exchange/,
|
19
|
-
# Received: by ***.**.** with Internet Mail Service (5.5.2657.72)
|
20
|
-
:'received' => %r/\Aby .+ with Internet Mail Service [(][\d.]+[)]/,
|
21
|
-
}.freeze
|
22
|
-
Re1 = {
|
23
|
-
:begin => %r/\AYour message/,
|
24
|
-
:error => %r/\Adid not reach the following recipient[(]s[)]:/,
|
25
|
-
:rfc822 => %r|\AContent-Type: message/rfc822|,
|
26
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
10
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
11
|
+
StartingOf = {
|
12
|
+
message: ['Your message'],
|
13
|
+
error: ['did not reach the following recipient(s):'],
|
14
|
+
rfc822: ['Content-Type: message/rfc822'],
|
27
15
|
}.freeze
|
28
|
-
|
16
|
+
ErrorCodes = {
|
29
17
|
onhold: [
|
30
18
|
'000B099C', # Host Unknown, Message exceeds size limit, ...
|
31
19
|
'000B09AA', # Unable to relay for, Message exceeds size limit,...
|
@@ -52,12 +40,10 @@ module Sisimai::Bite::Email
|
|
52
40
|
'000C0595', # Ambiguous Recipient
|
53
41
|
],
|
54
42
|
}.freeze
|
55
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
56
43
|
|
57
44
|
def description; return 'Microsoft Exchange Server 2003'; end
|
58
45
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
59
46
|
def headerlist; return ['X-MS-Embedded-Report', 'X-MimeOLE']; end
|
60
|
-
def pattern; return Re0; end
|
61
47
|
|
62
48
|
# Parse bounce messages from Microsoft Exchange Server 2003
|
63
49
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -74,29 +60,31 @@ module Sisimai::Bite::Email
|
|
74
60
|
return nil unless mhead
|
75
61
|
return nil unless mbody
|
76
62
|
match = 0
|
63
|
+
tryto = []
|
77
64
|
|
78
65
|
match += 1 if mhead['x-ms-embedded-report']
|
79
66
|
catch :EXCHANGE_OR_NOT do
|
80
|
-
|
67
|
+
while true
|
81
68
|
throw :EXCHANGE_OR_NOT if match > 0
|
82
69
|
|
83
70
|
if mhead['x-mailer']
|
84
71
|
# X-Mailer: Microsoft Exchange Server Internet Mail Connector Version 4.0.994.63
|
85
72
|
# X-Mailer: Internet Mail Service (5.5.2232.9)
|
86
|
-
|
73
|
+
tryto = ['Internet Mail Service (', 'Microsoft Exchange Server Internet Mail Connector']
|
74
|
+
match += 1 if mhead['x-mailer'].start_with?(tryto[0], tryto[1])
|
87
75
|
throw :EXCHANGE_OR_NOT if match > 0
|
88
76
|
end
|
89
77
|
|
90
78
|
if mhead['x-mimeole']
|
91
79
|
# X-MimeOLE: Produced By Microsoft Exchange V6.5
|
92
|
-
match += 1 if mhead['x-mimeole']
|
80
|
+
match += 1 if mhead['x-mimeole'].start_with?('Produced By Microsoft Exchange')
|
93
81
|
throw :EXCHANGE_OR_NOT if match > 0
|
94
82
|
end
|
95
83
|
|
96
84
|
throw :EXCHANGE_OR_NOT if mhead['received'].size.zero?
|
97
85
|
mhead['received'].each do |e|
|
98
86
|
# Received: by ***.**.** with Internet Mail Service (5.5.2657.72)
|
99
|
-
next unless e
|
87
|
+
next unless e.include?(' with Internet Mail Service (')
|
100
88
|
match += 1
|
101
89
|
throw :EXCHANGE_OR_NOT
|
102
90
|
end
|
@@ -120,10 +108,10 @@ module Sisimai::Bite::Email
|
|
120
108
|
}
|
121
109
|
v = nil
|
122
110
|
|
123
|
-
hasdivided.
|
111
|
+
while e = hasdivided.shift do
|
124
112
|
if readcursor.zero?
|
125
113
|
# Beginning of the bounce message or delivery status part
|
126
|
-
if e
|
114
|
+
if e.start_with?(StartingOf[:message][0])
|
127
115
|
readcursor |= Indicators[:deliverystatus]
|
128
116
|
next
|
129
117
|
end
|
@@ -131,7 +119,7 @@ module Sisimai::Bite::Email
|
|
131
119
|
|
132
120
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
133
121
|
# Beginning of the original message part
|
134
|
-
if e
|
122
|
+
if e.start_with?(StartingOf[:rfc822][0])
|
135
123
|
readcursor |= Indicators[:'message-rfc822']
|
136
124
|
next
|
137
125
|
end
|
@@ -145,7 +133,6 @@ module Sisimai::Bite::Email
|
|
145
133
|
next
|
146
134
|
end
|
147
135
|
rfc822list << e
|
148
|
-
|
149
136
|
else
|
150
137
|
# Before "message/rfc822"
|
151
138
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -182,24 +169,20 @@ module Sisimai::Bite::Email
|
|
182
169
|
elsif cv = e.match(/\A[ \t]+(MSEXCH:.+)\z/)
|
183
170
|
# MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
|
184
171
|
v['diagnosis'] ||= ''
|
185
|
-
v['diagnosis']
|
186
|
-
|
172
|
+
v['diagnosis'] << cv[1]
|
187
173
|
else
|
188
174
|
next if v['msexch']
|
189
|
-
if v['diagnosis']
|
175
|
+
if v['diagnosis'].to_s.start_with?('MSEXCH:')
|
190
176
|
# Continued from MEEXCH in the previous line
|
191
177
|
v['msexch'] = true
|
192
|
-
v['diagnosis']
|
193
|
-
v['diagnosis'] += ' ' + e
|
178
|
+
v['diagnosis'] << ' ' << e
|
194
179
|
statuspart = true
|
195
|
-
|
196
180
|
else
|
197
181
|
# Error message in the body part
|
198
182
|
v['alterrors'] ||= ''
|
199
|
-
v['alterrors']
|
183
|
+
v['alterrors'] << ' ' << e
|
200
184
|
end
|
201
185
|
end
|
202
|
-
|
203
186
|
else
|
204
187
|
# Your message
|
205
188
|
#
|
@@ -230,11 +213,10 @@ module Sisimai::Bite::Email
|
|
230
213
|
end
|
231
214
|
end
|
232
215
|
end
|
233
|
-
|
234
216
|
return nil if recipients.zero?
|
217
|
+
|
235
218
|
require 'sisimai/string'
|
236
219
|
require 'sisimai/smtp/status'
|
237
|
-
|
238
220
|
dscontents.map do |e|
|
239
221
|
if cv = e['diagnosis'].match(/\AMSEXCH:.+[ \t]*[(]([0-9A-F]{8})[)][ \t]*(.*)\z/)
|
240
222
|
# MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
|
@@ -242,9 +224,9 @@ module Sisimai::Bite::Email
|
|
242
224
|
errormessage = cv[2]
|
243
225
|
pseudostatus = ''
|
244
226
|
|
245
|
-
|
227
|
+
ErrorCodes.each_key do |r|
|
246
228
|
# Find captured code from the error code table
|
247
|
-
next unless
|
229
|
+
next unless ErrorCodes[r].index(capturedcode)
|
248
230
|
e['reason'] = r.to_s
|
249
231
|
pseudostatus = Sisimai::SMTP::Status.code(r.to_s)
|
250
232
|
e['status'] = pseudostatus if pseudostatus.size > 0
|
@@ -269,9 +251,9 @@ module Sisimai::Bite::Email
|
|
269
251
|
|
270
252
|
if rfc822list.empty?
|
271
253
|
# When original message does not included in the bounce message
|
272
|
-
rfc822list <<
|
273
|
-
rfc822list <<
|
274
|
-
rfc822list <<
|
254
|
+
rfc822list << ('From: ' << connheader['to'])
|
255
|
+
rfc822list << ('Date: ' << connheader['date'])
|
256
|
+
rfc822list << ('Subject: ' << connheader['subject'])
|
275
257
|
end
|
276
258
|
|
277
259
|
rfc822part = Sisimai::RFC5322.weedout(rfc822list)
|
@@ -7,16 +7,12 @@ module Sisimai::Bite::Email
|
|
7
7
|
# Imported from p5-Sisimail/lib/Sisimai/Bite/Email/Exchange2007.pm
|
8
8
|
require 'sisimai/bite/email'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
:
|
16
|
-
:error => %r/[ ]((?:RESOLVER|QUEUE)[.][A-Za-z]+(?:[.]\w+)?);/,
|
17
|
-
:rhost => %r/\AGenerating[ ]server:[ ]?(.*)/,
|
18
|
-
:rfc822 => %r/\AOriginal message headers:/,
|
19
|
-
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
10
|
+
Indicators = Sisimai::Bite::Email.INDICATORS
|
11
|
+
StartingOf = { rfc822: ['Original message headers:'] }.freeze
|
12
|
+
MarkingsOf = {
|
13
|
+
message: %r/ Microsoft Exchange Server 20\d{2}/,
|
14
|
+
error: %r/ ((?:RESOLVER|QUEUE)[.][A-Za-z]+(?:[.]\w+)?);/,
|
15
|
+
rhost: %r/\AGenerating server:[ ]?(.*)/,
|
20
16
|
}.freeze
|
21
17
|
NDRSubject = {
|
22
18
|
:'SMTPSEND.DNS.NonExistentDomain'=> 'hostunknown', # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
|
@@ -32,12 +28,10 @@ module Sisimai::Bite::Email
|
|
32
28
|
:'RESOLVER.RST.RecipSizeLimit' => 'mesgtoobig', # 550 5.2.3 RESOLVER.RST.RecipSizeLimit
|
33
29
|
:'QUEUE.Expired' => 'expired', # 550 4.4.7 QUEUE.Expired
|
34
30
|
}.freeze
|
35
|
-
Indicators = Sisimai::Bite::Email.INDICATORS
|
36
31
|
|
37
32
|
def description; return 'Microsoft Exchange Server 2007'; end
|
38
33
|
def smtpagent; return Sisimai::Bite.smtpagent(self); end
|
39
34
|
def headerlist; return ['Content-Language']; end
|
40
|
-
def pattern; return Re0; end
|
41
35
|
|
42
36
|
# Parse bounce messages from Microsoft Exchange Server 2007
|
43
37
|
# @param [Hash] mhead Message headers of a bounce email
|
@@ -54,9 +48,9 @@ module Sisimai::Bite::Email
|
|
54
48
|
return nil unless mhead
|
55
49
|
return nil unless mbody
|
56
50
|
|
57
|
-
return nil unless mhead['subject']
|
51
|
+
return nil unless mhead['subject'].start_with?('Undeliverable:')
|
58
52
|
return nil unless mhead['content-language']
|
59
|
-
return nil unless mhead['content-language'] =~
|
53
|
+
return nil unless mhead['content-language'] =~ /\A[a-z]{2}(?:[-][A-Z]{2})?\z/
|
60
54
|
|
61
55
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
62
56
|
hasdivided = mbody.split("\n")
|
@@ -70,10 +64,10 @@ module Sisimai::Bite::Email
|
|
70
64
|
}
|
71
65
|
v = nil
|
72
66
|
|
73
|
-
hasdivided.
|
67
|
+
while e = hasdivided.shift do
|
74
68
|
if readcursor.zero?
|
75
69
|
# Beginning of the bounce message or delivery status part
|
76
|
-
if e =~
|
70
|
+
if e =~ MarkingsOf[:message]
|
77
71
|
readcursor |= Indicators[:deliverystatus]
|
78
72
|
next
|
79
73
|
end
|
@@ -81,7 +75,7 @@ module Sisimai::Bite::Email
|
|
81
75
|
|
82
76
|
if (readcursor & Indicators[:'message-rfc822']).zero?
|
83
77
|
# Beginning of the original message part
|
84
|
-
if e
|
78
|
+
if e.start_with?(StartingOf[:rfc822][0])
|
85
79
|
readcursor |= Indicators[:'message-rfc822']
|
86
80
|
next
|
87
81
|
end
|
@@ -95,7 +89,6 @@ module Sisimai::Bite::Email
|
|
95
89
|
next
|
96
90
|
end
|
97
91
|
rfc822list << e
|
98
|
-
|
99
92
|
else
|
100
93
|
# Before "message/rfc822"
|
101
94
|
next if (readcursor & Indicators[:deliverystatus]).zero?
|
@@ -129,19 +122,18 @@ module Sisimai::Bite::Email
|
|
129
122
|
v['replycode'] = cv[1]
|
130
123
|
v['status'] = cv[2]
|
131
124
|
v['diagnosis'] = e
|
132
|
-
|
133
125
|
else
|
134
126
|
if v['diagnosis'].to_s.size > 0 && v['diagnosis'].end_with?('=')
|
135
127
|
# Continued line of error messages
|
136
|
-
v['diagnosis'] = v['diagnosis'].
|
137
|
-
v['diagnosis']
|
128
|
+
v['diagnosis'] = v['diagnosis'].chomp('=')
|
129
|
+
v['diagnosis'] << e
|
138
130
|
end
|
139
131
|
end
|
140
132
|
else
|
141
133
|
# Diagnostic information for administrators:
|
142
134
|
#
|
143
135
|
# Generating server: mta22.neko.example.org
|
144
|
-
if cv = e.match(
|
136
|
+
if cv = e.match(MarkingsOf[:rhost])
|
145
137
|
# Generating server: mta22.neko.example.org
|
146
138
|
next if connheader['rhost'].size > 0
|
147
139
|
connheader['rhost'] = cv[1]
|
@@ -154,7 +146,7 @@ module Sisimai::Bite::Email
|
|
154
146
|
|
155
147
|
require 'sisimai/string'
|
156
148
|
dscontents.map do |e|
|
157
|
-
if cv = e['diagnosis'].match(
|
149
|
+
if cv = e['diagnosis'].match(MarkingsOf[:error])
|
158
150
|
# #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
|
159
151
|
f = cv[1]
|
160
152
|
NDRSubject.each_key do |r|
|