sisimai 4.25.4 → 4.25.5

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/ChangeLog.md +50 -0
  4. data/README-JA.md +10 -37
  5. data/README.md +10 -37
  6. data/lib/sisimai.rb +15 -64
  7. data/lib/sisimai/address.rb +13 -17
  8. data/lib/sisimai/arf.rb +4 -4
  9. data/lib/sisimai/data.rb +3 -5
  10. data/lib/sisimai/lhost.rb +0 -14
  11. data/lib/sisimai/lhost/activehunter.rb +31 -55
  12. data/lib/sisimai/lhost/amavis.rb +41 -66
  13. data/lib/sisimai/lhost/amazonses.rb +189 -235
  14. data/lib/sisimai/lhost/amazonworkmail.rb +48 -71
  15. data/lib/sisimai/lhost/aol.rb +49 -75
  16. data/lib/sisimai/lhost/apachejames.rb +60 -83
  17. data/lib/sisimai/lhost/bigfoot.rb +61 -85
  18. data/lib/sisimai/lhost/biglobe.rb +40 -62
  19. data/lib/sisimai/lhost/courier.rb +60 -82
  20. data/lib/sisimai/lhost/domino.rb +50 -76
  21. data/lib/sisimai/lhost/einsundeins.rb +57 -55
  22. data/lib/sisimai/lhost/exchange2003.rb +79 -101
  23. data/lib/sisimai/lhost/exchange2007.rb +66 -74
  24. data/lib/sisimai/lhost/exim.rb +119 -142
  25. data/lib/sisimai/lhost/ezweb.rb +53 -73
  26. data/lib/sisimai/lhost/facebook.rb +49 -75
  27. data/lib/sisimai/lhost/fml.rb +25 -50
  28. data/lib/sisimai/lhost/gmx.rb +55 -79
  29. data/lib/sisimai/lhost/google.rb +39 -66
  30. data/lib/sisimai/lhost/gsuite.rb +74 -94
  31. data/lib/sisimai/lhost/imailserver.rb +34 -67
  32. data/lib/sisimai/lhost/interscanmss.rb +33 -67
  33. data/lib/sisimai/lhost/kddi.rb +30 -52
  34. data/lib/sisimai/lhost/mailfoundry.rb +35 -57
  35. data/lib/sisimai/lhost/mailmarshalsmtp.rb +66 -89
  36. data/lib/sisimai/lhost/mailru.rb +51 -76
  37. data/lib/sisimai/lhost/mcafee.rb +53 -79
  38. data/lib/sisimai/lhost/messagelabs.rb +49 -75
  39. data/lib/sisimai/lhost/messagingserver.rb +91 -113
  40. data/lib/sisimai/lhost/mfilter.rb +50 -70
  41. data/lib/sisimai/lhost/mxlogic.rb +38 -63
  42. data/lib/sisimai/lhost/notes.rb +53 -82
  43. data/lib/sisimai/lhost/office365.rb +64 -81
  44. data/lib/sisimai/lhost/opensmtpd.rb +30 -52
  45. data/lib/sisimai/lhost/outlook.rb +49 -75
  46. data/lib/sisimai/lhost/postfix.rb +116 -117
  47. data/lib/sisimai/lhost/qmail.rb +33 -55
  48. data/lib/sisimai/lhost/receivingses.rb +49 -75
  49. data/lib/sisimai/lhost/sendgrid.rb +68 -203
  50. data/lib/sisimai/lhost/sendmail.rb +101 -125
  51. data/lib/sisimai/lhost/surfcontrol.rb +53 -79
  52. data/lib/sisimai/lhost/userdefined.rb +15 -35
  53. data/lib/sisimai/lhost/v5sendmail.rb +59 -89
  54. data/lib/sisimai/lhost/verizon.rb +75 -124
  55. data/lib/sisimai/lhost/x1.rb +30 -54
  56. data/lib/sisimai/lhost/x2.rb +28 -52
  57. data/lib/sisimai/lhost/x3.rb +44 -68
  58. data/lib/sisimai/lhost/x4.rb +34 -58
  59. data/lib/sisimai/lhost/x5.rb +42 -70
  60. data/lib/sisimai/lhost/yahoo.rb +44 -68
  61. data/lib/sisimai/lhost/yandex.rb +59 -85
  62. data/lib/sisimai/lhost/zoho.rb +54 -78
  63. data/lib/sisimai/mail.rb +5 -9
  64. data/lib/sisimai/mail/maildir.rb +10 -14
  65. data/lib/sisimai/mail/mbox.rb +8 -12
  66. data/lib/sisimai/mail/memory.rb +5 -9
  67. data/lib/sisimai/mail/stdin.rb +7 -11
  68. data/lib/sisimai/mda.rb +2 -2
  69. data/lib/sisimai/message.rb +51 -154
  70. data/lib/sisimai/mime.rb +2 -2
  71. data/lib/sisimai/order.rb +2 -27
  72. data/lib/sisimai/reason.rb +3 -5
  73. data/lib/sisimai/rfc1894.rb +1 -1
  74. data/lib/sisimai/rfc3464.rb +29 -29
  75. data/lib/sisimai/rfc3834.rb +7 -6
  76. data/lib/sisimai/rfc5322.rb +20 -31
  77. data/lib/sisimai/rhost/franceptt.rb +120 -24
  78. data/lib/sisimai/rhost/iua.rb +1 -1
  79. data/lib/sisimai/smtp/error.rb +7 -7
  80. data/lib/sisimai/version.rb +1 -1
  81. data/set-of-emails/maildir/bsd/email-einsundeins-03.eml +66 -0
  82. data/set-of-emails/maildir/bsd/email-exchange2007-05.eml +1469 -0
  83. data/set-of-emails/maildir/bsd/email-exchange2007-06.eml +764 -0
  84. data/set-of-emails/maildir/bsd/email-postfix-64.eml +96 -0
  85. data/set-of-emails/maildir/bsd/rfc3834-03.eml +26 -0
  86. data/set-of-emails/maildir/bsd/rhost-franceptt-04.eml +66 -0
  87. data/set-of-emails/maildir/bsd/rhost-franceptt-05.eml +96 -0
  88. data/set-of-emails/maildir/bsd/rhost-franceptt-06.eml +100 -0
  89. data/set-of-emails/maildir/bsd/rhost-franceptt-07.eml +97 -0
  90. data/set-of-emails/maildir/bsd/rhost-franceptt-08.eml +78 -0
  91. data/set-of-emails/maildir/bsd/rhost-franceptt-10.eml +79 -0
  92. data/set-of-emails/maildir/bsd/rhost-franceptt-11.eml +96 -0
  93. metadata +14 -9
  94. data/lib/sisimai/bite.rb +0 -42
  95. data/lib/sisimai/bite/email.rb +0 -18
  96. data/lib/sisimai/bite/json.rb +0 -16
  97. data/lib/sisimai/message/email.rb +0 -26
  98. data/lib/sisimai/message/json.rb +0 -24
  99. data/lib/sisimai/order/email.rb +0 -20
  100. data/lib/sisimai/order/json.rb +0 -16
@@ -8,11 +8,24 @@ module Sisimai::Lhost
8
8
  require 'sisimai/lhost'
9
9
 
10
10
  Indicators = Sisimai::Lhost.INDICATORS
11
- StartingOf = { rfc822: ['Original message headers:'] }.freeze
11
+ ReBackbone = %r{^(?:
12
+ Original[ ]message[ ]headers: # en-US
13
+ |En-t.tes[ ]de[ ]message[ ]d'origine[ ]: # fr-FR/En-têtes de message d'origine
14
+ )
15
+ }x.freeze
12
16
  MarkingsOf = {
13
- message: %r/\ADiagnostic[ ]information[ ]for[ ]administrators:/,
17
+ message: %r{\A(?:
18
+ Diagnostic[ ]information[ ]for[ ]administrators: # en-US
19
+ |Informations[ ]de[ ]diagnostic[ ]pour[ ]les[ ]administrateurs # fr-FR
20
+ )
21
+ }x,
14
22
  error: %r/ ((?:RESOLVER|QUEUE)[.][A-Za-z]+(?:[.]\w+)?);/,
15
- rhost: %r/\AGenerating server:[ ]?(.*)/,
23
+ rhost: %r{\A(?:
24
+ Generating[ ]server # en-US
25
+ |Serveur[ ]de[ ]g.+ration[ ] # fr-FR/Serveur de génération
26
+ ):[ ]?(.*)
27
+ }x,
28
+ subject: %r/\A(?:Undeliverable|Non_remis_):/,
16
29
  }.freeze
17
30
  NDRSubject = {
18
31
  'SMTPSEND.DNS.NonExistentDomain' => 'hostunknown', # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
@@ -45,14 +58,13 @@ module Sisimai::Lhost
45
58
  # part or nil if it failed to parse or
46
59
  # the arguments are missing
47
60
  def make(mhead, mbody)
48
- return nil unless mhead['subject'].start_with?('Undeliverable:')
61
+ return nil unless mhead['subject'] =~ MarkingsOf[:subject]
49
62
  return nil unless mhead['content-language']
50
63
  return nil unless mhead['content-language'] =~ /\A[a-z]{2}(?:[-][A-Z]{2})?\z/
51
64
 
52
65
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
53
- hasdivided = mbody.split("\n")
54
- rfc822list = [] # (Array) Each line in message/rfc822 part string
55
- blanklines = 0 # (Integer) The number of blank lines
66
+ emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
67
+ bodyslices = emailsteak[0].split("\n")
56
68
  readcursor = 0 # (Integer) Points the current cursor position
57
69
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
58
70
  connvalues = 0 # (Integer) Flag, 1 if all the value of connheader have been set
@@ -61,80 +73,61 @@ module Sisimai::Lhost
61
73
  }
62
74
  v = nil
63
75
 
64
- while e = hasdivided.shift do
76
+ while e = bodyslices.shift do
77
+ # Read error messages and delivery status lines from the head of the email
78
+ # to the previous line of the beginning of the original message.
65
79
  if readcursor == 0
66
80
  # Beginning of the bounce message or delivery status part
67
- if e =~ MarkingsOf[:message]
68
- readcursor |= Indicators[:deliverystatus]
69
- next
70
- end
71
- end
72
-
73
- if (readcursor & Indicators[:'message-rfc822']) == 0
74
- # Beginning of the original message part
75
- if e.start_with?(StartingOf[:rfc822][0])
76
- readcursor |= Indicators[:'message-rfc822']
77
- next
78
- end
81
+ readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
82
+ next
79
83
  end
84
+ next if (readcursor & Indicators[:deliverystatus]) == 0
80
85
 
81
- if readcursor & Indicators[:'message-rfc822'] > 0
82
- # Inside of the original message part
83
- if e.empty?
84
- blanklines += 1
85
- break if blanklines > 1
86
- next
87
- end
88
- rfc822list << e
89
- else
90
- # Error message part
91
- next if (readcursor & Indicators[:deliverystatus]) == 0
86
+ if connvalues == connheader.keys.size
87
+ # Diagnostic information for administrators:
88
+ #
89
+ # Generating server: mta2.neko.example.jp
90
+ #
91
+ # kijitora@example.jp
92
+ # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
93
+ #
94
+ # Original message headers:
95
+ v = dscontents[-1]
92
96
 
93
- if connvalues == connheader.keys.size
94
- # Diagnostic information for administrators:
95
- #
96
- # Generating server: mta2.neko.example.jp
97
- #
97
+ if cv = e.match(/\A([^ @]+[@][^ @]+)\z/)
98
98
  # kijitora@example.jp
99
- # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
100
- #
101
- # Original message headers:
102
- v = dscontents[-1]
103
-
104
- if cv = e.match(/\A([^ @]+[@][^ @]+)\z/)
105
- # kijitora@example.jp
106
- if v['recipient']
107
- # There are multiple recipient addresses in the message body.
108
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
109
- v = dscontents[-1]
110
- end
111
- v['recipient'] = cv[1]
112
- v['diagnosis'] = ''
113
- recipients += 1
114
-
115
- elsif cv = e.match(/\A[#]([45]\d{2})[ ]([45][.]\d[.]\d+)[ ].+\z/)
116
- # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
117
- # #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipien=
118
- # t ##
119
- v['replycode'] = cv[1]
120
- v['status'] = cv[2]
121
- v['diagnosis'] = e
122
- else
123
- # Continued line of error messages
124
- next if v['diagnosis'].to_s.empty?
125
- next unless v['diagnosis'].end_with?('=')
126
- v['diagnosis'] = v['diagnosis'].chomp('=')
127
- v['diagnosis'] << e
99
+ if v['recipient']
100
+ # There are multiple recipient addresses in the message body.
101
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
102
+ v = dscontents[-1]
128
103
  end
104
+ v['recipient'] = cv[1]
105
+ v['diagnosis'] = ''
106
+ recipients += 1
107
+
108
+ elsif cv = e.match(/([45]\d{2})[ ]([45][.]\d[.]\d+)[ ].+\z/)
109
+ # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
110
+ # #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##
111
+ # Remote Server returned '550 5.1.1 RESOLVER.ADR.RecipNotFound; not found'
112
+ # 3/09/2016 8:05:56 PM - Remote Server at mydomain.com (10.1.1.3) returned '550 4.4.7 QUEUE.Expired; message expired'
113
+ v['replycode'] = cv[1]
114
+ v['status'] = cv[2]
115
+ v['diagnosis'] = e
129
116
  else
130
- # Diagnostic information for administrators:
131
- #
132
- # Generating server: mta22.neko.example.org
133
- next unless cv = e.match(MarkingsOf[:rhost])
134
- next unless connheader['rhost'].empty?
135
- connheader['rhost'] = cv[1]
136
- connvalues += 1
117
+ # Continued line of error messages
118
+ next if v['diagnosis'].to_s.empty?
119
+ next unless v['diagnosis'].end_with?('=')
120
+ v['diagnosis'] = v['diagnosis'].chomp('=')
121
+ v['diagnosis'] << e
137
122
  end
123
+ else
124
+ # Diagnostic information for administrators:
125
+ #
126
+ # Generating server: mta22.neko.example.org
127
+ next unless cv = e.match(MarkingsOf[:rhost])
128
+ next unless connheader['rhost'].empty?
129
+ connheader['rhost'] = cv[1]
130
+ connvalues += 1
138
131
  end
139
132
  end
140
133
  return nil unless recipients > 0
@@ -154,8 +147,7 @@ module Sisimai::Lhost
154
147
  e['agent'] = self.smtpagent
155
148
  end
156
149
 
157
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
158
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
150
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
159
151
  end
160
152
 
161
153
  end
@@ -7,6 +7,15 @@ module Sisimai::Lhost
7
7
  require 'sisimai/lhost'
8
8
 
9
9
  Indicators = Sisimai::Lhost.INDICATORS
10
+ # deliver.c:6423| if (bounce_return_body) fprintf(f,
11
+ # deliver.c:6424|"------ This is a copy of the message, including all the headers. ------\n");
12
+ # deliver.c:6425| else fprintf(f,
13
+ # deliver.c:6426|"------ This is a copy of the message's headers. ------\n");
14
+ ReBackbone = %r{^(?:
15
+ [-]+[ ]This[ ]is[ ]a[ ]copy[ ]of[ ](?:the|your)[ ]message.+headers[.][ ][-]+
16
+ |Content-Type:[ ]*message/rfc822
17
+ )
18
+ }x.freeze
10
19
  StartingOf = {
11
20
  deliverystatus: ['Content-type: message/delivery-status'],
12
21
  endof: ['__END_OF_EMAIL_MESSAGE__'],
@@ -29,18 +38,8 @@ module Sisimai::Lhost
29
38
  # deliver.c:6304|"could not be delivered to one or more of its recipients. The following\n"
30
39
  # deliver.c:6305|"address(es) failed:\n", sender_address);
31
40
  # deliver.c:6306| }
32
- #
33
- # deliver.c:6423| if (bounce_return_body) fprintf(f,
34
- # deliver.c:6424|"------ This is a copy of the message, including all the headers. ------\n");
35
- # deliver.c:6425| else fprintf(f,
36
- # deliver.c:6426|"------ This is a copy of the message's headers. ------\n");
37
- alias: %r/\A([ ]+an undisclosed address)\z/,
38
- frozen: %r/\AMessage .+ (?:has been frozen|was frozen on arrival)/,
39
- rfc822: %r{\A(?:
40
- [-]+[ ]This[ ]is[ ]a[ ]copy[ ]of[ ](?:the|your)[ ]message.+headers[.][ ][-]+
41
- |Content-Type:[ ]*message/rfc822
42
- )\z
43
- }x,
41
+ alias: %r/\A([ ]+an undisclosed address)\z/,
42
+ frozen: %r/\AMessage .+ (?:has been frozen|was frozen on arrival)/,
44
43
  message: %r{\A(?>
45
44
  This[ ]message[ ]was[ ]created[ ]automatically[ ]by[ ]mail[ ]delivery[ ]software[.]
46
45
  |A[ ]message[ ]that[ ]you[ ]sent[ ]was[ ]rejected[ ]by[ ]the[ ]local[ ]scanning[ ]code
@@ -159,16 +158,13 @@ module Sisimai::Lhost
159
158
  require 'sisimai/rfc1894'
160
159
  fieldtable = Sisimai::RFC1894.FIELDTABLE
161
160
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
162
- hasdivided = mbody.split("\n")
163
- rfc822list = [] # (Array) Each line in message/rfc822 part string
164
- blanklines = 0 # (Integer) The number of blank lines
161
+ emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
162
+ bodyslices = emailsteak[0].split("\n")
165
163
  readcursor = 0 # (Integer) Points the current cursor position
164
+ nextcursor = 0
166
165
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
167
166
  localhost0 = '' # (String) Local MTA
168
167
  boundary00 = '' # (String) Boundary string
169
- havepassed = {
170
- :deliverystatus => 0
171
- }
172
168
  v = nil
173
169
 
174
170
  if mhead['content-type']
@@ -177,7 +173,9 @@ module Sisimai::Lhost
177
173
  boundary00 = Sisimai::MIME.boundary(mhead['content-type']) || ''
178
174
  end
179
175
 
180
- while e = hasdivided.shift do
176
+ while e = bodyslices.shift do
177
+ # Read error messages and delivery status lines from the head of the email
178
+ # to the previous line of the beginning of the original message.
181
179
  break if e == StartingOf[:endof][0]
182
180
 
183
181
  if readcursor == 0
@@ -187,143 +185,123 @@ module Sisimai::Lhost
187
185
  next unless e =~ MarkingsOf[:frozen]
188
186
  end
189
187
  end
188
+ next if (readcursor & Indicators[:deliverystatus]) == 0
189
+ next if e.empty?
190
+
191
+ # This message was created automatically by mail delivery software.
192
+ #
193
+ # A message that you sent could not be delivered to one or more of its
194
+ # recipients. This is a permanent error. The following address(es) failed:
195
+ #
196
+ # kijitora@example.jp
197
+ # SMTP error from remote mail server after RCPT TO:<kijitora@example.jp>:
198
+ # host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
199
+ v = dscontents[-1]
200
+
201
+ if cv = e.match(/\A[ \t]{2}([^ \t]+[@][^ \t]+[.]?[a-zA-Z]+)(:.+)?\z/) ||
202
+ e.match(/\A[ \t]{2}[^ \t]+[@][^ \t]+[.][a-zA-Z]+[ ]<(.+?[@].+?)>:.+\z/) ||
203
+ e.match(MarkingsOf[:alias])
204
+ # kijitora@example.jp
205
+ # sabineko@example.jp: forced freeze
206
+ # mikeneko@example.jp <nekochan@example.org>: ...
207
+ #
208
+ # deliver.c:4549| printed = US"an undisclosed address";
209
+ # an undisclosed address
210
+ # (generated from kijitora@example.jp)
211
+ r = cv[1]
190
212
 
191
- if (readcursor & Indicators[:'message-rfc822']) == 0
192
- # Beginning of the original message part(message/rfc822)
193
- if e =~ MarkingsOf[:rfc822]
194
- readcursor |= Indicators[:'message-rfc822']
195
- next
213
+ if v['recipient']
214
+ # There are multiple recipient addresses in the message body.
215
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
216
+ v = dscontents[-1]
196
217
  end
197
- end
198
-
199
- if readcursor & Indicators[:'message-rfc822'] > 0
200
- # message/rfc822 OR text/rfc822-headers part
201
- if e.empty?
202
- blanklines += 1
203
- break if blanklines > 1
204
- next
218
+ # v['recipient'] = cv[1]
219
+
220
+ if cv = e.match(/\A[ \t]+[^ \t]+[@][^ \t]+[.][a-zA-Z]+[ ]<(.+?[@].+?)>:.+\z/)
221
+ # parser.c:743| while (bracket_count-- > 0) if (*s++ != '>')
222
+ # parser.c:744| {
223
+ # parser.c:745| *errorptr = s[-1] == 0
224
+ # parser.c:746| ? US"'>' missing at end of address"
225
+ # parser.c:747| : string_sprintf("malformed address: %.32s may not follow %.*s",
226
+ # parser.c:748| s-1, (int)(s - US mailbox - 1), mailbox);
227
+ # parser.c:749| goto PARSE_FAILED;
228
+ # parser.c:750| }
229
+ r = cv[1]
230
+ v['diagnosis'] = e
205
231
  end
206
- rfc822list << e
232
+ v['recipient'] = r
233
+ recipients += 1
234
+
235
+ elsif cv = e.match(/\A[ ]+[(]generated[ ]from[ ](.+)[)]\z/) ||
236
+ e.match(/\A[ ]+generated[ ]by[ ]([^ \t]+[@][^ \t]+)/)
237
+ # (generated from kijitora@example.jp)
238
+ # pipe to |/bin/echo "Some pipe output"
239
+ # generated by userx@myhost.test.ex
240
+ v['alias'] = cv[1]
207
241
  else
208
- # message/delivery-status part
209
- next if (readcursor & Indicators[:deliverystatus]) == 0
210
242
  next if e.empty?
211
243
 
212
- # This message was created automatically by mail delivery software.
213
- #
214
- # A message that you sent could not be delivered to one or more of its
215
- # recipients. This is a permanent error. The following address(es) failed:
216
- #
217
- # kijitora@example.jp
218
- # SMTP error from remote mail server after RCPT TO:<kijitora@example.jp>:
219
- # host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
220
- v = dscontents[-1]
221
-
222
- if cv = e.match(/\A[ \t]{2}([^ \t]+[@][^ \t]+[.]?[a-zA-Z]+)(:.+)?\z/) ||
223
- e.match(/\A[ \t]{2}[^ \t]+[@][^ \t]+[.][a-zA-Z]+[ ]<(.+?[@].+?)>:.+\z/) ||
224
- e.match(MarkingsOf[:alias])
225
- # kijitora@example.jp
226
- # sabineko@example.jp: forced freeze
227
- # mikeneko@example.jp <nekochan@example.org>: ...
228
- #
229
- # deliver.c:4549| printed = US"an undisclosed address";
230
- # an undisclosed address
231
- # (generated from kijitora@example.jp)
232
- r = cv[1]
233
-
234
- if v['recipient']
235
- # There are multiple recipient addresses in the message body.
236
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
237
- v = dscontents[-1]
238
- end
239
- # v['recipient'] = cv[1]
240
-
241
- if cv = e.match(/\A[ \t]+[^ \t]+[@][^ \t]+[.][a-zA-Z]+[ ]<(.+?[@].+?)>:.+\z/)
242
- # parser.c:743| while (bracket_count-- > 0) if (*s++ != '>')
243
- # parser.c:744| {
244
- # parser.c:745| *errorptr = s[-1] == 0
245
- # parser.c:746| ? US"'>' missing at end of address"
246
- # parser.c:747| : string_sprintf("malformed address: %.32s may not follow %.*s",
247
- # parser.c:748| s-1, (int)(s - US mailbox - 1), mailbox);
248
- # parser.c:749| goto PARSE_FAILED;
249
- # parser.c:750| }
250
- r = cv[1]
251
- v['diagnosis'] = e
252
- end
253
- v['recipient'] = r
254
- recipients += 1
255
-
256
- elsif cv = e.match(/\A[ ]+[(]generated[ ]from[ ](.+)[)]\z/) ||
257
- e.match(/\A[ ]+generated[ ]by[ ]([^ \t]+[@][^ \t]+)/)
258
- # (generated from kijitora@example.jp)
259
- # pipe to |/bin/echo "Some pipe output"
260
- # generated by userx@myhost.test.ex
261
- v['alias'] = cv[1]
244
+ if e =~ MarkingsOf[:frozen]
245
+ # Message *** has been frozen by the system filter.
246
+ # Message *** was frozen on arrival by ACL.
247
+ v['alterrors'] ||= ''
248
+ v['alterrors'] << e + ' '
262
249
  else
263
- next if e.empty?
250
+ if !boundary00.empty?
251
+ # --NNNNNNNNNN-eximdsn-MMMMMMMMMM
252
+ # Content-type: message/delivery-status
253
+ # ...
254
+ if Sisimai::RFC1894.match(e)
255
+ # "e" matched with any field defined in RFC3464
256
+ next unless o = Sisimai::RFC1894.field(e)
257
+
258
+ if o[-1] == 'addr'
259
+ # Final-Recipient: rfc822; kijitora@example.jp
260
+ # X-Actual-Recipient: rfc822; kijitora@example.co.jp
261
+ next unless o[0] == 'final-recipient'
262
+ v['spec'] ||= o[2].include?('@') ? 'SMTP' : 'X-UNIX'
263
+
264
+ elsif o[-1] == 'code'
265
+ # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
266
+ v['spec'] = o[1]
267
+ v['diagnosis'] = o[2]
264
268
 
265
- if e =~ MarkingsOf[:frozen]
266
- # Message *** has been frozen by the system filter.
267
- # Message *** was frozen on arrival by ACL.
268
- v['alterrors'] ||= ''
269
- v['alterrors'] << e + ' '
270
- else
271
- if !boundary00.empty?
272
- # --NNNNNNNNNN-eximdsn-MMMMMMMMMM
273
- # Content-type: message/delivery-status
274
- # ...
275
- if Sisimai::RFC1894.match(e)
276
- # "e" matched with any field defined in RFC3464
277
- next unless o = Sisimai::RFC1894.field(e)
278
-
279
- if o[-1] == 'addr'
280
- # Final-Recipient: rfc822; kijitora@example.jp
281
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
282
- next unless o[0] == 'final-recipient'
283
- v['spec'] ||= o[2].include?('@') ? 'SMTP' : 'X-UNIX'
284
-
285
- elsif o[-1] == 'code'
286
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
287
- v['spec'] = o[1]
288
- v['diagnosis'] = o[2]
289
-
290
- else
291
- # Other DSN fields defined in RFC3464
292
- next unless fieldtable.key?(o[0])
293
- v[fieldtable[o[0]]] = o[2]
294
- end
295
269
  else
296
- # Error message ?
297
- next if havepassed[:deliverystatus] == 1
298
-
299
- # Content-type: message/delivery-status
300
- havepassed[:deliverystatus] = 1 if e.start_with?(StartingOf[:deliverystatus][0])
301
- v['alterrors'] ||= ''
302
- v['alterrors'] << e + ' ' if e.start_with?(' ')
270
+ # Other DSN fields defined in RFC3464
271
+ next unless fieldtable[o[0]]
272
+ v[fieldtable[o[0]]] = o[2]
303
273
  end
304
274
  else
305
- if dscontents.size == recipients
306
- # Error message
307
- next if e.empty?
308
- v['diagnosis'] ||= ''
309
- v['diagnosis'] << e + ' '
275
+ # Error message ?
276
+ next if nextcursor == 1
277
+
278
+ # Content-type: message/delivery-status
279
+ nextcursor = 1 if e.start_with?(StartingOf[:deliverystatus][0])
280
+ v['alterrors'] ||= ''
281
+ v['alterrors'] << e + ' ' if e.start_with?(' ')
282
+ end
283
+ else
284
+ if dscontents.size == recipients
285
+ # Error message
286
+ next if e.empty?
287
+ v['diagnosis'] ||= ''
288
+ v['diagnosis'] << e + ' '
289
+ else
290
+ # Error message when email address above does not include '@'
291
+ # and domain part.
292
+ if e =~ %r<\A[ ]+pipe[ ]to[ ][|]/.+>
293
+ # pipe to |/path/to/prog ...
294
+ # generated by kijitora@example.com
295
+ v['diagnosis'] = e
310
296
  else
311
- # Error message when email address above does not include '@'
312
- # and domain part.
313
- if e =~ %r<\A[ ]+pipe[ ]to[ ][|]/.+>
314
- # pipe to |/path/to/prog ...
315
- # generated by kijitora@example.com
316
- v['diagnosis'] = e
317
- else
318
- next unless e.start_with?(' ')
319
- v['alterrors'] ||= ''
320
- v['alterrors'] << e + ' '
321
- end
297
+ next unless e.start_with?(' ')
298
+ v['alterrors'] ||= ''
299
+ v['alterrors'] << e + ' '
322
300
  end
323
301
  end
324
302
  end
325
303
  end
326
- end # End of message/delivery-status
304
+ end
327
305
  end
328
306
 
329
307
  if recipients > 0
@@ -519,8 +497,7 @@ module Sisimai::Lhost
519
497
  e.each_key { |a| e[a] ||= '' }
520
498
  end
521
499
 
522
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
523
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
500
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
524
501
  end
525
502
 
526
503
  end