Commit f055372d f055372d64373ee24823e5789e23f902f48011b0 by Sergey Poznyakoff

filter stream: make sure all input data get processed.

* include/mailutils/filter.h (MU_FILTER_MAX_AGAIN): Add a comment.
* libmailutils/stream/fltstream.c (filter_read): Use
mu_debug on the filter.error level, instead of plain mu_error.
If the xcoder returns OK and does not consume all input when
processing the last buffer, assume mu_filter_again.
Fix loop condition.
(filter_write_internal): Use
mu_debug on the filter.error level, instead of plain mu_error.
1 parent c522de11
...@@ -62,6 +62,8 @@ enum mu_filter_result ...@@ -62,6 +62,8 @@ enum mu_filter_result
62 mu_filter_again 62 mu_filter_again
63 }; 63 };
64 64
65 /* An xcode function is not allowed to return mu_filter_again more
66 than MU_FILTER_MAX_AGAIN times in a sequence. */
65 #define MU_FILTER_MAX_AGAIN 5 67 #define MU_FILTER_MAX_AGAIN 5
66 68
67 typedef int (*mu_filter_new_data_t) (void **, int, int argc, 69 typedef int (*mu_filter_new_data_t) (void **, int, int argc,
......
...@@ -172,18 +172,13 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) ...@@ -172,18 +172,13 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
172 if (++again > MU_FILTER_MAX_AGAIN) 172 if (++again > MU_FILTER_MAX_AGAIN)
173 { 173 {
174 /* FIXME: What filter? Need some id. */ 174 /* FIXME: What filter? Need some id. */
175 mu_error (_("filter returned `again' too many times")); 175 mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR,
176 (_("filter returned `again' too many times")));
176 again = 0; 177 again = 0;
177 } 178 }
178 break; 179 break;
179 180
180 case mu_filter_ok: 181 case mu_filter_ok:
181 again = 0;
182 if (cmd == mu_filter_lastbuf || iobuf.eof)
183 {
184 fs->fltflag |= _MU_FILTER_EOF;
185 stop = 1;
186 }
187 break; 182 break;
188 183
189 case mu_filter_failure: 184 case mu_filter_failure:
...@@ -207,6 +202,37 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) ...@@ -207,6 +202,37 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
207 202
208 /* iobuf.isize contains number of bytes read from input */ 203 /* iobuf.isize contains number of bytes read from input */
209 MFB_advance_pos (&fs->inbuf, iobuf.isize); 204 MFB_advance_pos (&fs->inbuf, iobuf.isize);
205
206 if (res == mu_filter_ok)
207 {
208 if (iobuf.eof)
209 {
210 fs->fltflag |= _MU_FILTER_EOF;
211 stop = 1;
212 }
213 else if (cmd == mu_filter_lastbuf)
214 {
215 if (MFB_RDBYTES (fs->inbuf))
216 {
217 /* If xcoder has not consumed all input, try again */
218 if (++again > MU_FILTER_MAX_AGAIN)
219 {
220 /* FIXME: What filter? Need some id. */
221 mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR,
222 (_("filter returned `again' too many times")));
223 stop = 1;
224 }
225 }
226
227 else
228 {
229 fs->fltflag |= _MU_FILTER_EOF;
230 stop = 1;
231 }
232 }
233 else
234 again = 0;
235 }
210 } 236 }
211 237
212 rdsize = size - total; 238 rdsize = size - total;
...@@ -217,7 +243,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) ...@@ -217,7 +243,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
217 total += rdsize; 243 total += rdsize;
218 244
219 } 245 }
220 while (!stop && (total < size || again)); 246 while (!stop && total < size);
221 247
222 *pret = total; 248 *pret = total;
223 return 0; 249 return 0;
...@@ -278,7 +304,8 @@ filter_write_internal (mu_stream_t stream, enum mu_filter_command cmd, ...@@ -278,7 +304,8 @@ filter_write_internal (mu_stream_t stream, enum mu_filter_command cmd,
278 if (++again > MU_FILTER_MAX_AGAIN) 304 if (++again > MU_FILTER_MAX_AGAIN)
279 { 305 {
280 /* FIXME: What filter? Need some id. */ 306 /* FIXME: What filter? Need some id. */
281 mu_error (_("filter returned `again' too many times")); 307 mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR,
308 (_("filter returned `again' too many times")));
282 again = 0; 309 again = 0;
283 } 310 }
284 break; 311 break;
......