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
@@ -28,8 +28,6 @@ module Sisimai
28
28
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
29
29
  }
30
30
  Indicators = Sisimai::MTA.INDICATORS
31
- LongFields = Sisimai::RFC5322.LONGFIELDS
32
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
33
31
 
34
32
  def description; return 'Module description'; end
35
33
  def smtpagent; return 'Module name'; end
@@ -64,11 +62,10 @@ module Sisimai
64
62
 
65
63
  # 2. Parse message body(mbody) of the bounce message. See some modules
66
64
  # in lib/sisimai/mta or lib/sisimai/msp directory to implement codes.
67
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
65
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
68
66
  hasdivided = mbody.split("\n")
69
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
70
- rfc822part = '' # (String) message/rfc822-headers part
71
- previousfn = '' # (String) Previous field name
67
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
68
+ blanklines = 0 # (Integer) The number of blank lines
72
69
  readcursor = 0 # (Integer) Points the current cursor position
73
70
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
74
71
 
@@ -76,7 +73,7 @@ module Sisimai
76
73
  if readcursor == 0
77
74
  # Beginning of the bounce message or delivery status part
78
75
  if e =~ Re1[:begin]
79
- readcursor |= Indicators[:'deliverystatus']
76
+ readcursor |= Indicators[:deliverystatus]
80
77
  next
81
78
  end
82
79
  end
@@ -91,30 +88,16 @@ module Sisimai
91
88
 
92
89
  if readcursor & Indicators[:'message-rfc822'] > 0
93
90
  # After "message/rfc822"
94
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
95
- # Get required headers only
96
- lhs = cv[1].downcase
97
- previousfn = ''
98
- next unless RFC822Head.key?(lhs)
99
-
100
- previousfn = lhs
101
- rfc822part += e + "\n"
102
-
103
- elsif e =~ /\A[ \t]+/
104
- # Continued line from the previous line
105
- next if rfc822next[previousfn]
106
- rfc822part += e + "\n" if LongFields.key?(previousfn)
107
-
108
- else
109
- # Check the end of headers in rfc822 part
110
- next unless LongFields.key?(previousfn)
111
- next unless e.empty?
112
- rfc822next[previousfn] = true
91
+ if e.empty?
92
+ blanklines += 1
93
+ break if blanklines > 1
94
+ next
113
95
  end
96
+ rfc822list << e
114
97
 
115
98
  else
116
99
  # Before "message/rfc822"
117
- next if readcursor & Indicators[:'deliverystatus'] == 0
100
+ next if readcursor & Indicators[:deliverystatus] == 0
118
101
  next if e.empty?
119
102
 
120
103
  end
@@ -129,15 +112,16 @@ module Sisimai
129
112
  dscontents[0]['agent'] = Sisimai::MTA::UserDefined.smtpagent
130
113
  recipients = 1 if dscontents[0]['recipient']
131
114
 
132
- rfc822part += 'From: shironeko@example.org' + "\n"
133
- rfc822part += 'Subject: Nyaaan' + "\n"
134
- rfc822part += 'Message-Id: 000000000000@example.jp' + "\n"
115
+ rfc822list << 'From: shironeko@example.org'
116
+ rfc822list << 'Subject: Nyaaan'
117
+ rfc822list << 'Message-Id: 000000000000@example.jp'
135
118
 
136
119
  # 3. Return undef when there is no recipient address which is failed to
137
120
  # delivery in the bounce message
138
121
  return nil if recipients == 0
139
122
 
140
123
  # 4. Return the following variable.
124
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
141
125
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
142
126
  end
143
127
 
@@ -39,8 +39,6 @@ module Sisimai
39
39
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
40
40
  }
41
41
  Indicators = Sisimai::MTA.INDICATORS
42
- LongFields = Sisimai::RFC5322.LONGFIELDS
43
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
44
42
 
45
43
  def description; return 'Sendmail version 5'; end
46
44
  def smtpagent; return 'V5sendmail'; end
@@ -63,11 +61,10 @@ module Sisimai
63
61
  return nil unless mbody
64
62
  return nil unless mhead['subject'] =~ Re0[:subject]
65
63
 
66
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
64
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
67
65
  hasdivided = mbody.split("\n")
68
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
69
- rfc822part = '' # (String) message/rfc822-headers part
70
- previousfn = '' # (String) Previous field name
66
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
67
+ blanklines = 0 # (Integer) The number of blank lines
71
68
  readcursor = 0 # (Integer) Points the current cursor position
72
69
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
73
70
  responding = [] # (Array) Responses from remote server
@@ -80,7 +77,7 @@ module Sisimai
80
77
  if readcursor == 0
81
78
  # Beginning of the bounce message or delivery status part
82
79
  if e =~ Re1[:begin]
83
- readcursor |= Indicators[:'deliverystatus']
80
+ readcursor |= Indicators[:deliverystatus]
84
81
  next
85
82
  end
86
83
  end
@@ -95,30 +92,16 @@ module Sisimai
95
92
 
96
93
  if readcursor & Indicators[:'message-rfc822'] > 0
97
94
  # After "message/rfc822"
98
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
99
- # Get required headers only
100
- lhs = cv[1].downcase
101
- previousfn = ''
102
- next unless RFC822Head.key?(lhs)
103
-
104
- previousfn = lhs
105
- rfc822part += e + "\n"
106
-
107
- elsif e =~ /\A[ \t]+/
108
- # Continued line from the previous line
109
- next if rfc822next[previousfn]
110
- rfc822part += e + "\n" if LongFields.key?(previousfn)
111
-
112
- else
113
- # Check the end of headers in rfc822 part
114
- next unless LongFields.key?(previousfn)
115
- next unless e.empty?
116
- rfc822next[previousfn] = true
95
+ if e.empty?
96
+ blanklines += 1
97
+ break if blanklines > 1
98
+ next
117
99
  end
100
+ rfc822list << e
118
101
 
119
102
  else
120
103
  # Before "message/rfc822"
121
- next if readcursor & Indicators[:'deliverystatus'] == 0
104
+ next if readcursor & Indicators[:deliverystatus] == 0
122
105
  next if e.empty?
123
106
 
124
107
  # ----- Transcript of session follows -----
@@ -178,10 +161,13 @@ module Sisimai
178
161
 
179
162
  if recipients == 0
180
163
  # Get the recipient address from the original message
181
- if cv = rfc822part.match(/^To: (.+)$/m)
182
- # The value of To: header in the original message
183
- dscontents[0]['recipient'] = Sisimai::Address.s3s4(cv[1])
184
- recipients = 1
164
+ rfc822list.each do |e|
165
+ if cv = e.match(/^To: (.+)$/m)
166
+ # The value of To: header in the original message
167
+ dscontents[0]['recipient'] = Sisimai::Address.s3s4(cv[1])
168
+ recipients = 1
169
+ break
170
+ end
185
171
  end
186
172
  end
187
173
  return nil if recipients == 0
@@ -189,15 +175,6 @@ module Sisimai
189
175
 
190
176
  dscontents.map do |e|
191
177
  errorindex += 1
192
-
193
- if mhead['received'].size > 0
194
- # Get localhost and remote host name from Received header.
195
- r0 = mhead['received']
196
- %w|lhost rhost|.each { |a| e[a] ||= '' }
197
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
198
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
199
- end
200
- e['spec'] ||= 'SMTP'
201
178
  e['agent'] = Sisimai::MTA::V5sendmail.smtpagent
202
179
  e['command'] = commandset[errorindex] || ''
203
180
 
@@ -222,6 +199,7 @@ module Sisimai
222
199
  e.each_key { |a| e[a] ||= '' }
223
200
  end
224
201
 
202
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
225
203
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
226
204
  end
227
205
 
@@ -18,8 +18,6 @@ module Sisimai
18
18
  :rfc822 => %r/\AReceived: from \d+[.]\d+[.]\d+[.]\d/,
19
19
  }
20
20
  Indicators = Sisimai::MTA.INDICATORS
21
- LongFields = Sisimai::RFC5322.LONGFIELDS
22
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
23
21
 
24
22
  def description; return 'Unknown MTA #1'; end
25
23
  def smtpagent; return 'X1'; end
@@ -43,11 +41,10 @@ module Sisimai
43
41
  return nil unless mhead['subject'] =~ Re0[:subject]
44
42
  return nil unless mhead['from'] =~ Re0[:from]
45
43
 
46
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
44
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
47
45
  hasdivided = mbody.split("\n")
48
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
49
- rfc822part = '' # (String) message/rfc822-headers part
50
- previousfn = '' # (String) Previous field name
46
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
47
+ blanklines = 0 # (Integer) The number of blank lines
51
48
  readcursor = 0 # (Integer) Points the current cursor position
52
49
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
53
50
  datestring = '' # (String) Date string
@@ -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
  # The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
@@ -123,29 +106,17 @@ module Sisimai
123
106
  end
124
107
  end
125
108
  end
126
-
127
109
  return nil if recipients == 0
128
110
  require 'sisimai/string'
129
- require 'sisimai/smtp/status'
130
111
 
131
112
  dscontents.map do |e|
132
- e['agent'] = Sisimai::MTA::X1.smtpagent
133
-
134
- if mhead['received'].size > 0
135
- # Get localhost and remote host name from Received header.
136
- r0 = mhead['received']
137
- %w|lhost rhost|.each { |a| e[a] ||= '' }
138
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
139
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
140
- end
113
+ e['agent'] = Sisimai::MTA::X1.smtpagent
141
114
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
142
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
143
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
144
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
145
115
  e['date'] = datestring || ''
146
116
  e.each_key { |a| e[a] ||= '' }
147
117
  end
148
118
 
119
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
149
120
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
150
121
  end
151
122
 
@@ -22,8 +22,6 @@ module Sisimai
22
22
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
23
23
  }
24
24
  Indicators = Sisimai::MTA.INDICATORS
25
- LongFields = Sisimai::RFC5322.LONGFIELDS
26
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
27
25
 
28
26
  def description; return 'Unknown MTA #2'; end
29
27
  def smtpagent; return 'X2'; end
@@ -47,11 +45,10 @@ module Sisimai
47
45
  return nil unless mhead['subject'] =~ Re0[:subject]
48
46
  return nil unless mhead['from'] =~ Re0[:from]
49
47
 
50
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
48
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
51
49
  hasdivided = mbody.split("\n")
52
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
53
- rfc822part = '' # (String) message/rfc822-headers part
54
- previousfn = '' # (String) Previous field name
50
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
51
+ blanklines = 0 # (Integer) The number of blank lines
55
52
  readcursor = 0 # (Integer) Points the current cursor position
56
53
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
57
54
  v = nil
@@ -60,7 +57,7 @@ module Sisimai
60
57
  if readcursor == 0
61
58
  # Beginning of the bounce message or delivery status part
62
59
  if e =~ Re1[:begin]
63
- readcursor |= Indicators[:'deliverystatus']
60
+ readcursor |= Indicators[:deliverystatus]
64
61
  next
65
62
  end
66
63
  end
@@ -75,30 +72,16 @@ module Sisimai
75
72
 
76
73
  if readcursor & Indicators[:'message-rfc822'] > 0
77
74
  # After "message/rfc822"
78
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
79
- # Get required headers only
80
- lhs = cv[1].downcase
81
- previousfn = ''
82
- next unless RFC822Head.key?(lhs)
83
-
84
- previousfn = lhs
85
- rfc822part += e + "\n"
86
-
87
- elsif e =~ /\A[ \t]+/
88
- # Continued line from the previous line
89
- next if rfc822next[previousfn]
90
- rfc822part += e + "\n" if LongFields.key?(previousfn)
91
-
92
- else
93
- # Check the end of headers in rfc822 part
94
- next unless LongFields.key?(previousfn)
95
- next unless e.empty?
96
- rfc822next[previousfn] = true
75
+ if e.empty?
76
+ blanklines += 1
77
+ break if blanklines > 2
78
+ next
97
79
  end
80
+ rfc822list << e
98
81
 
99
82
  else
100
83
  # Before "message/rfc822"
101
- next if readcursor & Indicators[:'deliverystatus'] == 0
84
+ next if readcursor & Indicators[:deliverystatus] == 0
102
85
  next if e.empty?
103
86
 
104
87
  # Message from example.com.
@@ -125,28 +108,16 @@ module Sisimai
125
108
  end
126
109
  end
127
110
  end
128
-
129
111
  return nil if recipients == 0
130
112
  require 'sisimai/string'
131
- require 'sisimai/smtp/status'
132
113
 
133
114
  dscontents.map do |e|
134
- e['agent'] = Sisimai::MTA::X2.smtpagent
135
-
136
- if mhead['received'].size > 0
137
- # Get localhost and remote host name from Received header.
138
- r0 = mhead['received']
139
- %w|lhost rhost|.each { |a| e[a] ||= '' }
140
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
141
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
142
- end
115
+ e['agent'] = Sisimai::MTA::X2.smtpagent
143
116
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
144
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
145
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
146
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
147
117
  e.each_key { |a| e[a] ||= '' }
148
118
  end
149
119
 
120
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
150
121
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
151
122
  end
152
123
 
@@ -18,8 +18,6 @@ module Sisimai
18
18
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
19
19
  }
20
20
  Indicators = Sisimai::MTA.INDICATORS
21
- LongFields = Sisimai::RFC5322.LONGFIELDS
22
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
23
21
 
24
22
  def description; return 'Unknown MTA #3'; end
25
23
  def smtpagent; return 'X3'; end
@@ -43,11 +41,10 @@ module Sisimai
43
41
  return nil unless mhead['subject'] =~ Re0[:subject]
44
42
  return nil unless mhead['from'] =~ Re0[:from]
45
43
 
46
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
44
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
47
45
  hasdivided = mbody.split("\n")
48
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
49
- rfc822part = '' # (String) message/rfc822-headers part
50
- previousfn = '' # (String) Previous field name
46
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
47
+ blanklines = 0 # (Integer) The number of blank lines
51
48
  readcursor = 0 # (Integer) Points the current cursor position
52
49
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
53
50
  v = nil
@@ -56,7 +53,7 @@ module Sisimai
56
53
  if readcursor == 0
57
54
  # Beginning of the bounce message or delivery status part
58
55
  if e =~ Re1[:begin]
59
- readcursor |= Indicators[:'deliverystatus']
56
+ readcursor |= Indicators[:deliverystatus]
60
57
  next
61
58
  end
62
59
  end
@@ -71,30 +68,16 @@ module Sisimai
71
68
 
72
69
  if readcursor & Indicators[:'message-rfc822'] > 0
73
70
  # After "message/rfc822"
74
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
75
- # Get required headers only
76
- lhs = cv[1].downcase
77
- previousfn = ''
78
- next unless RFC822Head.key?(lhs)
79
-
80
- previousfn = lhs
81
- rfc822part += e + "\n"
82
-
83
- elsif e =~ /\A[ \t]+/
84
- # Continued line from the previous line
85
- next if rfc822next[previousfn]
86
- rfc822part += e + "\n" if LongFields.key?(previousfn)
87
-
88
- else
89
- # Check the end of headers in rfc822 part
90
- next unless LongFields.key?(previousfn)
91
- next unless e.empty?
92
- rfc822next[previousfn] = true
71
+ if e.empty?
72
+ blanklines += 1
73
+ break if blanklines > 1
74
+ next
93
75
  end
76
+ rfc822list << e
94
77
 
95
78
  else
96
79
  # Before "message/rfc822"
97
- next if readcursor & Indicators[:'deliverystatus'] == 0
80
+ next if readcursor & Indicators[:deliverystatus] == 0
98
81
  next if e.empty?
99
82
 
100
83
  # ============================================================================
@@ -144,24 +127,14 @@ module Sisimai
144
127
  require 'sisimai/smtp/status'
145
128
 
146
129
  dscontents.map do |e|
147
- e['agent'] = Sisimai::MTA::X3.smtpagent
148
-
149
- if mhead['received'].size > 0
150
- # Get localhost and remote host name from Received header.
151
- r0 = mhead['received']
152
- %w|lhost rhost|.each { |a| e[a] ||= '' }
153
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
154
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
155
- end
130
+ e['agent'] = Sisimai::MTA::X3.smtpagent
156
131
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
157
132
  e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
158
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
159
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
160
133
  e.each_key { |a| e[a] ||= '' }
161
134
  end
162
135
 
136
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
163
137
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
164
-
165
138
  end
166
139
 
167
140
  end