sisimai 5.0.0-java → 5.0.3-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|