sisimai 5.7.1-java → 5.8.0-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 +4 -4
- data/.github/workflows/codecovio.yml +1 -1
- data/.github/workflows/rake-test.yml +2 -2
- data/ChangeLog.md +28 -0
- data/Developers.mk +4 -0
- data/Makefile +1 -0
- data/README-JA.md +32 -16
- data/README.md +31 -16
- data/lib/sisimai/arf.rb +1 -1
- data/lib/sisimai/eb.rb +2 -0
- data/lib/sisimai/lhost/activehunter.rb +2 -2
- data/lib/sisimai/lhost/amazonses.rb +4 -0
- data/lib/sisimai/lhost/apachejames.rb +2 -2
- data/lib/sisimai/lhost/biglobe.rb +2 -2
- data/lib/sisimai/lhost/courier.rb +2 -2
- data/lib/sisimai/lhost/deutschetelekom.rb +2 -2
- data/lib/sisimai/lhost/domino.rb +3 -4
- data/lib/sisimai/lhost/dragonfly.rb +2 -2
- data/lib/sisimai/lhost/einsundeins.rb +2 -2
- data/lib/sisimai/lhost/exchange2003.rb +2 -2
- data/lib/sisimai/lhost/exchange2007.rb +2 -2
- data/lib/sisimai/lhost/exim.rb +2 -2
- data/lib/sisimai/lhost/ezweb.rb +2 -2
- data/lib/sisimai/lhost/fml.rb +2 -2
- data/lib/sisimai/lhost/gmail.rb +2 -2
- data/lib/sisimai/lhost/gmx.rb +2 -2
- data/lib/sisimai/lhost/googlegroups.rb +1 -1
- data/lib/sisimai/lhost/googleworkspace.rb +2 -2
- data/lib/sisimai/lhost/imailserver.rb +2 -2
- data/lib/sisimai/lhost/kddi.rb +2 -2
- data/lib/sisimai/lhost/mailfoundry.rb +2 -2
- data/lib/sisimai/lhost/mailmarshal.rb +2 -2
- data/lib/sisimai/lhost/messagingserver.rb +2 -2
- data/lib/sisimai/lhost/mfilter.rb +2 -2
- data/lib/sisimai/lhost/mimecast.rb +2 -2
- data/lib/sisimai/lhost/notes.rb +2 -2
- data/lib/sisimai/lhost/opensmtpd.rb +2 -2
- data/lib/sisimai/lhost/postfix.rb +3 -3
- data/lib/sisimai/lhost/qmail.rb +2 -2
- data/lib/sisimai/lhost/sendmail.rb +4 -4
- data/lib/sisimai/lhost/trendmicro.rb +2 -2
- data/lib/sisimai/lhost/v5sendmail.rb +2 -4
- data/lib/sisimai/lhost/verizon.rb +4 -4
- data/lib/sisimai/lhost/x1.rb +2 -2
- data/lib/sisimai/lhost/x2.rb +2 -2
- data/lib/sisimai/lhost/x3.rb +2 -2
- data/lib/sisimai/lhost/x6.rb +2 -2
- data/lib/sisimai/lhost/zoho.rb +2 -2
- data/lib/sisimai/mail/maildir.rb +4 -2
- data/lib/sisimai/mail/stdin.rb +3 -3
- data/lib/sisimai/message.rb +9 -8
- data/lib/sisimai/reason/authfailure.rb +1 -0
- data/lib/sisimai/reason/blocked.rb +1 -0
- data/lib/sisimai/reason/ratelimited.rb +3 -2
- data/lib/sisimai/reason/requireptr.rb +1 -0
- data/lib/sisimai/reason/userunknown.rb +1 -0
- data/lib/sisimai/rfc3464.rb +5 -6
- data/lib/sisimai/rfc5322.rb +0 -1
- data/lib/sisimai/rhost/google.rb +11 -9
- data/lib/sisimai/smtp/status.rb +1 -1
- data/lib/sisimai/string.rb +4 -3
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +28 -4
- data/set-of-emails/mailbox/mbox-2 +141 -0
- metadata +3 -2
|
@@ -26,9 +26,9 @@ module Sisimai::Lhost
|
|
|
26
26
|
proceedsto = true if StartingOf[:command].any? { |a| mbody.include?(a) }
|
|
27
27
|
return nil if proceedsto == false
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
29
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
31
30
|
bodyslices = emailparts[0].split("\n")
|
|
31
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
32
32
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
33
33
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
34
34
|
markingset = {'diagnosis' => false, 'command' => false}
|
|
@@ -28,9 +28,9 @@ module Sisimai::Lhost
|
|
|
28
28
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
|
29
29
|
permessage = {} # (Hash) Store values of each Per-Message field
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
31
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
33
32
|
bodyslices = emailparts[0].split("\n")
|
|
33
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
34
34
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
35
35
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
36
36
|
|
data/lib/sisimai/lhost/notes.rb
CHANGED
|
@@ -24,9 +24,9 @@ module Sisimai::Lhost
|
|
|
24
24
|
def inquire(mhead, mbody)
|
|
25
25
|
return nil if mhead['subject'].start_with?('Undeliverable message') == false
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
27
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
29
28
|
bodyslices = emailparts[0].split("\n")
|
|
29
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
30
30
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
31
31
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
32
32
|
characters = '' # (String) Character set name of the bounce mail
|
|
@@ -46,9 +46,9 @@ module Sisimai::Lhost
|
|
|
46
46
|
return nil if mhead['from'].start_with?('Mailer Daemon <') == false
|
|
47
47
|
return nil if mhead['received'].none? { |a| a.include?(' (OpenSMTPD) with ') }
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
49
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
51
50
|
bodyslices = emailparts[0].split("\n")
|
|
51
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
52
52
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
53
53
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
54
54
|
|
|
@@ -42,11 +42,11 @@ module Sisimai::Lhost
|
|
|
42
42
|
end
|
|
43
43
|
return nil if match == 0 || mhead['x-aol-ip']
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
47
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
45
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
48
46
|
bodyslices = emailparts[0].split("\n")
|
|
47
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
49
48
|
readslices = ['']
|
|
49
|
+
permessage = {} # (Hash) Store values of each Per-Message field
|
|
50
50
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
51
51
|
nomessages = false # (Boolean) Delivery report unavailable
|
|
52
52
|
commandset = [] # (Array) ``in reply to * command'' list
|
data/lib/sisimai/lhost/qmail.rb
CHANGED
|
@@ -93,9 +93,9 @@ module Sisimai::Lhost
|
|
|
93
93
|
return nil if proceedsto == false
|
|
94
94
|
|
|
95
95
|
require "sisimai/smtp/command"
|
|
96
|
-
|
|
97
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
96
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
98
97
|
bodyslices = emailparts[0].split("\n")
|
|
98
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
99
99
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
100
100
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
101
101
|
|
|
@@ -37,12 +37,12 @@ module Sisimai::Lhost
|
|
|
37
37
|
match ||= true if mhead['subject'].start_with?('Warning: ')
|
|
38
38
|
return nil if match == false
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
permessage = {} # (Hash) Store values of each Per-Message field
|
|
42
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
43
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
40
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
44
41
|
bodyslices = emailparts[0].split("\n")
|
|
42
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
43
|
+
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
|
45
44
|
readslices = ['']
|
|
45
|
+
permessage = {} # (Hash) Store values of each Per-Message field
|
|
46
46
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
47
47
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
48
48
|
thecommand = '' # (String) SMTP Command name begin with the string '>>>'
|
|
@@ -27,9 +27,9 @@ module Sisimai::Lhost
|
|
|
27
27
|
return nil if match == 0
|
|
28
28
|
|
|
29
29
|
require 'sisimai/smtp/command'
|
|
30
|
-
|
|
31
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
30
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
32
31
|
bodyslices = emailparts[0].split("\n")
|
|
32
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
33
33
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
34
34
|
|
|
35
35
|
while e = bodyslices.shift do
|
|
@@ -38,14 +38,12 @@ module Sisimai::Lhost
|
|
|
38
38
|
# :from => %r/\AMail Delivery Subsystem/,
|
|
39
39
|
return nil if mhead['subject'].start_with?('Returned mail: ') == false
|
|
40
40
|
|
|
41
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
42
|
-
return nil if emailparts[1].size == 0
|
|
43
|
-
|
|
44
41
|
require 'sisimai/eb'
|
|
45
42
|
require 'sisimai/rfc1123'
|
|
46
43
|
require 'sisimai/smtp/command'
|
|
47
|
-
|
|
44
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[1].empty?
|
|
48
45
|
bodyslices = emailparts[0].split("\n")
|
|
46
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
49
47
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
50
48
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
51
49
|
anotherone = {} # (Hash) Another error information
|
|
@@ -41,7 +41,7 @@ module Sisimai::Lhost
|
|
|
41
41
|
Sisimai::Eb::ReUSER => ['550 - Requested action not taken: no such user here'],
|
|
42
42
|
}
|
|
43
43
|
boundaries = [Sisimai::RFC2045.boundary(mhead['content-type'], 1)]
|
|
44
|
-
emailparts = Sisimai::RFC5322.part(mbody, boundaries)
|
|
44
|
+
emailparts = Sisimai::RFC5322.part(mbody, boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
45
45
|
bodyslices = emailparts[0].split("\n")
|
|
46
46
|
|
|
47
47
|
while e = bodyslices.shift do
|
|
@@ -85,11 +85,11 @@ module Sisimai::Lhost
|
|
|
85
85
|
end
|
|
86
86
|
else
|
|
87
87
|
# vzwpix.com
|
|
88
|
-
startingof = {message: ['Message could not be delivered to mobile']}
|
|
89
|
-
messagesof = {Sisimai::Eb::ReUSER => ['No valid recipients for this MM']}
|
|
90
88
|
boundaries = [Sisimai::RFC2045.boundary(mhead['content-type'], 1)]
|
|
91
|
-
emailparts = Sisimai::RFC5322.part(mbody, boundaries)
|
|
89
|
+
emailparts = Sisimai::RFC5322.part(mbody, boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
92
90
|
bodyslices = emailparts[0].split("\n")
|
|
91
|
+
startingof = {message: ['Message could not be delivered to mobile']}
|
|
92
|
+
messagesof = {Sisimai::Eb::ReUSER => ['No valid recipients for this MM']}
|
|
93
93
|
|
|
94
94
|
while e = bodyslices.shift do
|
|
95
95
|
# Read error messages and delivery status lines from the head of the email to the previous
|
data/lib/sisimai/lhost/x1.rb
CHANGED
|
@@ -21,9 +21,9 @@ module Sisimai::Lhost
|
|
|
21
21
|
proceedsto = true if Sisimai::String.aligned(mhead['from'], ['"Mail Deliver', 'System" '])
|
|
22
22
|
return nil if proceedsto == false
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
24
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
26
25
|
bodyslices = emailparts[0].split("\n")
|
|
26
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
27
27
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
28
28
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
29
29
|
datestring = '' # (String) Date string
|
data/lib/sisimai/lhost/x2.rb
CHANGED
|
@@ -26,9 +26,9 @@ module Sisimai::Lhost
|
|
|
26
26
|
match ||= true if mhead['subject'].start_with?('failed delivery')
|
|
27
27
|
return nil if match == false
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
29
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
31
30
|
bodyslices = emailparts[0].split("\n")
|
|
31
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
32
32
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
33
33
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
34
34
|
|
data/lib/sisimai/lhost/x3.rb
CHANGED
|
@@ -19,9 +19,9 @@ module Sisimai::Lhost
|
|
|
19
19
|
return nil if mhead['from'].start_with?('Mail Delivery System') == false
|
|
20
20
|
|
|
21
21
|
require 'sisimai/smtp/command'
|
|
22
|
-
|
|
23
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
22
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
24
23
|
bodyslices = emailparts[0].split("\n")
|
|
24
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
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
|
data/lib/sisimai/lhost/x6.rb
CHANGED
|
@@ -18,9 +18,9 @@ module Sisimai::Lhost
|
|
|
18
18
|
def inquire(mhead, mbody)
|
|
19
19
|
return nil if mhead['subject'].start_with?('There was an error sending your mail') == false
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
21
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
23
22
|
bodyslices = emailparts[0].split("\n")
|
|
23
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
24
24
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
25
25
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
26
26
|
|
data/lib/sisimai/lhost/zoho.rb
CHANGED
|
@@ -20,9 +20,9 @@ module Sisimai::Lhost
|
|
|
20
20
|
# X-Mailer: Zoho Mail
|
|
21
21
|
return nil if mhead['x-zohomail'].nil?
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
23
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil? || emailparts[0].empty?
|
|
25
24
|
bodyslices = emailparts[0].split("\n")
|
|
25
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
26
26
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
27
27
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
28
28
|
qprintable = false
|
data/lib/sisimai/mail/maildir.rb
CHANGED
|
@@ -34,6 +34,7 @@ module Sisimai
|
|
|
34
34
|
seekhandle = self.handle
|
|
35
35
|
readbuffer = ''
|
|
36
36
|
|
|
37
|
+
require 'sisimai/eb'
|
|
37
38
|
begin
|
|
38
39
|
while r = seekhandle.read do
|
|
39
40
|
# Read each file in the directory
|
|
@@ -44,9 +45,10 @@ module Sisimai
|
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
emailindir = (self.dir + '/' + r).squeeze('/')
|
|
48
|
+
emailbytes = File.size(emailindir)
|
|
47
49
|
if File.ftype(emailindir) != 'file' ||
|
|
48
|
-
File.
|
|
49
|
-
|
|
50
|
+
File.readable?(emailindir) == false ||
|
|
51
|
+
emailbytes < 1 || emailbytes > Sisimai::Eb::XeBYTE
|
|
50
52
|
# The file is not a file, is empty, is not readable
|
|
51
53
|
self.offset += 1
|
|
52
54
|
next
|
data/lib/sisimai/mail/stdin.rb
CHANGED
|
@@ -6,8 +6,8 @@ module Sisimai
|
|
|
6
6
|
# :size [Integer] Data size which has been read
|
|
7
7
|
# :offset [Integer] The number of emails which have neen read
|
|
8
8
|
# :handle [IO::File] File handle
|
|
9
|
-
attr_reader :path, :name
|
|
10
|
-
attr_accessor :offset, :handle
|
|
9
|
+
attr_reader :path, :name
|
|
10
|
+
attr_accessor :offset, :handle, :size
|
|
11
11
|
|
|
12
12
|
# Constructor of Sisimai::Mail::STDIN
|
|
13
13
|
# @param [IO::STDIN] stdin Standard-In
|
|
@@ -16,7 +16,7 @@ module Sisimai
|
|
|
16
16
|
raise 'is not an IO object' if stdin.is_a?(IO) == false
|
|
17
17
|
|
|
18
18
|
@path = '<STDIN>'
|
|
19
|
-
@size =
|
|
19
|
+
@size = 0
|
|
20
20
|
@offset = 0
|
|
21
21
|
@handle = stdin
|
|
22
22
|
end
|
data/lib/sisimai/message.rb
CHANGED
|
@@ -86,7 +86,8 @@ module Sisimai
|
|
|
86
86
|
# There is a bounce message inside of mutipart/*, try to sift the first message/rfc822
|
|
87
87
|
# part as a entire message body again.
|
|
88
88
|
parseagain += 1
|
|
89
|
-
email = Sisimai::RFC5322.part(aftersplit[2], Boundaries, true).
|
|
89
|
+
email = Sisimai::RFC5322.part(aftersplit[2], Boundaries, true); break if email.nil?
|
|
90
|
+
email = email.pop.sub(/\A\s+/, '')
|
|
90
91
|
break if email.size < 128
|
|
91
92
|
end
|
|
92
93
|
return nil if beforefact.nil? || beforefact.empty?
|
|
@@ -202,7 +203,7 @@ module Sisimai
|
|
|
202
203
|
def tidy(argv0 = '')
|
|
203
204
|
return '' if argv0.empty?
|
|
204
205
|
|
|
205
|
-
email =
|
|
206
|
+
email = ::String.new(capacity: argv0.bytesize, encoding: Encoding::UTF_8)
|
|
206
207
|
lines = argv0.split("\n")
|
|
207
208
|
index = -1
|
|
208
209
|
lines.each do |e|
|
|
@@ -215,7 +216,7 @@ module Sisimai
|
|
|
215
216
|
index += 1
|
|
216
217
|
if fn == ''
|
|
217
218
|
# There is neither ":" character nor the field listed in $FieldTable
|
|
218
|
-
email
|
|
219
|
+
email << e << "\n"
|
|
219
220
|
next
|
|
220
221
|
end
|
|
221
222
|
|
|
@@ -294,12 +295,12 @@ module Sisimai
|
|
|
294
295
|
|
|
295
296
|
# 4. Remove redundant space characters
|
|
296
297
|
bf = bf.squeeze(' ').strip
|
|
297
|
-
email
|
|
298
|
+
email << sprintf("%s: %s\n", fn, bf)
|
|
298
299
|
end
|
|
299
300
|
|
|
300
301
|
# 5. Convert the lower-cased SMTP command to the upper-cased.
|
|
301
|
-
email
|
|
302
|
-
email
|
|
302
|
+
email.gsub!("after end of data:", "after end of DATA:")
|
|
303
|
+
email << "\n" if email.end_with?("\n\n") == false
|
|
303
304
|
return email
|
|
304
305
|
end
|
|
305
306
|
|
|
@@ -314,7 +315,7 @@ module Sisimai
|
|
|
314
315
|
# @param options argvs [Array] tryonfirst MTA module list to load on first
|
|
315
316
|
# @return [Hash] Decoded and structured bounce mails
|
|
316
317
|
def sift(argvs)
|
|
317
|
-
return nil if argvs['mail'].nil? || argvs['body'].nil?
|
|
318
|
+
return nil if argvs['mail'].nil? || argvs['body'].nil? || argvs['body'].empty?
|
|
318
319
|
|
|
319
320
|
mailheader = argvs['mail']['header']
|
|
320
321
|
bodystring = argvs['body']
|
|
@@ -356,6 +357,7 @@ module Sisimai
|
|
|
356
357
|
bodystring = p if p.empty? == false
|
|
357
358
|
end
|
|
358
359
|
bodystring = bodystring.scrub('?').delete("\r").gsub("\t", " ")
|
|
360
|
+
return nil if bodystring.empty?
|
|
359
361
|
|
|
360
362
|
haveloaded = {}
|
|
361
363
|
havesifted = nil
|
|
@@ -428,4 +430,3 @@ module Sisimai
|
|
|
428
430
|
end
|
|
429
431
|
end
|
|
430
432
|
end
|
|
431
|
-
|
|
@@ -23,6 +23,7 @@ module Sisimai
|
|
|
23
23
|
"error: no valid recipients from ",
|
|
24
24
|
"esmtp not accepting connections", # icloud.com
|
|
25
25
|
"extreme bad ip profile",
|
|
26
|
+
"found on one or more dnsbls", # comcast.net
|
|
26
27
|
"helo command rejected:",
|
|
27
28
|
"host network not allowed",
|
|
28
29
|
"invalid ip for sending mail of domain",
|
|
@@ -18,8 +18,6 @@ module Sisimai
|
|
|
18
18
|
"temporarily deferred due to unexpected volume or user complaints",
|
|
19
19
|
"throttling failure: ",
|
|
20
20
|
"too many errors from your ip", # Free.fr
|
|
21
|
-
"too many recipients", # ntt docomo
|
|
22
|
-
"too many smtp sessions for this host", # Sendmail(daemon.c)
|
|
23
21
|
"trop de connexions, ",
|
|
24
22
|
"we have already made numerous attempts to deliver this message",
|
|
25
23
|
].freeze
|
|
@@ -27,6 +25,9 @@ module Sisimai
|
|
|
27
25
|
["exceeded ", "allowable number of posts without solving a captcha"],
|
|
28
26
|
["connection ", "limit"],
|
|
29
27
|
["temporarily", "rate limited"],
|
|
28
|
+
["throttled ", "postmaster.comcast.net"],
|
|
29
|
+
["too many ", "session"], # Sendmail(daemon.c), comcast.net
|
|
30
|
+
["too many ", "recipients"], # nttdocomo, comcast.net
|
|
30
31
|
["too many con", "s"],
|
|
31
32
|
].freeze
|
|
32
33
|
|
|
@@ -13,6 +13,7 @@ module Sisimai
|
|
|
13
13
|
"corresponding forward dns entry does not point to the sending ip", # Google
|
|
14
14
|
"ip name lookup failed",
|
|
15
15
|
"no matches to nameserver query",
|
|
16
|
+
"ptr lookup failure",
|
|
16
17
|
"sender ip reverse lookup rejected",
|
|
17
18
|
"unresolvable relay host name",
|
|
18
19
|
].freeze
|
|
@@ -67,6 +67,7 @@ module Sisimai
|
|
|
67
67
|
"recipient is not accepted",
|
|
68
68
|
"recipient is not in my validrcptto list",
|
|
69
69
|
"recipient is not local",
|
|
70
|
+
"recipient mailbox unallocated", # comcast.net
|
|
70
71
|
"recipient not ok",
|
|
71
72
|
"recipient refuses to accept your mail",
|
|
72
73
|
"recipient unknown",
|
data/lib/sisimai/rfc3464.rb
CHANGED
|
@@ -35,11 +35,10 @@ module Sisimai
|
|
|
35
35
|
p0 = mbody.index("\n\nReturn-Path:")
|
|
36
36
|
mbody = sprintf("%s%s%s", mbody[0, p0], Boundaries[0], mbody[p0 + 1, mbody.size]) if p0
|
|
37
37
|
end
|
|
38
|
-
|
|
39
|
-
permessage = {}
|
|
38
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries); return nil if emailparts.nil?
|
|
40
39
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
41
40
|
alternates = Sisimai::Lhost.DELIVERYSTATUS
|
|
42
|
-
|
|
41
|
+
permessage = {}
|
|
43
42
|
readslices = [""]
|
|
44
43
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
45
44
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
@@ -62,12 +61,13 @@ module Sisimai
|
|
|
62
61
|
end
|
|
63
62
|
break if p0.nil?
|
|
64
63
|
|
|
65
|
-
cx = mbody[p1, mbody.size]
|
|
66
|
-
p2 = cx.index("\n\n")
|
|
64
|
+
cx = mbody[p1, mbody.size]; return nil if cx.nil?
|
|
65
|
+
p2 = cx.index("\n\n"); return nil if p2.nil?
|
|
67
66
|
cv = cx[p2 + 2, mbody.size]
|
|
68
67
|
emailparts = Sisimai::RFC5322.part(cv, [ct], 0)
|
|
69
68
|
break
|
|
70
69
|
end
|
|
70
|
+
return nil if emailparts.nil?
|
|
71
71
|
|
|
72
72
|
if emailparts[0].index(StartingOf[:message][0]) == nil
|
|
73
73
|
# There is no "Content-Type: message/delivery-status" line in the message body
|
|
@@ -272,4 +272,3 @@ module Sisimai
|
|
|
272
272
|
end
|
|
273
273
|
end
|
|
274
274
|
end
|
|
275
|
-
|
data/lib/sisimai/rfc5322.rb
CHANGED
data/lib/sisimai/rhost/google.rb
CHANGED
|
@@ -230,8 +230,9 @@ module Sisimai
|
|
|
230
230
|
['550', '5.7.1', 'email quota exceeded'],
|
|
231
231
|
],
|
|
232
232
|
Sisimai::Eb::ReINET => [
|
|
233
|
-
# - 554 5.4.6 Message exceeded 50 hops, this may
|
|
234
|
-
#
|
|
233
|
+
# - 554 5.4.6 Message exceeded 50 hops, this may show a mail loop. For details,
|
|
234
|
+
# go to SMTP relay service error messages.
|
|
235
|
+
# - https://support.google.com/mail/?p=MailLoop
|
|
235
236
|
['554', '5.4.6', 'message exceeded 50 hops'],
|
|
236
237
|
['554', '5.6.0', 'message exceeded 50 hops'],
|
|
237
238
|
],
|
|
@@ -389,9 +390,10 @@ module Sisimai
|
|
|
389
390
|
['550', '5.7.25', 'does not match the ip address of the hostname'],
|
|
390
391
|
],
|
|
391
392
|
Sisimai::Eb::ReSAFE => [
|
|
392
|
-
# - 454 4.7.0 Too many
|
|
393
|
-
# to
|
|
394
|
-
|
|
393
|
+
# - 454 4.7.0 Too many sign-in attempts, try again later. For details,
|
|
394
|
+
# go to SMTP relay service error messages.
|
|
395
|
+
# - https://support.google.com/mail/answer/7126229
|
|
396
|
+
['454', '4.7.0', 'too many sign-in attempts'],
|
|
395
397
|
|
|
396
398
|
# - 503 5.7.0 No identity changes permitted. For more information, go to About SMTP
|
|
397
399
|
# error messages.
|
|
@@ -496,10 +498,10 @@ module Sisimai
|
|
|
496
498
|
# https://support.google.com/a/answer/7282433
|
|
497
499
|
['452', '4.5.3', 'domain policy size per transaction exceeded'],
|
|
498
500
|
|
|
499
|
-
# - 454 4.7.0 Cannot
|
|
500
|
-
# For
|
|
501
|
-
#
|
|
502
|
-
['454', '4.7.0', 'cannot
|
|
501
|
+
# - 454 4.7.0 Cannot sign in due to a temporary system problem. Try again later.
|
|
502
|
+
# For details, go to SMTP relay service error messages.
|
|
503
|
+
# - https://support.google.com/a/answer/3221692
|
|
504
|
+
['454', '4.7.0', 'cannot sign in due to a temporary system problem'],
|
|
503
505
|
],
|
|
504
506
|
Sisimai::Eb::ReUSER => [
|
|
505
507
|
# - 550 5.1.1 The email account that you tried to reach does not exist. Please try dou-
|
data/lib/sisimai/smtp/status.rb
CHANGED
|
@@ -572,7 +572,7 @@ module Sisimai
|
|
|
572
572
|
'5.6.3' => Sisimai::Eb::ReBODY, # Conversion required but not supported
|
|
573
573
|
'5.6.5' => Sisimai::Eb::ReBODY, # Conversion Failed
|
|
574
574
|
'5.6.6' => Sisimai::Eb::ReBODY, # Message content not available
|
|
575
|
-
'5.6.7' => Sisimai::Eb::
|
|
575
|
+
'5.6.7' => Sisimai::Eb::RePROC, # Non-ASCII addresses not permitted for that sender/recipient
|
|
576
576
|
'5.6.8' => Sisimai::Eb::ReBODY, # UTF-8 string reply is required, but not permitted by the SMTP client
|
|
577
577
|
'5.6.9' => Sisimai::Eb::ReBODY, # UTF-8 header message cannot be transferred to one or more recipients
|
|
578
578
|
'5.7.0' => Sisimai::Eb::ReSAFE, # Other or undefined security status
|
data/lib/sisimai/string.rb
CHANGED
|
@@ -53,9 +53,10 @@ module Sisimai
|
|
|
53
53
|
# 3. <a href = 'http://...'>...</a> to " http://... "
|
|
54
54
|
# 4. <a href = 'mailto:...'>...</a> to " Value <mailto:...> "
|
|
55
55
|
plain.scrub!('?')
|
|
56
|
-
|
|
57
|
-
plain = plain.gsub(%r|<
|
|
58
|
-
plain = plain.gsub(%r|<
|
|
56
|
+
cv = plain.downcase
|
|
57
|
+
plain = plain.gsub(%r|<head>.+?</head>|im, "") if cv.include?("</head>")
|
|
58
|
+
plain = plain.gsub(%r|<style.+?>.+?</style>|im, "") if cv.include?("</style>")
|
|
59
|
+
plain = plain.gsub(%r|<a\s+href\s*=\s*(['"])(https?://[^'"]+?)\1[^>]*?>(.*?)</a>|i, ' [\3](\2) ')
|
|
59
60
|
plain = plain.gsub(%r|<a\s+href\s*=\s*["']mailto:([^\s]+?)["']>(.*?)</a>|i, '[\2](mailto:\1)')
|
|
60
61
|
plain = plain.gsub(/<[^<@>]+?>\s*/, ' ') # Delete HTML tags except <neko@example.jp>
|
|
61
62
|
plain = plain.gsub(/</, '<').gsub(/>/, '>') # Convert to angle brackets
|
data/lib/sisimai/version.rb
CHANGED
data/lib/sisimai.rb
CHANGED
|
@@ -19,16 +19,40 @@ module Sisimai
|
|
|
19
19
|
# @return [nil] nil if the argument was wrong or an empty array
|
|
20
20
|
def rise(argv0, **argv1)
|
|
21
21
|
return nil unless argv0
|
|
22
|
+
require 'sisimai/eb'
|
|
22
23
|
require 'sisimai/mail'
|
|
23
24
|
require 'sisimai/fact'
|
|
24
|
-
|
|
25
25
|
return nil unless mail = Sisimai::Mail.new(argv0)
|
|
26
|
-
|
|
26
|
+
|
|
27
|
+
maxb = Sisimai::Eb::XeBYTE * 32 # 64MB * 32 = 2GB
|
|
28
|
+
if (mail.kind == "mailbox" || mail.kind == "memory") && (mail.data.size > maxb || mail.data.size < 1)
|
|
29
|
+
# Check and limit the max size of entire email data: UNIX mbox and memory: 2GB
|
|
30
|
+
warn " ***warning: Input email is empty or too large: #{mail.data.size} bytes"
|
|
31
|
+
return nil
|
|
32
|
+
end
|
|
33
|
+
|
|
27
34
|
c___ = argv1[:c___].is_a?(Array) ? argv1[:c___] : [nil, nil]
|
|
28
35
|
sisi = []
|
|
29
|
-
|
|
36
|
+
sumb = 0
|
|
30
37
|
while r = mail.data.read do
|
|
31
38
|
# Read and decode each email file
|
|
39
|
+
if mail.kind == 'maildir'
|
|
40
|
+
# - Check and limit the max size of each email file (64MB)
|
|
41
|
+
# - Skip to the next email when the size of email is larger than 64MB.
|
|
42
|
+
next if mail.data.size > Sisimai::Eb::XeBYTE
|
|
43
|
+
else
|
|
44
|
+
# UNIX mbox, memory, and stdin.
|
|
45
|
+
next if r.bytesize > Sisimai::Eb::XeBYTE
|
|
46
|
+
|
|
47
|
+
if mail.kind == "stdin"
|
|
48
|
+
# Check and limit the max size of entire email data read from STDIN: 2GB
|
|
49
|
+
sumb += r.bytesize; if sumb > maxb
|
|
50
|
+
warn " ***warning: Input email is too large: #{sumb} bytes"
|
|
51
|
+
return nil
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
32
56
|
path = mail.data.path
|
|
33
57
|
args = {data: r, hook: c___[0], origin: path, delivered: argv1[:delivered], vacation: argv1[:vacation]}
|
|
34
58
|
fact = Sisimai::Fact.rise(**args) || []
|
|
@@ -36,7 +60,7 @@ module Sisimai
|
|
|
36
60
|
if c___[1]
|
|
37
61
|
# Run the callback function specified with "c___" parameter of Sisimai.rise after reading
|
|
38
62
|
# each email file in Maildir/ every time
|
|
39
|
-
args = {'kind' => kind, 'mail' => r, 'path' => path, 'fact' => fact}
|
|
63
|
+
args = {'kind' => mail.kind, 'mail' => r, 'path' => path, 'fact' => fact}
|
|
40
64
|
begin
|
|
41
65
|
c___[1].call(args) if c___[1].is_a?(Proc)
|
|
42
66
|
rescue StandardError => ce
|