sisimai 4.16.0-java → 4.17.0-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sisimai might be problematic. Click here for more details.

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
@@ -36,8 +36,6 @@ module Sisimai
36
36
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
37
37
  }
38
38
  Indicators = Sisimai::MTA.INDICATORS
39
- LongFields = Sisimai::RFC5322.LONGFIELDS
40
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
41
39
 
42
40
  def description; return 'Postfix'; end
43
41
  def smtpagent; return 'Postfix'; end
@@ -60,12 +58,11 @@ module Sisimai
60
58
  return nil unless mbody
61
59
  return nil unless mhead['subject'] =~ Re0[:subject]
62
60
 
63
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
61
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
64
62
  hasdivided = mbody.split("\n")
65
63
  havepassed = ['']
66
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
67
- rfc822part = '' # (String) message/rfc822-headers part
68
- previousfn = '' # (String) Previous field name
64
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
65
+ blanklines = 0 # (Integer) The number of blank lines
69
66
  readcursor = 0 # (Integer) Points the current cursor position
70
67
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
71
68
  commandset = [] # (Array) ``in reply to * command'' list
@@ -79,12 +76,13 @@ module Sisimai
79
76
 
80
77
  hasdivided.each do |e|
81
78
  # Save the current line for the next loop
82
- havepassed << e; p = havepassed[-2]
79
+ havepassed << e
80
+ p = havepassed[-2]
83
81
 
84
82
  if readcursor == 0
85
83
  # Beginning of the bounce message or delivery status part
86
84
  if e =~ Re1[:begin]
87
- readcursor |= Indicators[:'deliverystatus']
85
+ readcursor |= Indicators[:deliverystatus]
88
86
  next
89
87
  end
90
88
  end
@@ -99,30 +97,16 @@ module Sisimai
99
97
 
100
98
  if readcursor & Indicators[:'message-rfc822'] > 0
101
99
  # After "message/rfc822"
102
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.*\z/)
103
- # Get required headers only
104
- lhs = cv[1].downcase
105
- previousfn = ''
106
- next unless RFC822Head.key?(lhs)
107
-
108
- previousfn = lhs
109
- rfc822part += e + "\n"
110
-
111
- elsif e =~ /\A[ \t]+/
112
- # Continued line from the previous line
113
- next if rfc822next[previousfn]
114
- rfc822part += e + "\n" if LongFields.key?(previousfn)
115
-
116
- else
117
- # Check the end of headers in rfc822 part
118
- next unless LongFields.key?(previousfn)
119
- next unless e.empty?
120
- rfc822next[previousfn] = true
100
+ if e.empty?
101
+ blanklines += 1
102
+ break if blanklines > 1
103
+ next
121
104
  end
105
+ rfc822list << e
122
106
 
123
107
  else
124
108
  # Before "message/rfc822"
125
- next if readcursor & Indicators[:'deliverystatus'] == 0
109
+ next if readcursor & Indicators[:deliverystatus] == 0
126
110
  next if e.empty?
127
111
 
128
112
  if connvalues == connheader.keys.size
@@ -145,7 +129,7 @@ module Sisimai
145
129
  recipients += 1
146
130
 
147
131
  elsif cv = e.match(/\A[Xx]-[Aa]ctual-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/) ||
148
- cv = e.match(/\A[Oo]riginal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
132
+ e.match(/\A[Oo]riginal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
149
133
  # X-Actual-Recipient: RFC822; kijitora@example.co.jp
150
134
  # Original-Recipient: rfc822;kijitora@example.co.jp
151
135
  v['alias'] = cv[1]
@@ -222,7 +206,7 @@ module Sisimai
222
206
 
223
207
  elsif cv = e.match(/\A(X-Postfix-Sender):[ ]*rfc822;[ ]*(.+)\z/)
224
208
  # X-Postfix-Sender: rfc822; shironeko@example.org
225
- rfc822part += sprintf('%s: %s\n', cv[1], cv[2])
209
+ rfc822list << sprintf('%s: %s', cv[1], cv[2])
226
210
 
227
211
  else
228
212
  # Alternative error message and recipient
@@ -279,24 +263,10 @@ module Sisimai
279
263
  end
280
264
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
281
265
  e['spec'] ||= 'SMTP' if e['diagnosis'] =~ /host .+ said:/
282
- e['status'] ||= ''
283
-
284
- if mhead['received'].size > 0
285
- # Get localhost and remote host name from Received header.
286
- r0 = mhead['received']
287
- %w|lhost rhost|.each { |a| e[a] ||= '' }
288
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
289
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
290
- end
291
-
292
- if e['status'].empty? || e['status'] =~ /\A\d[.]0[.]0\z/
293
- # There is no value of Status header or the value is 5.0.0, 4.0.0
294
- r = Sisimai::SMTP::Status.find(e['diagnosis'])
295
- e['status'] = r if r.size > 0
296
- end
297
266
  e.each_key { |a| e[a] ||= '' }
298
267
  end
299
268
 
269
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
300
270
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
301
271
  end
302
272
 
@@ -29,21 +29,21 @@ module Sisimai
29
29
  ReSMTP = {
30
30
  # Error text regular expressions which defined in qmail-remote.c
31
31
  # qmail-remote.c:225| if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
32
- 'conn' => %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]greeting[ ]failed[.]/x,
32
+ conn: %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]greeting[ ]failed[.]/x,
33
33
  # qmail-remote.c:231| if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
34
- 'ehlo' => %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]my[ ]name[ ]was[ ]rejected[.]/x,
34
+ ehlo: %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]my[ ]name[ ]was[ ]rejected[.]/x,
35
35
  # qmail-remote.c:238| if (code >= 500) quit("DConnected to "," but sender was rejected");
36
36
  # reason = rejected
37
- 'mail' => %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]sender[ ]was[ ]rejected[.]/x,
37
+ mail: %r/(?:Error:)?Connected[ ]to[ ].+[ ]but[ ]sender[ ]was[ ]rejected[.]/x,
38
38
  # qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
39
39
  # qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
40
40
  # reason = userunknown
41
- 'rcpt' => %r/(?:Error:)?.+[ ]does[ ]not[ ]like[ ]recipient[.]/x,
41
+ rcpt: %r/(?:Error:)?.+[ ]does[ ]not[ ]like[ ]recipient[.]/x,
42
42
  # qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
43
43
  # qmail-remote.c:266| if (code >= 400) quit("Z"," failed on DATA command");
44
44
  # qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
45
45
  # qmail-remote.c:272| if (code >= 400) quit("Z"," failed after I sent the message");
46
- 'data' => %r{(?:
46
+ data: %r{(?:
47
47
  (?:Error:)?.+[ ]failed[ ]on[ ]DATA[ ]command[.]
48
48
  |(?:Error:)?.+[ ]failed[ ]after[ ]I[ ]sent[ ]the[ ]message[.]
49
49
  )
@@ -58,10 +58,10 @@ module Sisimai
58
58
  }x
59
59
  ReLDAP = {
60
60
  # qmail-ldap-1.03-20040101.patch:19817 - 19866
61
- 'suspend' => %r/Mailaddress is administrative?le?y disabled/, # 5.2.1
62
- 'userunknown' => %r/[Ss]orry, no mailbox here by that name/, # 5.1.1
63
- 'exceedlimit' => %r/The message exeeded the maximum size the user accepts/, # 5.2.3
64
- 'systemerror' => %r{(?>
61
+ suspend: %r/Mailaddress is administrative?le?y disabled/, # 5.2.1
62
+ userunknown: %r/[Ss]orry, no mailbox here by that name/, # 5.1.1
63
+ exceedlimit: %r/The message exeeded the maximum size the user accepts/, # 5.2.3
64
+ systemerror: %r{(?>
65
65
  Automatic[ ]homedir[ ]creator[ ]crashed # 4.3.0
66
66
  |Illegal[ ]value[ ]in[ ]LDAP[ ]attribute # 5.3.5
67
67
  |LDAP[ ]attribute[ ]is[ ]not[ ]given[ ]but[ ]mandatory # 5.3.5
@@ -89,40 +89,37 @@ module Sisimai
89
89
  ReFailure = {
90
90
  # qmail-local.c:589| strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)");
91
91
  # qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
92
- 'userunknown' => %r{(?:
92
+ userunknown: %r{(?:
93
93
  no[ ]mailbox[ ]here[ ]by[ ]that[ ]name
94
94
  |[ ]does[ ]not[ ]like[ ]recipient[.]
95
95
  )
96
96
  }x,
97
97
  # error_str.c:192| X(EDQUOT,"disk quota exceeded")
98
- 'mailboxfull' => %r/disk[ ]quota[ ]exceeded/x,
98
+ mailboxfull: %r/disk[ ]quota[ ]exceeded/x,
99
99
  # qmail-qmtpd.c:233| ... result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)";
100
100
  # qmail-smtpd.c:391| ... out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return;
101
- 'mesgtoobig' => %r/Message[ ]size[ ]exceeds[ ]fixed[ ]maximum[ ]message[ ]size:/x,
101
+ mesgtoobig: %r/Message[ ]size[ ]exceeds[ ]fixed[ ]maximum[ ]message[ ]size:/x,
102
102
  # qmail-remote.c:68| Sorry, I couldn't find any host by that name. (#4.1.2)\n"); zerodie();
103
103
  # qmail-remote.c:78| Sorry, I couldn't find any host named ");
104
- 'hostunknown' => %r/\ASorry[,][ ]I[ ]couldn[']t[ ]find[ ]any[ ]host[ ]/x,
105
- 'systemerror' => %r{(?>
104
+ hostunknown: %r/\ASorry[,][ ]I[ ]couldn[']t[ ]find[ ]any[ ]host[ ]/x,
105
+ systemerror: %r{(?>
106
106
  bad[ ]interpreter:[ ]No[ ]such[ ]file[ ]or[ ]directory
107
107
  |system[ ]error
108
108
  |Unable[ ]to\b
109
109
  )
110
110
  }x,
111
- 'networkerror' => %r{Sorry(?:
111
+ networkerror: %r{Sorry(?:
112
112
  [,][ ]I[ ]wasn[']t[ ]able[ ]to[ ]establish[ ]an[ ]SMTP[ ]connection
113
113
  |[,][ ]I[ ]couldn[']t[ ]find[ ]a[ ]mail[ ]exchanger[ ]or[ ]IP[ ]address
114
114
  |[.][ ]Although[ ]I[']m[ ]listed[ ]as[ ]a[ ]best[-]preference[ ]MX[ ]
115
115
  or[ ]A[ ]for[ ]that[ ]host
116
116
  )
117
117
  }x,
118
- 'systemfull' => %r/Requested action not taken: mailbox unavailable [(]not enough free space[)]/,
118
+ systemfull: %r/Requested action not taken: mailbox unavailable [(]not enough free space[)]/,
119
119
  }
120
120
  # qmail-send.c:922| ... (&dline[c],"I'm not going to try again; this message has been in the queue too long.\n")) nomem();
121
121
  ReDelayed = %r/this[ ]message[ ]has[ ]been[ ]in[ ]the[ ]queue[ ]too[ ]long[.]\z/x
122
-
123
122
  Indicators = Sisimai::MTA.INDICATORS
124
- LongFields = Sisimai::RFC5322.LONGFIELDS
125
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
126
123
 
127
124
  def description; return 'qmail'; end
128
125
  def smtpagent; return 'qmail'; end
@@ -153,11 +150,10 @@ module Sisimai
153
150
  match += 1 if mhead['received'].find { |a| a =~ Re0[:received] }
154
151
  return nil if match == 0
155
152
 
156
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
153
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
157
154
  hasdivided = mbody.split("\n")
158
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
159
- rfc822part = '' # (String) message/rfc822-headers part
160
- previousfn = '' # (String) Previous field name
155
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
156
+ blanklines = 0 # (Integer) The number of blank lines
161
157
  readcursor = 0 # (Integer) Points the current cursor position
162
158
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
163
159
  v = nil
@@ -166,7 +162,7 @@ module Sisimai
166
162
  if readcursor == 0
167
163
  # Beginning of the bounce message or delivery status part
168
164
  if e =~ Re1[:begin]
169
- readcursor |= Indicators[:'deliverystatus']
165
+ readcursor |= Indicators[:deliverystatus]
170
166
  next
171
167
  end
172
168
  end
@@ -181,30 +177,16 @@ module Sisimai
181
177
 
182
178
  if readcursor & Indicators[:'message-rfc822'] > 0
183
179
  # After "message/rfc822"
184
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
185
- # Get required headers only
186
- lhs = cv[1].downcase
187
- previousfn = ''
188
- next unless RFC822Head.key?(lhs)
189
-
190
- previousfn = lhs
191
- rfc822part += e + "\n"
192
-
193
- elsif e =~ /\A[ \t]+/
194
- # Continued line from the previous line
195
- next if rfc822next[previousfn]
196
- rfc822part += e + "\n" if LongFields.key?(previousfn)
197
-
198
- else
199
- # Check the end of headers in rfc822 part
200
- next unless LongFields.key?(previousfn)
201
- next unless e.empty?
202
- rfc822next[previousfn] = true
180
+ if e.empty?
181
+ blanklines += 1
182
+ break if blanklines > 1
183
+ next
203
184
  end
185
+ rfc822list << e
204
186
 
205
187
  else
206
188
  # Before "message/rfc822"
207
- next if readcursor & Indicators[:'deliverystatus'] == 0
189
+ next if readcursor & Indicators[:deliverystatus] == 0
208
190
  next if e.empty?
209
191
 
210
192
  # <kijitora@example.jp>:
@@ -243,16 +225,7 @@ module Sisimai
243
225
  require 'sisimai/smtp/status'
244
226
 
245
227
  dscontents.map do |e|
246
- # Set default values if each value is empty.
247
- e['agent'] = Sisimai::MTA::Qmail.smtpagent
248
-
249
- if mhead['received'].size > 0
250
- # Get localhost and remote host name from Received header.
251
- r0 = mhead['received']
252
- %w|lhost rhost|.each { |a| e[a] ||= '' }
253
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
254
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
255
- end
228
+ e['agent'] = Sisimai::MTA::Qmail.smtpagent
256
229
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
257
230
 
258
231
  unless e['command']
@@ -260,7 +233,7 @@ module Sisimai
260
233
  ReSMTP.each_key do |r|
261
234
  # Verify each regular expression of SMTP commands
262
235
  next unless e['diagnosis'] =~ ReSMTP[r]
263
- e['command'] = r.upcase
236
+ e['command'] = r.to_s.upcase
264
237
  break
265
238
  end
266
239
 
@@ -295,12 +268,12 @@ module Sisimai
295
268
  if e['alterrors']
296
269
  # Check the value of "alterrors"
297
270
  next unless e['alterrors'] =~ ReFailure[r]
298
- e['reason'] = r
271
+ e['reason'] = r.to_s
299
272
  end
300
273
  break if e['reason']
301
274
 
302
275
  next unless e['diagnosis'] =~ ReFailure[r]
303
- e['reason'] = r
276
+ e['reason'] = r.to_s
304
277
  break
305
278
  end
306
279
 
@@ -308,7 +281,7 @@ module Sisimai
308
281
  ReLDAP.each_key do |r|
309
282
  # Verify each regular expression of LDAP errors
310
283
  next unless e['diagnosis'] =~ ReLDAP[r]
311
- e['reason'] = r
284
+ e['reason'] = r.to_s
312
285
  break
313
286
  end
314
287
  end
@@ -320,11 +293,10 @@ module Sisimai
320
293
  end
321
294
 
322
295
  e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
323
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
324
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
325
296
  e.each_key { |a| e[a] ||= '' }
326
297
  end
327
298
 
299
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
328
300
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
329
301
  end
330
302
 
@@ -24,8 +24,6 @@ module Sisimai
24
24
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
25
25
  }
26
26
  Indicators = Sisimai::MTA.INDICATORS
27
- LongFields = Sisimai::RFC5322.LONGFIELDS
28
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
29
27
 
30
28
  def description; return 'V8Sendmail: /usr/sbin/sendmail'; end
31
29
  def smtpagent; return 'Sendmail'; end
@@ -54,12 +52,11 @@ module Sisimai
54
52
  return nil unless mhead['from'] =~ Re0[:from]
55
53
  end
56
54
 
57
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
55
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
58
56
  hasdivided = mbody.split("\n")
59
57
  havepassed = ['']
60
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
61
- rfc822part = '' # (String) message/rfc822-headers part
62
- previousfn = '' # (String) Previous field name
58
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
59
+ blanklines = 0 # (Integer) The number of blank lines
63
60
  readcursor = 0 # (Integer) Points the current cursor position
64
61
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
65
62
  commandtxt = '' # (String) SMTP Command name begin with the string '>>>'
@@ -75,12 +72,13 @@ module Sisimai
75
72
 
76
73
  hasdivided.each do |e|
77
74
  # Save the current line for the next loop
78
- havepassed << e; p = havepassed[-2]
75
+ havepassed << e
76
+ p = havepassed[-2]
79
77
 
80
78
  if readcursor == 0
81
79
  # Beginning of the bounce message or delivery status part
82
80
  if e =~ Re1[:begin]
83
- readcursor |= Indicators[:'deliverystatus']
81
+ readcursor |= Indicators[:deliverystatus]
84
82
  next
85
83
  end
86
84
  end
@@ -95,30 +93,16 @@ module Sisimai
95
93
 
96
94
  if readcursor & Indicators[:'message-rfc822'] > 0
97
95
  # 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
96
+ if e.empty?
97
+ blanklines += 1
98
+ break if blanklines > 1
99
+ next
117
100
  end
101
+ rfc822list << e
118
102
 
119
103
  else
120
104
  # Before "message/rfc822"
121
- next if readcursor & Indicators[:'deliverystatus'] == 0
105
+ next if readcursor & Indicators[:deliverystatus] == 0
122
106
  next if e.empty?
123
107
 
124
108
  if connvalues == connheader.keys.size
@@ -255,7 +239,6 @@ module Sisimai
255
239
  end
256
240
  end
257
241
  end
258
-
259
242
  return nil if recipients == 0
260
243
  require 'sisimai/string'
261
244
 
@@ -263,15 +246,6 @@ module Sisimai
263
246
  # Set default values if each value is empty.
264
247
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
265
248
 
266
- if mhead['received'].size > 0
267
- # Get localhost and remote host name from Received header.
268
- r0 = mhead['received']
269
- %w|lhost rhost|.each { |a| e[a] ||= '' }
270
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
271
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
272
- end
273
-
274
- e['spec'] ||= 'SMTP'
275
249
  e['agent'] = Sisimai::MTA::Sendmail.smtpagent
276
250
  e['command'] ||= commandtxt
277
251
  if e['command'].empty?
@@ -308,6 +282,7 @@ module Sisimai
308
282
  e.each_key { |a| e[a] ||= '' }
309
283
  end
310
284
 
285
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
311
286
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
312
287
  end
313
288
 
@@ -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 'WebSense SurfControl'; end
26
24
  def smtpagent; return 'SurfControl'; end
@@ -48,24 +46,24 @@ module Sisimai
48
46
  return nil unless mhead['x-mailer']
49
47
  return nil unless mhead['x-mailer'] =~ Re0[:'x-mailer']
50
48
 
51
- dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
49
+ dscontents = [Sisimai::MTA.DELIVERYSTATUS]
52
50
  hasdivided = mbody.split("\n")
53
- havepassed = [''];
54
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
55
- rfc822part = '' # (String) message/rfc822-headers part
56
- previousfn = '' # (String) Previous field name
51
+ havepassed = ['']
52
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
53
+ blanklines = 0 # (Integer) The number of blank lines
57
54
  readcursor = 0 # (Integer) Points the current cursor position
58
55
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
59
56
  v = nil
60
57
 
61
58
  hasdivided.each do |e|
62
59
  # Save the current line for the next loop
63
- havepassed << e; p = havepassed[-2]
60
+ havepassed << e
61
+ p = havepassed[-2]
64
62
 
65
63
  if readcursor == 0
66
64
  # Beginning of the bounce message or delivery status part
67
65
  if e =~ Re1[:begin]
68
- readcursor |= Indicators[:'deliverystatus']
66
+ readcursor |= Indicators[:deliverystatus]
69
67
  next
70
68
  end
71
69
  end
@@ -80,30 +78,16 @@ module Sisimai
80
78
 
81
79
  if readcursor & Indicators[:'message-rfc822'] > 0
82
80
  # 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
81
+ if e.empty?
82
+ blanklines += 1
83
+ break if blanklines > 1
84
+ next
102
85
  end
86
+ rfc822list << e
103
87
 
104
88
  else
105
89
  # Before "message/rfc822"
106
- next if readcursor & Indicators[:'deliverystatus'] == 0
90
+ next if readcursor & Indicators[:deliverystatus] == 0
107
91
  next if e.empty?
108
92
 
109
93
  # Your message could not be sent.
@@ -160,29 +144,16 @@ module Sisimai
160
144
  end
161
145
  end
162
146
  end
163
-
164
147
  return nil if recipients == 0
165
148
  require 'sisimai/string'
166
- require 'sisimai/smtp/status'
167
149
 
168
150
  dscontents.map do |e|
169
- e['agent'] = Sisimai::MTA::SurfControl.smtpagent
170
-
171
- if mhead['received'].size > 0
172
- # Get localhost and remote host name from Received header.
173
- r0 = mhead['received']
174
- %w|lhost rhost|.each { |a| e[a] ||= '' }
175
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
176
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
177
- end
151
+ e['agent'] = Sisimai::MTA::SurfControl.smtpagent
178
152
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
179
-
180
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
181
- e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
182
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
183
153
  e.each_key { |a| e[a] ||= '' }
184
154
  end
185
155
 
156
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
186
157
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
187
158
  end
188
159