sisimai 4.16.0-java → 4.17.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.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/ANALYTICAL-PRECISION +7 -7
  4. data/Changes +15 -0
  5. data/Makefile +1 -1
  6. data/README.md +30 -28
  7. data/lib/sisimai.rb +20 -1
  8. data/lib/sisimai/address.rb +28 -9
  9. data/lib/sisimai/arf.rb +37 -46
  10. data/lib/sisimai/data.rb +67 -43
  11. data/lib/sisimai/datetime.rb +210 -210
  12. data/lib/sisimai/mda.rb +30 -30
  13. data/lib/sisimai/message.rb +3 -5
  14. data/lib/sisimai/msp/de/einsundeins.rb +14 -42
  15. data/lib/sisimai/msp/de/gmx.rb +17 -44
  16. data/lib/sisimai/msp/jp/biglobe.rb +15 -44
  17. data/lib/sisimai/msp/jp/ezweb.rb +20 -50
  18. data/lib/sisimai/msp/jp/kddi.rb +16 -43
  19. data/lib/sisimai/msp/ru/mailru.rb +20 -48
  20. data/lib/sisimai/msp/ru/yandex.rb +16 -50
  21. data/lib/sisimai/msp/uk/messagelabs.rb +17 -51
  22. data/lib/sisimai/msp/us/amazonses.rb +18 -40
  23. data/lib/sisimai/msp/us/amazonworkmail.rb +17 -35
  24. data/lib/sisimai/msp/us/aol.rb +17 -41
  25. data/lib/sisimai/msp/us/bigfoot.rb +15 -48
  26. data/lib/sisimai/msp/us/facebook.rb +63 -90
  27. data/lib/sisimai/msp/us/google.rb +15 -44
  28. data/lib/sisimai/msp/us/office365.rb +21 -46
  29. data/lib/sisimai/msp/us/outlook.rb +17 -50
  30. data/lib/sisimai/msp/us/receivingses.rb +20 -43
  31. data/lib/sisimai/msp/us/sendgrid.rb +13 -37
  32. data/lib/sisimai/msp/us/verizon.rb +30 -74
  33. data/lib/sisimai/msp/us/yahoo.rb +12 -40
  34. data/lib/sisimai/msp/us/zoho.rb +14 -42
  35. data/lib/sisimai/mta/activehunter.rb +11 -40
  36. data/lib/sisimai/mta/apachejames.rb +18 -40
  37. data/lib/sisimai/mta/courier.rb +20 -57
  38. data/lib/sisimai/mta/domino.rb +24 -56
  39. data/lib/sisimai/mta/exchange.rb +26 -54
  40. data/lib/sisimai/mta/exim.rb +20 -39
  41. data/lib/sisimai/mta/imailserver.rb +26 -71
  42. data/lib/sisimai/mta/interscanmss.rb +26 -44
  43. data/lib/sisimai/mta/mailfoundry.rb +12 -42
  44. data/lib/sisimai/mta/mailmarshalsmtp.rb +13 -43
  45. data/lib/sisimai/mta/mcafee.rb +17 -46
  46. data/lib/sisimai/mta/messagingserver.rb +14 -47
  47. data/lib/sisimai/mta/mfilter.rb +12 -35
  48. data/lib/sisimai/mta/mxlogic.rb +18 -42
  49. data/lib/sisimai/mta/notes.rb +22 -45
  50. data/lib/sisimai/mta/opensmtpd.rb +18 -48
  51. data/lib/sisimai/mta/postfix.rb +15 -45
  52. data/lib/sisimai/mta/qmail.rb +32 -60
  53. data/lib/sisimai/mta/sendmail.rb +13 -38
  54. data/lib/sisimai/mta/surfcontrol.rb +15 -44
  55. data/lib/sisimai/mta/userdefined.rb +14 -30
  56. data/lib/sisimai/mta/v5sendmail.rb +18 -40
  57. data/lib/sisimai/mta/x1.rb +12 -41
  58. data/lib/sisimai/mta/x2.rb +12 -41
  59. data/lib/sisimai/mta/x3.rb +12 -39
  60. data/lib/sisimai/mta/x4.rb +33 -66
  61. data/lib/sisimai/mta/x5.rb +15 -42
  62. data/lib/sisimai/reason.rb +8 -71
  63. data/lib/sisimai/reason/blocked.rb +3 -0
  64. data/lib/sisimai/reason/contenterror.rb +3 -0
  65. data/lib/sisimai/reason/delivered.rb +27 -0
  66. data/lib/sisimai/reason/exceedlimit.rb +3 -0
  67. data/lib/sisimai/reason/expired.rb +3 -0
  68. data/lib/sisimai/reason/feedback.rb +18 -0
  69. data/lib/sisimai/reason/filtered.rb +4 -0
  70. data/lib/sisimai/reason/hasmoved.rb +3 -0
  71. data/lib/sisimai/reason/hostunknown.rb +3 -0
  72. data/lib/sisimai/reason/mailboxfull.rb +3 -0
  73. data/lib/sisimai/reason/mailererror.rb +3 -0
  74. data/lib/sisimai/reason/mesgtoobig.rb +3 -0
  75. data/lib/sisimai/reason/networkerror.rb +3 -0
  76. data/lib/sisimai/reason/norelaying.rb +3 -0
  77. data/lib/sisimai/reason/notaccept.rb +3 -0
  78. data/lib/sisimai/reason/onhold.rb +3 -0
  79. data/lib/sisimai/reason/rejected.rb +3 -0
  80. data/lib/sisimai/reason/securityerror.rb +3 -0
  81. data/lib/sisimai/reason/spamdetected.rb +3 -0
  82. data/lib/sisimai/reason/suspend.rb +3 -0
  83. data/lib/sisimai/reason/syntaxerror.rb +41 -0
  84. data/lib/sisimai/reason/systemerror.rb +3 -0
  85. data/lib/sisimai/reason/systemfull.rb +3 -0
  86. data/lib/sisimai/reason/toomanyconn.rb +3 -0
  87. data/lib/sisimai/reason/undefined.rb +18 -0
  88. data/lib/sisimai/reason/userunknown.rb +3 -0
  89. data/lib/sisimai/reason/vacation.rb +18 -0
  90. data/lib/sisimai/rfc3464.rb +15 -40
  91. data/lib/sisimai/rfc3834.rb +1 -10
  92. data/lib/sisimai/rfc5322.rb +57 -19
  93. data/lib/sisimai/rhost/googleapps.rb +82 -82
  94. data/lib/sisimai/smtp/reply.rb +2 -1
  95. data/lib/sisimai/smtp/status.rb +154 -152
  96. data/lib/sisimai/string.rb +2 -3
  97. data/lib/sisimai/version.rb +1 -1
  98. data/set-of-emails/maildir/bsd/rfc3464-29.eml +60 -0
  99. data/set-of-emails/maildir/bsd/us-amazonworkmail-06.eml +156 -0
  100. data/set-of-emails/maildir/bsd/us-amazonworkmail-07.eml +158 -0
  101. data/set-of-emails/maildir/bsd/us-google-15.eml +97 -0
  102. data/set-of-emails/maildir/bsd/us-google-16.eml +99 -0
  103. data/set-of-emails/maildir/bsd/us-google-17.eml +104 -0
  104. data/set-of-emails/maildir/dos/apachejames-01.eml +4 -4
  105. data/set-of-emails/maildir/dos/us-amazonworkmail-01.eml +156 -0
  106. data/set-of-emails/maildir/dos/us-office365-01.eml +102 -0
  107. data/set-of-emails/maildir/mac/apachejames-01.eml +1 -9
  108. data/set-of-emails/maildir/mac/us-amazonworkmail-01.eml +1 -7
  109. data/set-of-emails/maildir/mac/us-office365-01.eml +1 -4
  110. metadata +17 -2
@@ -19,8 +19,6 @@ module Sisimai
19
19
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
20
20
  }
21
21
  Indicators = Sisimai::MTA.INDICATORS
22
- LongFields = Sisimai::RFC5322.LONGFIELDS
23
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
24
22
 
25
23
  def description; return 'MailFoundry'; end
26
24
  def smtpagent; return 'MailFoundry'; end
@@ -44,11 +42,10 @@ module Sisimai
44
42
  return nil unless mhead['subject'] =~ Re0[:subject]
45
43
  return nil unless mhead['received'].find { |a| a =~ Re0[:received] }
46
44
 
47
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
45
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
48
46
  hasdivided = mbody.split("\n")
49
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
50
- rfc822part = '' # (String) message/rfc822-headers part
51
- previousfn = '' # (String) Previous field name
47
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
48
+ blanklines = 0 # (Integer) The number of blank lines
52
49
  readcursor = 0 # (Integer) Points the current cursor position
53
50
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
54
51
  v = nil
@@ -57,7 +54,7 @@ module Sisimai
57
54
  if readcursor == 0
58
55
  # Beginning of the bounce message or delivery status part
59
56
  if e =~ Re1[:begin]
60
- readcursor |= Indicators[:'deliverystatus']
57
+ readcursor |= Indicators[:deliverystatus]
61
58
  next
62
59
  end
63
60
  end
@@ -72,30 +69,16 @@ module Sisimai
72
69
 
73
70
  if readcursor & Indicators[:'message-rfc822'] > 0
74
71
  # After "message/rfc822"
75
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
76
- # Get required headers only
77
- lhs = cv[1].downcase
78
- previousfn = ''
79
- next unless RFC822Head.key?(lhs)
80
-
81
- previousfn = lhs
82
- rfc822part += e + "\n"
83
-
84
- elsif e =~ /\A[ \t]+/
85
- # Continued line from the previous line
86
- next if rfc822next[previousfn]
87
- rfc822part += e + "\n" if LongFields.key?(previousfn)
88
-
89
- else
90
- # Check the end of headers in rfc822 part
91
- next unless LongFields.key?(previousfn)
92
- next unless e.empty?
93
- rfc822next[previousfn] = true
72
+ if e.empty?
73
+ blanklines += 1
74
+ break if blanklines > 1
75
+ next
94
76
  end
77
+ rfc822list << e
95
78
 
96
79
  else
97
80
  # Before "message/rfc822"
98
- next if readcursor & Indicators[:'deliverystatus'] == 0
81
+ next if readcursor & Indicators[:deliverystatus] == 0
99
82
  next if e.empty?
100
83
 
101
84
  # Unable to deliver message to: <kijitora@example.org>
@@ -140,29 +123,16 @@ module Sisimai
140
123
  end
141
124
  end
142
125
  end
143
-
144
126
  return nil if recipients == 0
145
127
  require 'sisimai/string'
146
- require 'sisimai/smtp/status'
147
128
 
148
129
  dscontents.map do |e|
149
- e['agent'] = Sisimai::MTA::MailFoundry.smtpagent
150
-
151
- if mhead['received'].size > 0
152
- # Get localhost and remote host name from Received header.
153
- r0 = mhead['received']
154
- %w|lhost rhost|.each { |a| e[a] ||= '' }
155
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
156
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
157
- end
130
+ e['agent'] = Sisimai::MTA::MailFoundry.smtpagent
158
131
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
159
-
160
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
161
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
162
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
163
132
  e.each_key { |a| e[a] ||= '' }
164
133
  end
165
134
 
135
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
166
136
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
167
137
  end
168
138
 
@@ -20,8 +20,6 @@ module Sisimai
20
20
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
21
21
  }
22
22
  Indicators = Sisimai::MTA.INDICATORS
23
- LongFields = Sisimai::RFC5322.LONGFIELDS
24
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
25
23
 
26
24
  def description; return 'Trustwave Secure Email Gateway'; end
27
25
  def smtpagent; return 'MailMarshalSMTP'; end
@@ -45,11 +43,10 @@ module Sisimai
45
43
  return nil unless mhead['subject'] =~ Re0[:subject]
46
44
 
47
45
  require 'sisimai/mime'
48
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
46
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
49
47
  hasdivided = mbody.split("\n")
50
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
51
- rfc822part = '' # (String) message/rfc822-headers part
52
- previousfn = '' # (String) Previous field name
48
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
49
+ blanklines = 0 # (Integer) The number of blank lines
53
50
  readcursor = 0 # (Integer) Points the current cursor position
54
51
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
55
52
  endoferror = false # (Boolean) Flag for the end of error message
@@ -68,7 +65,7 @@ module Sisimai
68
65
  if readcursor == 0
69
66
  # Beginning of the bounce message or delivery status part
70
67
  if e =~ Re1[:begin]
71
- readcursor |= Indicators[:'deliverystatus']
68
+ readcursor |= Indicators[:deliverystatus]
72
69
  next
73
70
  end
74
71
  end
@@ -83,30 +80,16 @@ module Sisimai
83
80
 
84
81
  if readcursor & Indicators[:'message-rfc822'] > 0
85
82
  # After "message/rfc822"
86
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
87
- # Get required headers only
88
- lhs = cv[1].downcase
89
- previousfn = ''
90
- next unless RFC822Head.key?(lhs)
91
-
92
- previousfn = lhs
93
- rfc822part += e + "\n"
94
-
95
- elsif e =~ /\A[ \t]+/
96
- # Continued line from the previous line
97
- next if rfc822next[previousfn]
98
- rfc822part += e + "\n" if LongFields.key?(previousfn)
99
-
100
- else
101
- # Check the end of headers in rfc822 part
102
- next unless LongFields.key?(previousfn)
103
- next unless e.empty?
104
- rfc822next[previousfn] = true
83
+ if e.empty?
84
+ blanklines += 1
85
+ break if blanklines > 1
86
+ next
105
87
  end
88
+ rfc822list << e
106
89
 
107
90
  else
108
91
  # Before "message/rfc822"
109
- next if readcursor & Indicators[:'deliverystatus'] == 0
92
+ next if readcursor & Indicators[:deliverystatus] == 0
110
93
  break if e =~ regularexp
111
94
 
112
95
  # Your message:
@@ -159,7 +142,7 @@ module Sisimai
159
142
  # Original Sender: <originalsender@example.com>
160
143
  # Use this line instead of "From" header of the original
161
144
  # message.
162
- rfc822part += sprintf("From: %s\n", cv[1])
145
+ rfc822list << sprintf('From: %s', cv[1])
163
146
 
164
147
  elsif cv = e.match(/\ASender-MTA:[ \t]+[<](.+)[>]\z/)
165
148
  # Sender-MTA: <10.11.12.13>
@@ -173,29 +156,16 @@ module Sisimai
173
156
  end
174
157
  end
175
158
  end
176
-
177
159
  return nil if recipients == 0
178
160
  require 'sisimai/string'
179
- require 'sisimai/smtp/status'
180
161
 
181
162
  dscontents.map do |e|
182
- e['agent'] = Sisimai::MTA::MailMarshalSMTP.smtpagent
183
-
184
- if mhead['received'].size > 0
185
- # Get localhost and remote host name from Received header.
186
- r0 = mhead['received']
187
- %w|lhost rhost|.each { |a| e[a] ||= '' }
188
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
189
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
190
- end
163
+ e['agent'] = Sisimai::MTA::MailMarshalSMTP.smtpagent
191
164
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
192
-
193
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
194
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
195
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
196
165
  e.each_key { |a| e[a] ||= '' }
197
166
  end
198
167
 
168
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
199
169
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
200
170
  end
201
171
 
@@ -19,15 +19,13 @@ module Sisimai
19
19
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
20
20
  }
21
21
  ReFailure = {
22
- 'userunknown' => %r{(?:
22
+ userunknown: %r{(?:
23
23
  User[ ][(].+[@].+[)][ ]unknown[.]
24
24
  |550[ ]Unknown[ ]user[ ][^ ]+[@][^ ]+
25
25
  )
26
26
  }x,
27
27
  }
28
28
  Indicators = Sisimai::MTA.INDICATORS
29
- LongFields = Sisimai::RFC5322.LONGFIELDS
30
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
31
29
 
32
30
  def description; return 'McAfee Email Appliance'; end
33
31
  def smtpagent; return 'McAfee'; end
@@ -53,12 +51,11 @@ module Sisimai
53
51
  return nil unless mhead['subject'] =~ Re0[:'subject']
54
52
 
55
53
  require 'sisimai/address'
56
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
54
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
57
55
  hasdivided = mbody.split("\n")
58
- havepassed = [''];
59
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
60
- rfc822part = '' # (String) message/rfc822-headers part
61
- previousfn = '' # (String) Previous field name
56
+ havepassed = ['']
57
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
58
+ blanklines = 0 # (Integer) The number of blank lines
62
59
  readcursor = 0 # (Integer) Points the current cursor position
63
60
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
64
61
  diagnostic = '' # (String) Alternative diagnostic message
@@ -66,12 +63,13 @@ module Sisimai
66
63
 
67
64
  hasdivided.each do |e|
68
65
  # Save the current line for the next loop
69
- havepassed << e; p = havepassed[-2]
66
+ havepassed << e
67
+ p = havepassed[-2]
70
68
 
71
69
  if readcursor == 0
72
70
  # Beginning of the bounce message or delivery status part
73
71
  if e =~ Re1[:begin]
74
- readcursor |= Indicators[:'deliverystatus']
72
+ readcursor |= Indicators[:deliverystatus]
75
73
  next
76
74
  end
77
75
  end
@@ -86,30 +84,16 @@ module Sisimai
86
84
 
87
85
  if readcursor & Indicators[:'message-rfc822'] > 0
88
86
  # After "message/rfc822"
89
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
90
- # Get required headers only
91
- lhs = cv[1].downcase
92
- previousfn = ''
93
- next unless RFC822Head.key?(lhs)
94
-
95
- previousfn = lhs
96
- rfc822part += e + "\n"
97
-
98
- elsif e =~ /\A[ \t]+/
99
- # Continued line from the previous line
100
- next if rfc822next[previousfn]
101
- rfc822part += e + "\n" if LongFields.key?(previousfn)
102
-
103
- else
104
- # Check the end of headers in rfc822 part
105
- next unless LongFields.key?(previousfn)
106
- next unless e.empty?
107
- rfc822next[previousfn] = true
87
+ if e.empty?
88
+ blanklines += 1
89
+ break if blanklines > 1
90
+ next
108
91
  end
92
+ rfc822list << e
109
93
 
110
94
  else
111
95
  # Before "message/rfc822"
112
- next if readcursor & Indicators[:'deliverystatus'] == 0
96
+ next if readcursor & Indicators[:deliverystatus] == 0
113
97
  next if e.empty?
114
98
 
115
99
  # Content-Type: text/plain; name="deliveryproblems.txt"
@@ -161,36 +145,23 @@ module Sisimai
161
145
  end
162
146
  end
163
147
  end
164
-
165
148
  return nil if recipients == 0
166
149
  require 'sisimai/string'
167
- require 'sisimai/smtp/status'
168
150
 
169
151
  dscontents.map do |e|
170
- # Set default values if each value is empty.
171
- e['agent'] = Sisimai::MTA::McAfee.smtpagent
172
-
173
- if mhead['received'].size > 0
174
- # Get localhost and remote host name from Received header.
175
- r0 = mhead['received']
176
- %w|lhost rhost|.each { |a| e[a] ||= '' }
177
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
178
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
179
- end
152
+ e['agent'] = Sisimai::MTA::McAfee.smtpagent
180
153
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'] || diagnostic)
181
154
 
182
155
  ReFailure.each_key do |r|
183
156
  # Verify each regular expression of session errors
184
157
  next unless e['diagnosis'] =~ ReFailure[r]
185
- e['reason'] = r
158
+ e['reason'] = r.to_s
186
159
  break
187
160
  end
188
-
189
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
190
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
191
161
  e.each_key { |a| e[a] ||= '' }
192
162
  end
193
163
 
164
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
194
165
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
195
166
  end
196
167
 
@@ -20,11 +20,9 @@ module Sisimai
20
20
  :rfc822 => %r!\A(?:Content-type:[ ]*message/rfc822|Return-path:[ ]*)!x,
21
21
  }
22
22
  ReFailure = {
23
- 'hostunknown' => %r{Illegal[ ]host/domain[ ]name[ ]found}x,
23
+ hostunknown: %r|Illegal[ ]host/domain[ ]name[ ]found|x,
24
24
  }
25
25
  Indicators = Sisimai::MTA.INDICATORS
26
- LongFields = Sisimai::RFC5322.LONGFIELDS
27
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
28
26
 
29
27
  def description; return 'Oracle Communications Messaging Server'; end
30
28
  def smtpagent; return 'MessagingServer'; end
@@ -52,11 +50,10 @@ module Sisimai
52
50
  return nil if match == 0
53
51
 
54
52
  require 'sisimai/address'
55
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
53
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
56
54
  hasdivided = mbody.split("\n")
57
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
58
- rfc822part = '' # (String) message/rfc822-headers part
59
- previousfn = '' # (String) Previous field name
55
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
56
+ blanklines = 0 # (Integer) The number of blank lines
60
57
  readcursor = 0 # (Integer) Points the current cursor position
61
58
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
62
59
  v = nil
@@ -65,7 +62,7 @@ module Sisimai
65
62
  if readcursor == 0
66
63
  # Beginning of the bounce message or delivery status part
67
64
  if e =~ Re1[:begin]
68
- readcursor |= Indicators[:'deliverystatus']
65
+ readcursor |= Indicators[:deliverystatus]
69
66
  next
70
67
  end
71
68
  end
@@ -80,30 +77,16 @@ module Sisimai
80
77
 
81
78
  if readcursor & Indicators[:'message-rfc822'] > 0
82
79
  # After "message/rfc822"
83
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
84
- # Get required headers only
85
- lhs = cv[1].downcase
86
- previousfn = ''
87
- next unless RFC822Head.key?(lhs)
88
-
89
- previousfn = lhs
90
- rfc822part += e + "\n"
91
-
92
- elsif e =~ /\A[ \t]+/
93
- # Continued line from the previous line
94
- next if rfc822next[previousfn]
95
- rfc822part += e + "\n" if LongFields.key?(previousfn)
96
-
97
- else
98
- # Check the end of headers in rfc822 part
99
- next unless LongFields.key?(previousfn)
100
- next unless e.empty?
101
- rfc822next[previousfn] = true
80
+ if e.empty?
81
+ blanklines += 1
82
+ break if blanklines > 1
83
+ next
102
84
  end
85
+ rfc822list << e
103
86
 
104
87
  else
105
88
  # Before "message/rfc822"
106
- next if readcursor & Indicators[:'deliverystatus'] == 0
89
+ next if readcursor & Indicators[:deliverystatus] == 0
107
90
  next if e.empty?
108
91
 
109
92
  # --Boundary_(ID_0000000000000000000000)
@@ -198,39 +181,23 @@ module Sisimai
198
181
  end
199
182
  end
200
183
  end
201
-
202
184
  return nil if recipients == 0
203
185
  require 'sisimai/string'
204
- require 'sisimai/smtp/status'
205
186
 
206
187
  dscontents.map do |e|
207
- e['agent'] = Sisimai::MTA::MessagingServer.smtpagent
208
-
209
- if mhead['received'].size > 0
210
- # Get localhost and remote host name from Received header.
211
- r0 = mhead['received']
212
- %w|lhost rhost|.each { |a| e[a] ||= '' }
213
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
214
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
215
- end
188
+ e['agent'] = Sisimai::MTA::MessagingServer.smtpagent
216
189
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
217
190
 
218
191
  ReFailure.each_key do |r|
219
192
  # Verify each regular expression of session errors
220
193
  next unless e['diagnosis'] =~ ReFailure[r]
221
- e['reason'] = r
194
+ e['reason'] = r.to_s
222
195
  break
223
196
  end
224
-
225
- if e['status'].nil? || e['status'].empty? || e['status'] =~ /\A\d[.]0[.]0\z/
226
- # There is no value of Status header or the value is 5.0.0, 4.0.0
227
- pseudostatus = Sisimai::SMTP::Status.find(e['diagnosis'])
228
- e['status'] = pseudostatus if pseudostatus.size > 0
229
- end
230
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
231
197
  e.each_key { |a| e[a] ||= '' }
232
198
  end
233
199
 
200
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
234
201
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
235
202
  end
236
203