sisimai 4.25.16-java → 5.0.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/rake-test.yml +55 -0
- data/.travis.yml +3 -3
- data/ANALYTICAL-PRECISION +2 -2
- data/Benchmarks.mk +3 -3
- data/CONTRIBUTING +1 -1
- data/ChangeLog.md +451 -393
- data/Developers.mk +5 -6
- data/Gemfile +1 -1
- data/Makefile +15 -15
- data/README-JA.md +323 -149
- data/README.md +319 -149
- data/Rakefile +9 -3
- data/Repository.mk +2 -3
- data/lib/sisimai/address.rb +118 -74
- data/lib/sisimai/arf.rb +84 -82
- data/lib/sisimai/datetime.rb +5 -52
- data/lib/sisimai/{data → fact}/json.rb +7 -9
- data/lib/sisimai/fact/yaml.rb +31 -0
- data/lib/sisimai/fact.rb +506 -0
- data/lib/sisimai/lhost/activehunter.rb +12 -14
- data/lib/sisimai/lhost/amavis.rb +11 -14
- data/lib/sisimai/lhost/amazonses.rb +37 -42
- data/lib/sisimai/lhost/amazonworkmail.rb +15 -19
- data/lib/sisimai/lhost/aol.rb +12 -15
- data/lib/sisimai/lhost/apachejames.rb +19 -21
- data/lib/sisimai/lhost/barracuda.rb +10 -12
- data/lib/sisimai/lhost/bigfoot.rb +21 -22
- data/lib/sisimai/lhost/biglobe.rb +15 -16
- data/lib/sisimai/lhost/courier.rb +20 -20
- data/lib/sisimai/lhost/domino.rb +23 -20
- data/lib/sisimai/lhost/einsundeins.rb +23 -18
- data/lib/sisimai/lhost/exchange2003.rb +30 -29
- data/lib/sisimai/lhost/exchange2007.rb +70 -58
- data/lib/sisimai/lhost/exim.rb +179 -174
- data/lib/sisimai/lhost/ezweb.rb +31 -56
- data/lib/sisimai/lhost/facebook.rb +21 -34
- data/lib/sisimai/lhost/fml.rb +43 -48
- data/lib/sisimai/lhost/gmail.rb +29 -29
- data/lib/sisimai/lhost/gmx.rb +18 -17
- data/lib/sisimai/lhost/googlegroups.rb +11 -11
- data/lib/sisimai/lhost/gsuite.rb +21 -28
- data/lib/sisimai/lhost/imailserver.rb +25 -39
- data/lib/sisimai/lhost/interscanmss.rb +28 -31
- data/lib/sisimai/lhost/kddi.rb +22 -28
- data/lib/sisimai/lhost/mailfoundry.rb +11 -12
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
- data/lib/sisimai/lhost/mailru.rb +37 -40
- data/lib/sisimai/lhost/mcafee.rb +21 -31
- data/lib/sisimai/lhost/messagelabs.rb +17 -21
- data/lib/sisimai/lhost/messagingserver.rb +40 -37
- data/lib/sisimai/lhost/mfilter.rb +16 -17
- data/lib/sisimai/lhost/mxlogic.rb +24 -33
- data/lib/sisimai/lhost/notes.rb +17 -17
- data/lib/sisimai/lhost/office365.rb +64 -28
- data/lib/sisimai/lhost/opensmtpd.rb +12 -13
- data/lib/sisimai/lhost/outlook.rb +12 -16
- data/lib/sisimai/lhost/postfix.rb +179 -130
- data/lib/sisimai/lhost/powermta.rb +12 -14
- data/lib/sisimai/lhost/qmail.rb +44 -47
- data/lib/sisimai/lhost/receivingses.rb +15 -21
- data/lib/sisimai/lhost/sendgrid.rb +34 -34
- data/lib/sisimai/lhost/sendmail.rb +65 -53
- data/lib/sisimai/lhost/surfcontrol.rb +19 -19
- data/lib/sisimai/lhost/v5sendmail.rb +45 -39
- data/lib/sisimai/lhost/verizon.rb +35 -39
- data/lib/sisimai/lhost/x1.rb +18 -17
- data/lib/sisimai/lhost/x2.rb +17 -14
- data/lib/sisimai/lhost/x3.rb +19 -19
- data/lib/sisimai/lhost/x4.rb +72 -57
- data/lib/sisimai/lhost/x5.rb +17 -19
- data/lib/sisimai/lhost/x6.rb +41 -17
- data/lib/sisimai/lhost/yahoo.rb +17 -16
- data/lib/sisimai/lhost/yandex.rb +16 -21
- data/lib/sisimai/lhost/zoho.rb +16 -15
- data/lib/sisimai/lhost.rb +8 -10
- data/lib/sisimai/mail/maildir.rb +1 -3
- data/lib/sisimai/mail/mbox.rb +3 -4
- data/lib/sisimai/mail/memory.rb +0 -1
- data/lib/sisimai/mail/stdin.rb +1 -3
- data/lib/sisimai/mail.rb +3 -7
- data/lib/sisimai/mda.rb +28 -42
- data/lib/sisimai/message.rb +444 -326
- data/lib/sisimai/order.rb +5 -5
- data/lib/sisimai/reason/authfailure.rb +65 -0
- data/lib/sisimai/reason/badreputation.rb +53 -0
- data/lib/sisimai/reason/blocked.rb +96 -160
- data/lib/sisimai/reason/contenterror.rb +8 -9
- data/lib/sisimai/reason/delivered.rb +4 -6
- data/lib/sisimai/reason/exceedlimit.rb +10 -12
- data/lib/sisimai/reason/expired.rb +7 -8
- data/lib/sisimai/reason/feedback.rb +2 -3
- data/lib/sisimai/reason/filtered.rb +17 -19
- data/lib/sisimai/reason/hasmoved.rb +9 -10
- data/lib/sisimai/reason/hostunknown.rb +15 -15
- data/lib/sisimai/reason/mailboxfull.rb +11 -12
- data/lib/sisimai/reason/mailererror.rb +18 -20
- data/lib/sisimai/reason/mesgtoobig.rb +9 -11
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +8 -11
- data/lib/sisimai/reason/notaccept.rb +13 -14
- data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +14 -12
- data/lib/sisimai/reason/rejected.rb +26 -24
- data/lib/sisimai/reason/requireptr.rb +69 -0
- data/lib/sisimai/reason/securityerror.rb +34 -36
- data/lib/sisimai/reason/spamdetected.rb +115 -147
- data/lib/sisimai/reason/speeding.rb +49 -0
- data/lib/sisimai/reason/suspend.rb +12 -11
- data/lib/sisimai/reason/syntaxerror.rb +11 -10
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +7 -8
- data/lib/sisimai/reason/toomanyconn.rb +9 -11
- data/lib/sisimai/reason/undefined.rb +2 -3
- data/lib/sisimai/reason/userunknown.rb +129 -146
- data/lib/sisimai/reason/vacation.rb +3 -4
- data/lib/sisimai/reason/virusdetected.rb +10 -11
- data/lib/sisimai/reason.rb +59 -64
- data/lib/sisimai/rfc1894.rb +55 -28
- data/lib/sisimai/rfc2045.rb +373 -0
- data/lib/sisimai/rfc3464.rb +250 -308
- data/lib/sisimai/rfc3834.rb +42 -45
- data/lib/sisimai/rfc5322.rb +177 -146
- data/lib/sisimai/rfc5965.rb +31 -0
- data/lib/sisimai/rhost/cox.rb +5 -6
- data/lib/sisimai/rhost/franceptt.rb +6 -8
- data/lib/sisimai/rhost/godaddy.rb +12 -12
- data/lib/sisimai/rhost/google.rb +530 -0
- data/lib/sisimai/rhost/iua.rb +9 -10
- data/lib/sisimai/rhost/kddi.rb +6 -8
- data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
- data/lib/sisimai/rhost/mimecast.rb +51 -42
- data/lib/sisimai/rhost/nttdocomo.rb +12 -12
- data/lib/sisimai/rhost/spectrum.rb +10 -12
- data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
- data/lib/sisimai/rhost.rb +23 -31
- data/lib/sisimai/smtp/command.rb +59 -0
- data/lib/sisimai/smtp/error.rb +4 -7
- data/lib/sisimai/smtp/reply.rb +161 -74
- data/lib/sisimai/smtp/status.rb +507 -393
- data/lib/sisimai/smtp/transcript.rb +124 -0
- data/lib/sisimai/smtp.rb +0 -1
- data/lib/sisimai/string.rb +74 -5
- data/lib/sisimai/time.rb +1 -2
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +46 -31
- data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
- data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
- data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
- data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
- data/set-of-emails/maildir/bsd/lhost-sendmail-60.eml +85 -0
- data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
- data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
- data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
- data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +48 -26
- data/.rspec +0 -2
- data/lib/sisimai/data/yaml.rb +0 -33
- data/lib/sisimai/data.rb +0 -411
- data/lib/sisimai/mime.rb +0 -456
- data/lib/sisimai/rhost/googleapps.rb +0 -261
- /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::Verizon parses a bounce email which created by
|
|
3
|
-
#
|
|
4
|
-
# Methods in the module are called from only Sisimai::Message.
|
|
2
|
+
# Sisimai::Lhost::Verizon parses a bounce email which created by Verizon Wireless. Methods in the
|
|
3
|
+
# module are called from only Sisimai::Message.
|
|
5
4
|
module Verizon
|
|
6
5
|
class << self
|
|
7
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/Verizon.pm
|
|
8
6
|
require 'sisimai/lhost'
|
|
9
7
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
10
8
|
|
|
@@ -13,25 +11,25 @@ module Sisimai::Lhost
|
|
|
13
11
|
# @param [String] mbody Message body of a bounce email
|
|
14
12
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
15
13
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
16
|
-
def
|
|
14
|
+
def inquire(mhead, mbody)
|
|
17
15
|
match = -1
|
|
18
16
|
while true
|
|
19
17
|
# Check the value of "From" header
|
|
20
18
|
# :'subject' => %r/Undeliverable Message/,
|
|
21
19
|
break unless mhead['received'].any? { |a| a.include?('.vtext.com (') }
|
|
22
20
|
match = 1 if mhead['from'] == 'post_master@vtext.com'
|
|
23
|
-
match = 0 if mhead['from']
|
|
21
|
+
match = 0 if Sisimai::String.aligned(mhead['from'], ['sysadmin@', '.vzwpix.com'])
|
|
24
22
|
break
|
|
25
23
|
end
|
|
26
24
|
return nil if match < 0
|
|
27
25
|
|
|
26
|
+
boundaries = []
|
|
28
27
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
29
|
-
|
|
28
|
+
emailparts = []
|
|
30
29
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
31
30
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
32
31
|
senderaddr = '' # (String) Sender address in the message body
|
|
33
32
|
subjecttxt = '' # (String) Subject of the original message
|
|
34
|
-
|
|
35
33
|
markingsof = {} # (Hash) Delimiter patterns
|
|
36
34
|
startingof = {} # (Hash) Delimiter strings
|
|
37
35
|
messagesof = {} # (Hash) Error message patterns
|
|
@@ -39,22 +37,21 @@ module Sisimai::Lhost
|
|
|
39
37
|
|
|
40
38
|
if match == 1
|
|
41
39
|
# vtext.com
|
|
42
|
-
markingsof = { message:
|
|
40
|
+
markingsof = { message: ['Error: '] }
|
|
43
41
|
messagesof = {
|
|
44
42
|
# The attempted recipient address does not exist.
|
|
45
43
|
'userunknown' => ['550 - Requested action not taken: no such user here'],
|
|
46
44
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
bodyslices = emailsteak[0].split("\n")
|
|
45
|
+
boundaries = [Sisimai::RFC2045.boundary(mhead['content-type'], 1)]
|
|
46
|
+
emailparts = Sisimai::RFC5322.part(mbody, boundaries)
|
|
47
|
+
bodyslices = emailparts[0].split("\n")
|
|
51
48
|
|
|
52
49
|
while e = bodyslices.shift do
|
|
53
|
-
# Read error messages and delivery status lines from the head of the email
|
|
54
|
-
#
|
|
50
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
51
|
+
# line of the beginning of the original message.
|
|
55
52
|
if readcursor == 0
|
|
56
53
|
# Beginning of the bounce message or delivery status part
|
|
57
|
-
readcursor |= Indicators[:deliverystatus] if e
|
|
54
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(markingsof[:message][0])
|
|
58
55
|
next
|
|
59
56
|
end
|
|
60
57
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
|
@@ -66,41 +63,40 @@ module Sisimai::Lhost
|
|
|
66
63
|
# MAIL FROM: *******@hg.example.com
|
|
67
64
|
# RCPT TO: *****@vtext.com
|
|
68
65
|
v = dscontents[-1]
|
|
69
|
-
if
|
|
66
|
+
if e.start_with?(' RCPT TO: ')
|
|
70
67
|
if v['recipient']
|
|
71
68
|
# There are multiple recipient addresses in the message body.
|
|
72
69
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
73
70
|
v = dscontents[-1]
|
|
74
71
|
end
|
|
75
72
|
|
|
76
|
-
v['recipient'] =
|
|
73
|
+
v['recipient'] = e[11, e.size]
|
|
77
74
|
recipients += 1
|
|
78
75
|
next
|
|
79
76
|
|
|
80
|
-
elsif
|
|
77
|
+
elsif e.start_with?(' MAIL FROM: ')
|
|
81
78
|
# MAIL FROM: *******@hg.example.com
|
|
82
|
-
senderaddr =
|
|
79
|
+
senderaddr = e[13, e.size] if senderaddr.empty?
|
|
83
80
|
|
|
84
|
-
elsif
|
|
81
|
+
elsif e.start_with?(' Subject: ')
|
|
85
82
|
# Subject:
|
|
86
|
-
subjecttxt =
|
|
83
|
+
subjecttxt = e[11, e.size] if subjecttxt.empty?
|
|
87
84
|
else
|
|
88
85
|
# 550 - Requested action not taken: no such user here
|
|
89
|
-
v['diagnosis'] = e if e
|
|
86
|
+
v['diagnosis'] = e if e.include?(' - ')
|
|
90
87
|
end
|
|
91
88
|
end
|
|
92
89
|
else
|
|
93
90
|
# vzwpix.com
|
|
94
91
|
startingof = { message: ['Message could not be delivered to mobile'] }
|
|
95
92
|
messagesof = { 'userunknown' => ['No valid recipients for this MM'] }
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
bodyslices = emailsteak[0].split("\n")
|
|
93
|
+
boundaries = [Sisimai::RFC2045.boundary(mhead['content-type'], 1)]
|
|
94
|
+
emailparts = Sisimai::RFC5322.part(mbody, boundaries)
|
|
95
|
+
bodyslices = emailparts[0].split("\n")
|
|
100
96
|
|
|
101
97
|
while e = bodyslices.shift do
|
|
102
|
-
# Read error messages and delivery status lines from the head of the email
|
|
103
|
-
#
|
|
98
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
99
|
+
# line of the beginning of the original message.
|
|
104
100
|
if readcursor == 0
|
|
105
101
|
# Beginning of the bounce message or delivery status part
|
|
106
102
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(startingof[:message][0])
|
|
@@ -115,35 +111,35 @@ module Sisimai::Lhost
|
|
|
115
111
|
# Subject: test for bounce
|
|
116
112
|
# Date: Wed, 20 Jun 2013 10:29:52 +0000
|
|
117
113
|
v = dscontents[-1]
|
|
118
|
-
if
|
|
114
|
+
if e.start_with?('To: ')
|
|
119
115
|
if v['recipient']
|
|
120
116
|
# There are multiple recipient addresses in the message body.
|
|
121
117
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
122
118
|
v = dscontents[-1]
|
|
123
119
|
end
|
|
124
|
-
v['recipient'] = Sisimai::Address.s3s4(
|
|
120
|
+
v['recipient'] = Sisimai::Address.s3s4(e[4, e.size])
|
|
125
121
|
recipients += 1
|
|
126
122
|
next
|
|
127
123
|
|
|
128
|
-
elsif
|
|
124
|
+
elsif e.start_with?('From: ')
|
|
129
125
|
# From: kijitora <kijitora@example.jp>
|
|
130
|
-
senderaddr = Sisimai::Address.s3s4(
|
|
126
|
+
senderaddr = Sisimai::Address.s3s4(e[4, e.size]) if senderaddr.empty?
|
|
131
127
|
|
|
132
|
-
elsif
|
|
128
|
+
elsif e.start_with?('Subject: ')
|
|
133
129
|
# Subject:
|
|
134
|
-
subjecttxt =
|
|
130
|
+
subjecttxt = e[9, e.size] if subjecttxt.empty?
|
|
135
131
|
else
|
|
136
132
|
# Message could not be delivered to mobile.
|
|
137
133
|
# Error: No valid recipients for this MM
|
|
138
|
-
v['diagnosis'] = e if e
|
|
134
|
+
v['diagnosis'] = Sisimai::String.sweep(e[7, e.size]) if e.start_with?('Error: ')
|
|
139
135
|
end
|
|
140
136
|
end
|
|
141
137
|
end
|
|
142
138
|
return nil unless recipients > 0
|
|
143
139
|
|
|
144
140
|
# Set the value of "MAIL FROM:" and "From:"
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
emailparts[1] << ('From: ' << senderaddr << "\n") if emailparts[1].include?("\nFrom: ") == false
|
|
142
|
+
emailparts[1] << ('Subject: ' << subjecttxt << "\n") if emailparts[1].include?("\nSubject: ") == false
|
|
147
143
|
|
|
148
144
|
dscontents.each do |e|
|
|
149
145
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
@@ -155,7 +151,7 @@ module Sisimai::Lhost
|
|
|
155
151
|
end
|
|
156
152
|
end
|
|
157
153
|
|
|
158
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
154
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
159
155
|
end
|
|
160
156
|
def description; return 'Verizon Wireless: https://www.verizonwireless.com'; end
|
|
161
157
|
end
|
data/lib/sisimai/lhost/x1.rb
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::X1 parses a bounce email which created by Unknown MTA #1.
|
|
3
|
-
#
|
|
2
|
+
# Sisimai::Lhost::X1 parses a bounce email which created by Unknown MTA #1. Methods in the module
|
|
3
|
+
# are called from only Sisimai::Message.
|
|
4
4
|
module X1
|
|
5
5
|
class << self
|
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/X1.pm
|
|
7
6
|
require 'sisimai/lhost'
|
|
8
7
|
|
|
9
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
10
|
-
|
|
11
|
-
MarkingsOf = { message:
|
|
9
|
+
Boundaries = ['Received: from '].freeze
|
|
10
|
+
MarkingsOf = { message: ['The original message was received at '] }.freeze
|
|
12
11
|
|
|
13
12
|
# Parse bounce messages from Unknown MTA #1
|
|
14
13
|
# @param [Hash] mhead Message headers of a bounce email
|
|
15
14
|
# @param [String] mbody Message body of a bounce email
|
|
16
15
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
17
16
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
18
|
-
def
|
|
17
|
+
def inquire(mhead, mbody)
|
|
19
18
|
return nil unless mhead['subject'].start_with?('Returned Mail: ')
|
|
20
19
|
return nil unless mhead['from'].start_with?('"Mail Deliver System" ')
|
|
21
20
|
|
|
22
21
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
23
|
-
|
|
24
|
-
bodyslices =
|
|
22
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
23
|
+
bodyslices = emailparts[0].split("\n")
|
|
25
24
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
26
25
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
27
26
|
datestring = '' # (String) Date string
|
|
28
27
|
v = nil
|
|
29
28
|
|
|
30
29
|
while e = bodyslices.shift do
|
|
31
|
-
# Read error messages and delivery status lines from the head of the email
|
|
32
|
-
#
|
|
30
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
31
|
+
# line of the beginning of the original message.
|
|
33
32
|
if readcursor == 0
|
|
34
33
|
# Beginning of the bounce message or delivery status part
|
|
35
|
-
readcursor |= Indicators[:deliverystatus] if e
|
|
34
|
+
readcursor |= Indicators[:deliverystatus] if e.start_with?(MarkingsOf[:message][0])
|
|
36
35
|
next
|
|
37
36
|
end
|
|
38
37
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
|
@@ -46,20 +45,22 @@ module Sisimai::Lhost
|
|
|
46
45
|
# kijitora@example.co.jp [User unknown]
|
|
47
46
|
v = dscontents[-1]
|
|
48
47
|
|
|
49
|
-
if
|
|
48
|
+
if Sisimai::String.aligned(e, ['@', ' [', ']'])
|
|
50
49
|
# kijitora@example.co.jp [User unknown]
|
|
51
50
|
if v['recipient']
|
|
52
51
|
# There are multiple recipient addresses in the message body.
|
|
53
52
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
54
53
|
v = dscontents[-1]
|
|
55
54
|
end
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
p1 = e.index(' ')
|
|
56
|
+
p2 = e.index(']')
|
|
57
|
+
v['recipient'] = e[0, p1]
|
|
58
|
+
v['diagnosis'] = e[p1 + 2, p2 - p1 - 2]
|
|
58
59
|
recipients += 1
|
|
59
60
|
|
|
60
|
-
elsif
|
|
61
|
+
elsif e.start_with?(MarkingsOf[:message][0])
|
|
61
62
|
# The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
|
|
62
|
-
datestring =
|
|
63
|
+
datestring = e[MarkingsOf[:message][0].size, e.size]
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
66
|
return nil unless recipients > 0
|
|
@@ -69,7 +70,7 @@ module Sisimai::Lhost
|
|
|
69
70
|
e['date'] = datestring || ''
|
|
70
71
|
end
|
|
71
72
|
|
|
72
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
73
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
73
74
|
end
|
|
74
75
|
def description; return 'Unknown MTA #1'; end
|
|
75
76
|
end
|
data/lib/sisimai/lhost/x2.rb
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::X2 parses a bounce email which created by Unknown MTA #2.
|
|
3
|
-
#
|
|
2
|
+
# Sisimai::Lhost::X2 parses a bounce email which created by Unknown MTA #2. Methods in the module
|
|
3
|
+
# are called from only Sisimai::Message.
|
|
4
4
|
module X2
|
|
5
5
|
class << self
|
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/X2.pm
|
|
7
6
|
require 'sisimai/lhost'
|
|
8
7
|
|
|
9
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
10
|
-
|
|
9
|
+
Boundaries = ['--- Original message follows.'].freeze
|
|
11
10
|
StartingOf = { message: ['Unable to deliver message to the following address'] }.freeze
|
|
12
11
|
|
|
13
12
|
# Parse bounce messages from Unknown MTA #2
|
|
@@ -15,20 +14,24 @@ module Sisimai::Lhost
|
|
|
15
14
|
# @param [String] mbody Message body of a bounce email
|
|
16
15
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
17
16
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
def inquire(mhead, mbody)
|
|
18
|
+
match = nil
|
|
19
|
+
match ||= 1 if mhead['from'].include?('MAILER-DAEMON@')
|
|
20
|
+
match ||= 1 if mhead['subject'].start_with?('Delivery failure')
|
|
21
|
+
match ||= 1 if mhead['subject'].start_with?('failure delivery')
|
|
22
|
+
match ||= 1 if mhead['subject'].start_with?('failed delivery')
|
|
23
|
+
return nil unless match
|
|
21
24
|
|
|
22
25
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
23
|
-
|
|
24
|
-
bodyslices =
|
|
26
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
27
|
+
bodyslices = emailparts[0].split("\n")
|
|
25
28
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
26
29
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
27
30
|
v = nil
|
|
28
31
|
|
|
29
32
|
while e = bodyslices.shift do
|
|
30
|
-
# Read error messages and delivery status lines from the head of the email
|
|
31
|
-
#
|
|
33
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
34
|
+
# line of the beginning of the original message.
|
|
32
35
|
if readcursor == 0
|
|
33
36
|
# Beginning of the bounce message or delivery status part
|
|
34
37
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
|
@@ -44,14 +47,14 @@ module Sisimai::Lhost
|
|
|
44
47
|
# This user doesn't have a example.com account (kijitora@example.com) [0]
|
|
45
48
|
v = dscontents[-1]
|
|
46
49
|
|
|
47
|
-
if
|
|
50
|
+
if e.start_with?('<') && Sisimai::String.aligned(e, ['<', '@', '>', ':'])
|
|
48
51
|
# <kijitora@example.com>:
|
|
49
52
|
if v['recipient']
|
|
50
53
|
# There are multiple recipient addresses in the message body.
|
|
51
54
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
52
55
|
v = dscontents[-1]
|
|
53
56
|
end
|
|
54
|
-
v['recipient'] =
|
|
57
|
+
v['recipient'] = e[1, e.size - 3]
|
|
55
58
|
recipients += 1
|
|
56
59
|
else
|
|
57
60
|
# This user doesn't have a example.com account (kijitora@example.com) [0]
|
|
@@ -62,7 +65,7 @@ module Sisimai::Lhost
|
|
|
62
65
|
return nil unless recipients > 0
|
|
63
66
|
|
|
64
67
|
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
|
65
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
68
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
66
69
|
end
|
|
67
70
|
def description; return 'Unknown MTA #2'; end
|
|
68
71
|
end
|
data/lib/sisimai/lhost/x3.rb
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::X3 parses a bounce email which created by Unknown MTA #3.
|
|
3
|
-
#
|
|
2
|
+
# Sisimai::Lhost::X3 parses a bounce email which created by Unknown MTA #3. Methods in the module
|
|
3
|
+
# are called from only Sisimai::Message.
|
|
4
4
|
module X3
|
|
5
5
|
class << self
|
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/X3.pm
|
|
7
6
|
require 'sisimai/lhost'
|
|
8
7
|
|
|
9
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
10
|
-
|
|
9
|
+
Boundaries = ['Content-Type: message/rfc822'].freeze
|
|
11
10
|
StartingOf = { message: [' This is an automatically generated Delivery Status Notification.'] }.freeze
|
|
12
11
|
|
|
13
12
|
# Parse bounce messages from Unknown MTA #3
|
|
@@ -15,20 +14,21 @@ module Sisimai::Lhost
|
|
|
15
14
|
# @param [String] mbody Message body of a bounce email
|
|
16
15
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
17
16
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
18
|
-
def
|
|
17
|
+
def inquire(mhead, mbody)
|
|
19
18
|
return nil unless mhead['subject'].start_with?('Delivery status notification')
|
|
20
19
|
return nil unless mhead['from'].start_with?('Mail Delivery System')
|
|
21
20
|
|
|
21
|
+
require 'sisimai/smtp/command'
|
|
22
22
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
23
|
-
|
|
24
|
-
bodyslices =
|
|
23
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
24
|
+
bodyslices = emailparts[0].split("\n")
|
|
25
25
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
26
26
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
27
27
|
v = nil
|
|
28
28
|
|
|
29
29
|
while e = bodyslices.shift do
|
|
30
|
-
# Read error messages and delivery status lines from the head of the email
|
|
31
|
-
#
|
|
30
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
31
|
+
# line of the beginning of the original message.
|
|
32
32
|
if readcursor == 0
|
|
33
33
|
# Beginning of the bounce message or delivery status part
|
|
34
34
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
|
@@ -54,29 +54,29 @@ module Sisimai::Lhost
|
|
|
54
54
|
# ============================================================================
|
|
55
55
|
v = dscontents[-1]
|
|
56
56
|
|
|
57
|
-
if
|
|
57
|
+
if e.include?(' * ') && e.include?('@')
|
|
58
58
|
# * kijitora@example.com
|
|
59
59
|
if v['recipient']
|
|
60
60
|
# There are multiple recipient addresses in the message body.
|
|
61
61
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
62
62
|
v = dscontents[-1]
|
|
63
63
|
end
|
|
64
|
-
v['recipient'] =
|
|
64
|
+
v['recipient'] = e[e.index(' * ') + 3, e.size]
|
|
65
65
|
recipients += 1
|
|
66
66
|
else
|
|
67
67
|
# Detect error message
|
|
68
|
-
if
|
|
68
|
+
if e.start_with?('SMTP:')
|
|
69
69
|
# SMTP:RCPT host 192.0.2.8: 553 5.3.0 <kijitora@example.com>... No such user here
|
|
70
|
-
v['command'] =
|
|
71
|
-
v['diagnosis'] =
|
|
70
|
+
v['command'] = Sisimai::SMTP::Command.find(e)
|
|
71
|
+
v['diagnosis'] = e
|
|
72
72
|
|
|
73
|
-
elsif
|
|
73
|
+
elsif e.start_with?('Routing: ')
|
|
74
74
|
# Routing: Could not find a gateway for kijitora@example.co.jp
|
|
75
|
-
v['diagnosis'] =
|
|
75
|
+
v['diagnosis'] = e[9, e.size]
|
|
76
76
|
|
|
77
|
-
elsif
|
|
77
|
+
elsif e.start_with?('Diagnostic-Code: smtp; ')
|
|
78
78
|
# Diagnostic-Code: smtp; 552 5.2.2 Over quota
|
|
79
|
-
v['diagnosis'] =
|
|
79
|
+
v['diagnosis'] = e[e.index(';') + 2, e.size]
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
82
|
end
|
|
@@ -87,7 +87,7 @@ module Sisimai::Lhost
|
|
|
87
87
|
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
90
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
91
91
|
end
|
|
92
92
|
def description; return 'Unknown MTA #3'; end
|
|
93
93
|
end
|