sisimai 5.0.0-java → 5.0.3-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 +33 -0
- data/.github/workflows/rake-test.yml +54 -0
- data/ChangeLog.md +68 -1
- data/Gemfile +2 -0
- data/README-JA.md +224 -112
- data/README.md +56 -33
- data/lib/sisimai/arf.rb +24 -5
- data/lib/sisimai/fact.rb +46 -8
- data/lib/sisimai/lhost/amazonses.rb +0 -1
- data/lib/sisimai/lhost/amazonworkmail.rb +0 -1
- data/lib/sisimai/lhost/aol.rb +0 -1
- data/lib/sisimai/lhost/bigfoot.rb +0 -1
- data/lib/sisimai/lhost/domino.rb +0 -1
- data/lib/sisimai/lhost/exchange2007.rb +1 -1
- data/lib/sisimai/lhost/exim.rb +7 -16
- data/lib/sisimai/lhost/facebook.rb +0 -1
- data/lib/sisimai/lhost/googlegroups.rb +2 -1
- data/lib/sisimai/lhost/gsuite.rb +0 -1
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +1 -1
- data/lib/sisimai/lhost/mailru.rb +8 -17
- data/lib/sisimai/lhost/messagelabs.rb +0 -1
- data/lib/sisimai/lhost/mfilter.rb +1 -1
- data/lib/sisimai/lhost/mxlogic.rb +8 -18
- data/lib/sisimai/lhost/office365.rb +1 -1
- data/lib/sisimai/lhost/outlook.rb +0 -1
- data/lib/sisimai/lhost/postfix.rb +0 -1
- data/lib/sisimai/lhost/receivingses.rb +0 -1
- data/lib/sisimai/lhost/sendgrid.rb +1 -3
- data/lib/sisimai/lhost/sendmail.rb +0 -1
- data/lib/sisimai/lhost/yandex.rb +0 -1
- data/lib/sisimai/message.rb +14 -5
- data/lib/sisimai/reason/authfailure.rb +1 -0
- data/lib/sisimai/reason/blocked.rb +3 -0
- data/lib/sisimai/reason/expired.rb +8 -0
- data/lib/sisimai/reason/filtered.rb +1 -0
- data/lib/sisimai/reason/mailboxfull.rb +4 -0
- data/lib/sisimai/reason/norelaying.rb +1 -0
- data/lib/sisimai/reason/rejected.rb +1 -1
- data/lib/sisimai/reason/securityerror.rb +1 -0
- data/lib/sisimai/reason/spamdetected.rb +1 -0
- data/lib/sisimai/reason/suspend.rb +5 -0
- data/lib/sisimai/reason/userunknown.rb +4 -1
- data/lib/sisimai/rfc5322.rb +120 -64
- data/lib/sisimai/rhost/google.rb +347 -71
- data/lib/sisimai/rhost/microsoft.rb +8 -0
- data/lib/sisimai/rhost/mimecast.rb +9 -2
- data/lib/sisimai/rhost/nttdocomo.rb +3 -3
- data/lib/sisimai/smtp/status.rb +3 -0
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +12 -11
- data/set-of-emails/maildir/bsd/arf-26.eml +27 -0
- data/set-of-emails/maildir/bsd/lhost-sendmail-60.eml +85 -0
- data/set-of-emails/maildir/bsd/rhost-microsoft-04.eml +86 -0
- data/set-of-emails/maildir/bsd/rhost-microsoft-05.eml +83 -0
- metadata +13 -8
- data/.travis.yml +0 -23
@@ -168,7 +168,6 @@ module Sisimai::Lhost
|
|
168
168
|
dscontents.each do |e|
|
169
169
|
# Set default values if each value is empty.
|
170
170
|
e['diagnosis'] ||= ''
|
171
|
-
e['lhost'] ||= permessage['rhost']
|
172
171
|
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
173
172
|
|
174
173
|
if anotherset['diagnosis']
|
data/lib/sisimai/lhost/yandex.rb
CHANGED
@@ -103,7 +103,6 @@ module Sisimai::Lhost
|
|
103
103
|
|
104
104
|
dscontents.each do |e|
|
105
105
|
# Set default values if each value is empty.
|
106
|
-
e['lhost'] ||= permessage['rhost']
|
107
106
|
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
108
107
|
|
109
108
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
|
data/lib/sisimai/message.rb
CHANGED
@@ -198,17 +198,26 @@ module Sisimai
|
|
198
198
|
# Select and convert all the headers in $argv0. The following regular expression is based on
|
199
199
|
# https://gist.github.com/xtetsuji/b080e1f5551d17242f6415aba8a00239
|
200
200
|
headermaps = { 'subject' => '' }
|
201
|
-
|
201
|
+
receivedby = []
|
202
202
|
argv0.scan(/^([\w-]+):[ ]*(.*?)\n(?![\s\t])/m) { |e| headermaps[e[0].downcase] = e[1] }
|
203
203
|
headermaps.delete('received')
|
204
204
|
headermaps.each_key { |e| headermaps[e].gsub!(/\n[\s\t]+/, ' ') }
|
205
205
|
|
206
206
|
if argv0.include?('Received:')
|
207
207
|
# Capture values of each Received: header
|
208
|
-
|
209
|
-
|
208
|
+
re = argv0.scan(/^Received:[ ]*(.*?)\n(?![\s\t])/m).flatten
|
209
|
+
re.each do |e|
|
210
|
+
# 1. Exclude the Received header including "(qmail ** invoked from network)".
|
211
|
+
# 2. Convert all consecutive spaces and line breaks into a single space character.
|
212
|
+
next if e.include?(' invoked by uid')
|
213
|
+
next if e.include?(' invoked from network')
|
214
|
+
|
215
|
+
e.gsub!(/\n[\s\t]+/, ' ')
|
216
|
+
e.squeeze!("\n\t ")
|
217
|
+
receivedby << e
|
218
|
+
end
|
210
219
|
end
|
211
|
-
headermaps['received'] =
|
220
|
+
headermaps['received'] = receivedby
|
212
221
|
|
213
222
|
return headermaps unless argv1
|
214
223
|
return headermaps if headermaps['subject'].empty?
|
@@ -443,7 +452,7 @@ module Sisimai
|
|
443
452
|
unless haveloaded['Sisimai::ARF']
|
444
453
|
# Feedback Loop message
|
445
454
|
require 'sisimai/arf'
|
446
|
-
havesifted = Sisimai::ARF.inquire(mailheader, bodystring)
|
455
|
+
havesifted = Sisimai::ARF.inquire(mailheader, bodystring)
|
447
456
|
throw :PARSER if havesifted
|
448
457
|
end
|
449
458
|
|
@@ -46,6 +46,7 @@ module Sisimai
|
|
46
46
|
'part of their network is on our block list',
|
47
47
|
'please use the smtp server of your isp',
|
48
48
|
'refused - see http',
|
49
|
+
'rejected - multi-blacklist', # junkemailfilter.com
|
49
50
|
'rejected because the sending mta or the sender has not passed validation',
|
50
51
|
'rejecting open proxy', # Sendmail(srvrsmtp.c)
|
51
52
|
'sender ip address rejected',
|
@@ -61,6 +62,7 @@ module Sisimai
|
|
61
62
|
'we do not accept mail from dynamic ips', # @mail.ru
|
62
63
|
'you are not allowed to connect',
|
63
64
|
'you are sending spam',
|
65
|
+
'your ip address is listed in the rbl',
|
64
66
|
'your network is temporary blacklisted',
|
65
67
|
'your server requires confirmation',
|
66
68
|
].freeze
|
@@ -78,6 +80,7 @@ module Sisimai
|
|
78
80
|
['message from ', ' rejected based on blacklist'],
|
79
81
|
['messages from ', ' temporarily deferred due to user complaints'], # Yahoo!
|
80
82
|
['server ip ', ' listed as abusive'],
|
83
|
+
['sorry! your ip address', ' is blocked by rbl'], # junkemailfilter.com
|
81
84
|
['the domain ', ' is blacklisted'],
|
82
85
|
['the email ', ' is blacklisted'],
|
83
86
|
['the ip', ' is blacklisted'],
|
@@ -7,10 +7,13 @@ module Sisimai
|
|
7
7
|
# the message you sent has been in the queue for long time.
|
8
8
|
module Expired
|
9
9
|
class << self
|
10
|
+
require 'sisimai/string'
|
11
|
+
|
10
12
|
Index = [
|
11
13
|
'connection timed out',
|
12
14
|
'could not find a gateway for',
|
13
15
|
'delivery attempts will continue to be',
|
16
|
+
'delivery expired',
|
14
17
|
'delivery time expired',
|
15
18
|
'failed to deliver to domain ',
|
16
19
|
'giving up on',
|
@@ -18,6 +21,7 @@ module Sisimai
|
|
18
21
|
'has been delayed',
|
19
22
|
'it has not been collected after',
|
20
23
|
'message expired after sitting in queue for',
|
24
|
+
'message expired, cannot connect to remote server',
|
21
25
|
'message expired, connection refulsed',
|
22
26
|
'message timed out',
|
23
27
|
'retry time not reached for any host after a long failure period',
|
@@ -27,6 +31,9 @@ module Sisimai
|
|
27
31
|
'was not reachable within the allowed queue period',
|
28
32
|
'your message could not be delivered for more than',
|
29
33
|
].freeze
|
34
|
+
Pairs = [
|
35
|
+
['could not be delivered for', ' days'],
|
36
|
+
].freeze
|
30
37
|
|
31
38
|
def text; return 'expired'; end
|
32
39
|
def description; return 'Delivery time has expired due to a connection failure'; end
|
@@ -38,6 +45,7 @@ module Sisimai
|
|
38
45
|
def match(argv1)
|
39
46
|
return nil unless argv1
|
40
47
|
return true if Index.any? { |a| argv1.include?(a) }
|
48
|
+
return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
|
41
49
|
return false
|
42
50
|
end
|
43
51
|
|
@@ -21,6 +21,7 @@ module Sisimai
|
|
21
21
|
'resolver.rst.notauthorized', # Microsoft Exchange
|
22
22
|
'this account is protected by',
|
23
23
|
'user not found', # Filter on MAIL.RU
|
24
|
+
'user refuses to receive this mail',
|
24
25
|
'user reject',
|
25
26
|
'we failed to deliver mail because the following address recipient id refuse to receive mail', # Willcom
|
26
27
|
'you have been blocked by the recipient',
|
@@ -8,6 +8,7 @@ module Sisimai
|
|
8
8
|
module MailboxFull
|
9
9
|
class << self
|
10
10
|
Index = [
|
11
|
+
'452 insufficient disk space',
|
11
12
|
'account disabled temporarly for exceeding receiving limits',
|
12
13
|
'account is exceeding their quota',
|
13
14
|
'account is over quota',
|
@@ -15,6 +16,7 @@ module Sisimai
|
|
15
16
|
'boite du destinataire pleine',
|
16
17
|
'delivery failed: over quota',
|
17
18
|
'disc quota exceeded',
|
19
|
+
'diskspace quota',
|
18
20
|
'does not have enough space',
|
19
21
|
'exceeded storage allocation',
|
20
22
|
'exceeding its mailbox quota',
|
@@ -34,7 +36,9 @@ module Sisimai
|
|
34
36
|
'maildir delivery failed: userdisk quota ',
|
35
37
|
'maildir delivery failed: domaindisk quota ',
|
36
38
|
'mailfolder is full',
|
39
|
+
'no space left on device',
|
37
40
|
'not enough storage space in',
|
41
|
+
'not sufficient disk space',
|
38
42
|
'over the allowed quota',
|
39
43
|
'quota exceeded',
|
40
44
|
'quota violation for',
|
@@ -24,6 +24,7 @@ module Sisimai
|
|
24
24
|
'relay not permitted',
|
25
25
|
'relaying denied', # Sendmail
|
26
26
|
'relaying mail to ',
|
27
|
+
'specified domain is not allowed',
|
27
28
|
"that domain isn't in my list of allowed rcpthost",
|
28
29
|
'this system is not configured to relay mail',
|
29
30
|
'unable to relay for',
|
@@ -38,7 +38,7 @@ module Sisimai
|
|
38
38
|
'email address is on senderfilterconfig list',
|
39
39
|
'emetteur invalide',
|
40
40
|
'empty envelope senders not allowed',
|
41
|
-
'envelope blocked
|
41
|
+
'envelope blocked - ',
|
42
42
|
'error: no third-party dsns', # SpamWall - block empty sender
|
43
43
|
'from: domain is invalid. please provide a valid from:',
|
44
44
|
'fully qualified email address required', # McAfee
|
@@ -29,6 +29,7 @@ module Sisimai
|
|
29
29
|
'insecure mail relay',
|
30
30
|
'recipient address rejected: access denied',
|
31
31
|
"sorry, you don't authenticate or the domain isn't in my list of allowed rcpthosts",
|
32
|
+
'starttls is required to send mail',
|
32
33
|
'tls required but not supported', # SendGrid:the recipient mailserver does not support TLS or have a valid certificate
|
33
34
|
'unauthenticated senders not allowed',
|
34
35
|
'verification failure',
|
@@ -76,6 +76,7 @@ module Sisimai
|
|
76
76
|
'spam score ',
|
77
77
|
'spambouncer identified spam', # SpamBouncer identified SPAM
|
78
78
|
'spamming not allowed',
|
79
|
+
'too many spam complaints',
|
79
80
|
'too much spam.', # Earthlink
|
80
81
|
'the email message was detected as spam',
|
81
82
|
'the message has been rejected by spam filtering engine',
|
@@ -12,16 +12,21 @@ module Sisimai
|
|
12
12
|
'boite du destinataire archivee',
|
13
13
|
'email account that you tried to reach is disabled',
|
14
14
|
'has been suspended',
|
15
|
+
'inactive account',
|
15
16
|
'invalid/inactive user',
|
16
17
|
'is a deactivated mailbox', # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
|
17
18
|
'is unavailable: user is terminated',
|
18
19
|
'mailbox currently suspended',
|
20
|
+
'mailbox disabled',
|
19
21
|
'mailbox is frozen',
|
20
22
|
'mailbox unavailable or access denied',
|
21
23
|
'recipient rejected: temporarily inactive',
|
22
24
|
'recipient suspend the service',
|
23
25
|
'this account has been disabled or discontinued',
|
26
|
+
'this account has been temporarily suspended',
|
27
|
+
'this address no longer accepts mail',
|
24
28
|
'this mailbox is disabled',
|
29
|
+
'user or domain is disabled',
|
25
30
|
'user suspended', # http://mail.163.com/help/help_spam_16.htm
|
26
31
|
'vdelivermail: account is locked email bounced',
|
27
32
|
].freeze
|
@@ -63,7 +63,6 @@ module Sisimai
|
|
63
63
|
'no such mailbox',
|
64
64
|
'no such person at this address',
|
65
65
|
'no such recipient',
|
66
|
-
|
67
66
|
'no such user',
|
68
67
|
'no thank you rejected: account unavailable',
|
69
68
|
'no valid recipients, bye',
|
@@ -76,7 +75,9 @@ module Sisimai
|
|
76
75
|
'recipient address rejected: invalid user',
|
77
76
|
'recipient address rejected: invalid-recipient',
|
78
77
|
'recipient address rejected: unknown user',
|
78
|
+
'recipient address rejected: userunknown',
|
79
79
|
'recipient does not exist',
|
80
|
+
'recipient is not accepted',
|
80
81
|
'recipient is not local',
|
81
82
|
'recipient not exist',
|
82
83
|
'recipient not found',
|
@@ -125,6 +126,7 @@ module Sisimai
|
|
125
126
|
['no ', ' in name directory'],
|
126
127
|
['non', 'existent user'],
|
127
128
|
['rcpt <', ' does not exist'],
|
129
|
+
['rcpt (', 't exist '],
|
128
130
|
['recipient ', ' was not found in'],
|
129
131
|
['recipient address rejected: user ', ' does not exist'],
|
130
132
|
['recipient address rejected: user unknown in ', ' table'],
|
@@ -135,6 +137,7 @@ module Sisimai
|
|
135
137
|
['unknown local', 'part'],
|
136
138
|
['user ', ' was not found'],
|
137
139
|
['user ', ' does not exist'],
|
140
|
+
['user (', ') unknown'],
|
138
141
|
].freeze
|
139
142
|
|
140
143
|
def text; return 'userunknown'; end
|
data/lib/sisimai/rfc5322.rb
CHANGED
@@ -3,6 +3,7 @@ module Sisimai
|
|
3
3
|
module RFC5322
|
4
4
|
class << self
|
5
5
|
require 'sisimai/string'
|
6
|
+
require 'sisimai/address'
|
6
7
|
HeaderTable = {
|
7
8
|
:messageid => %w[message-id],
|
8
9
|
:subject => %w[subject],
|
@@ -52,79 +53,134 @@ module Sisimai
|
|
52
53
|
# @return [Array] Received header as a structured data
|
53
54
|
def received(argv1)
|
54
55
|
return [] unless argv1.is_a?(::String)
|
56
|
+
return [] if argv1.include?(' invoked by uid')
|
57
|
+
return [] if argv1.include?(' invoked from network')
|
58
|
+
|
59
|
+
# - https://datatracker.ietf.org/doc/html/rfc5322
|
60
|
+
# received = "Received:" *received-token ";" date-time CRLF
|
61
|
+
# received-token = word / angle-addr / addr-spec / domain
|
62
|
+
#
|
63
|
+
# - Appendix A.4. Message with Trace Fields
|
64
|
+
# Received:
|
65
|
+
# from x.y.test
|
66
|
+
# by example.net
|
67
|
+
# via TCP
|
68
|
+
# with ESMTP
|
69
|
+
# id ABC12345
|
70
|
+
# for <mary@example.net>; 21 Nov 1997 10:05:43 -0600
|
71
|
+
recvd = argv1.split(' ')
|
72
|
+
label = %w[from by via with id for]
|
73
|
+
token = {}
|
74
|
+
other = []
|
75
|
+
alter = []
|
76
|
+
right = false
|
77
|
+
range = recvd.size
|
78
|
+
index = -1
|
79
|
+
|
80
|
+
recvd.each do |e|
|
81
|
+
# Look up each label defined in "label" from Received header
|
82
|
+
index += 1
|
83
|
+
break unless index < range; f = e.downcase
|
84
|
+
next unless label.any? { |a| f == a }
|
85
|
+
token[f] = recvd[index + 1] || next
|
86
|
+
token[f] = token[f].downcase.delete('();')
|
87
|
+
|
88
|
+
next unless f == 'from'
|
89
|
+
break unless index + 2 < range
|
90
|
+
next unless recvd[index + 2].start_with?('(')
|
91
|
+
|
92
|
+
# Get and keep a hostname in the comment as follows:
|
93
|
+
# from mx1.example.com (c213502.kyoto.example.ne.jp [192.0.2.135]) by mx.example.jp (V8/cf)
|
94
|
+
# [
|
95
|
+
# "from", # index + 0
|
96
|
+
# "mx1.example.com", # index + 1
|
97
|
+
# "(c213502.kyoto.example.ne.jp", # index + 2
|
98
|
+
# "[192.0.2.135])", # index + 3
|
99
|
+
# "by",
|
100
|
+
# "mx.example.jp",
|
101
|
+
# "(V8/cf)",
|
102
|
+
# ...
|
103
|
+
# ]
|
104
|
+
# The 2nd element after the current element is NOT a continuation of the current element
|
105
|
+
# such as "(c213502.kyoto.example.ne.jp)"
|
106
|
+
other << recvd[index + 2].delete('();')
|
107
|
+
|
108
|
+
# The 2nd element after the current element is a continuation of the current element.
|
109
|
+
# such as "(c213502.kyoto.example.ne.jp", "[192.0.2.135])"
|
110
|
+
break unless index + 3 < range
|
111
|
+
other << recvd[index + 3].delete('();')
|
112
|
+
end
|
55
113
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# Wed, 26 Feb 2014 06:05:48 -0500
|
69
|
-
value['from'] = Sisimai::String.sweep(argv1[p1 + 5, p2 - p1 - 5])
|
70
|
-
value['by'] = Sisimai::String.sweep(argv1[p2 + 3, p3 - p2 - 3])
|
114
|
+
other.each do |e|
|
115
|
+
# Check alternatives in "other", and then delete uninformative values.
|
116
|
+
next if e.nil?
|
117
|
+
next if e.size < 4
|
118
|
+
next if e == 'unknown'
|
119
|
+
next if e == 'localhost'
|
120
|
+
next if e == '[127.0.0.1]'
|
121
|
+
next if e == '[IPv6:::1]'
|
122
|
+
next unless e.include?('.')
|
123
|
+
next if e.include?('=')
|
124
|
+
alter << e
|
125
|
+
end
|
71
126
|
|
72
|
-
|
73
|
-
#
|
74
|
-
|
75
|
-
|
127
|
+
%w[from by].each do |e|
|
128
|
+
# Remove square brackets from the IP address such as "[192.0.2.25]"
|
129
|
+
next if token[e].nil?
|
130
|
+
next if token[e].empty?
|
131
|
+
next unless token[e].start_with?('[')
|
132
|
+
token[e] = Sisimai::String.ipv4(token[e]).shift || ''
|
76
133
|
end
|
134
|
+
token['from'] ||= ''
|
77
135
|
|
78
|
-
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
hostname = ''
|
85
|
-
hostaddr = ''
|
86
|
-
|
87
|
-
while e = received.shift do
|
88
|
-
# Received: from [10.22.22.222] (smtp-gateway.kyoto.ocn.ne.jp [192.0.2.222])
|
89
|
-
cv = Sisimai::String.ipv4(e) || []
|
90
|
-
if cv.size > 0
|
91
|
-
# [192.0.2.1] or (192.0.2.1)
|
92
|
-
addrlist.append(*cv)
|
93
|
-
else
|
94
|
-
# hostname
|
95
|
-
e = e.delete('()').strip
|
96
|
-
namelist << e
|
97
|
-
end
|
98
|
-
end
|
136
|
+
while true do
|
137
|
+
# Prefer hostnames over IP addresses, except for localhost.localdomain and similar.
|
138
|
+
break if token['from'] == 'localhost'
|
139
|
+
break if token['from'] == 'localhost.localdomain'
|
140
|
+
break unless token['from'].include?('.') # A hostname without a domain name
|
141
|
+
break unless Sisimai::String.ipv4(token['from']).empty?
|
99
142
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
break
|
105
|
-
end
|
143
|
+
# No need to rewrite token['from']
|
144
|
+
right = true
|
145
|
+
break
|
146
|
+
end
|
106
147
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
148
|
+
while true do
|
149
|
+
# Try to rewrite uninformative hostnames and IP addresses in token['from']
|
150
|
+
break if right # There is no need to rewrite
|
151
|
+
break if alter.empty? # There is no alternative to rewriting
|
152
|
+
break if alter[0].include?(token['from'])
|
153
|
+
|
154
|
+
if token['from'].start_with?('localhost')
|
155
|
+
# localhost or localhost.localdomain
|
156
|
+
token['from'] = alter[0]
|
157
|
+
elsif token['from'].index('.')
|
158
|
+
# A hostname without a domain name such as "mail", "mx", or "mbox"
|
159
|
+
token['from'] = alter[0] if alter[0].include?('.')
|
160
|
+
else
|
161
|
+
# An IPv4 address
|
162
|
+
token['from'] = alter[0]
|
116
163
|
end
|
117
|
-
|
118
|
-
value['from'] = hostname || hostaddr || addrlist[-1]
|
164
|
+
break
|
119
165
|
end
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
166
|
+
token.delete('from') if token['from'].nil?
|
167
|
+
token.delete('by') if token['by'].nil?
|
168
|
+
token['for'] = Sisimai::Address.s3s4(token['for']) if token.has_key?('for')
|
169
|
+
|
170
|
+
token.keys.each do |e|
|
171
|
+
# Delete an invalid value
|
172
|
+
token[e] = '' if token[e].include?(' ')
|
173
|
+
token[e].delete!('[]') # Remove "[]" from the IP address
|
126
174
|
end
|
127
|
-
|
175
|
+
|
176
|
+
return [
|
177
|
+
token['from'] || '',
|
178
|
+
token['by'] || '',
|
179
|
+
token['via'] || '',
|
180
|
+
token['with'] || '',
|
181
|
+
token['id'] || '',
|
182
|
+
token['for'] || '',
|
183
|
+
]
|
128
184
|
end
|
129
185
|
|
130
186
|
# Split given entire message body into error message lines and the original message part only
|