Fix mime creation and Sieve reject/redirect actions.
* examples/mta.c (finalize_option): New variable. (message_finalize): Don't modify the message if finalize_option is 0. * include/mailutils/sys/message.h (_mu_message) <orig_header_size>: New member. * include/mailutils/sys/mime.h (_mu_mime) <part_stream>: New member. * libmu_sieve/actions.c (mime_create_reason) (mime_create_ds): Use mu_body_get_streamref. (mime_create_quote): Use mu_body_get_streamref/mu_message_get_streamref. (sieve_action_reject): Set the To: header. * mailbox/message.c (mu_message_get_header): Set orig_header_size. (mu_message_get_body): Use orig_header_size instead of relying on mu_header_size. * mailbox/mime.c (_mime_part_size): New static. (_mime_body_stream_size): New method. (_mime_body_seek): Rename to _mime_body_stream_seek. (_mime_body_read): Rewrite and rename to _mime_body_stream_read. (_mime_body_ioctl): Rename to _mime_body_stream_ioctl. (create_mime_body_stream): Take mu_mime_t as the 2nd parameter. Initialize sp->stream.size and sp->mime. (_mime_body_size): Rewrite using _mime_part_size. (mu_mime_destroy): Destroy part_stream. * sieve/testsuite/Redirect: Reflect new mta behavior. * sieve/testsuite/Reject: Likewise.
Showing
8 changed files
with
205 additions
and
120 deletions
... | @@ -73,6 +73,18 @@ int dot = 1; /* Message is terminated by a lone dot on a line */ | ... | @@ -73,6 +73,18 @@ int dot = 1; /* Message is terminated by a lone dot on a line */ |
73 | 73 | ||
74 | mu_address_t recipients = NULL; | 74 | mu_address_t recipients = NULL; |
75 | char *progname; | 75 | char *progname; |
76 | /* FIXME: If finalize_option is set, mta should try to finalize | ||
77 | received messages the way sendmail does, i.e. to add To: or | ||
78 | Cc: headers, if they are missing, etc. The code to do so is | ||
79 | already included, but the modified message is not reproduced | ||
80 | on diagnostic output because mta_send reads it from the stream, | ||
81 | which does not reflect modifications to the header. | ||
82 | |||
83 | Ideally, the mu_message_get_streamref function should notice the | ||
84 | change in the header (and/or the body) and return a temporary | ||
85 | stream, which will read the modified values. This is left as | ||
86 | as TODO for a later time. 2010-09-29, Sergey */ | ||
87 | int finalize_option = 0; | ||
76 | 88 | ||
77 | int mta_stdin (int argc, char **argv); | 89 | int mta_stdin (int argc, char **argv); |
78 | int mta_smtp (int argc, char **argv); | 90 | int mta_smtp (int argc, char **argv); |
... | @@ -361,7 +373,7 @@ message_finalize (mu_message_t msg, int warn) | ... | @@ -361,7 +373,7 @@ message_finalize (mu_message_t msg, int warn) |
361 | 373 | ||
362 | mu_message_get_header (msg, &header); | 374 | mu_message_get_header (msg, &header); |
363 | 375 | ||
364 | if (warn && from_person) | 376 | if (finalize_option && warn && from_person) |
365 | { | 377 | { |
366 | struct passwd *pwd = getpwuid (getuid ()); | 378 | struct passwd *pwd = getpwuid (getuid ()); |
367 | char *warn = malloc (strlen (pwd->pw_name) + 1 + | 379 | char *warn = malloc (strlen (pwd->pw_name) + 1 + |
... | @@ -400,7 +412,8 @@ message_finalize (mu_message_t msg, int warn) | ... | @@ -400,7 +412,8 @@ message_finalize (mu_message_t msg, int warn) |
400 | free (value); | 412 | free (value); |
401 | } | 413 | } |
402 | 414 | ||
403 | if (mu_header_aget_value (header, MU_HEADER_BCC, &value) == 0) | 415 | if (finalize_option && |
416 | mu_header_aget_value (header, MU_HEADER_BCC, &value) == 0) | ||
404 | { | 417 | { |
405 | if (add_recipient (value)) | 418 | if (add_recipient (value)) |
406 | { | 419 | { |
... | @@ -412,7 +425,7 @@ message_finalize (mu_message_t msg, int warn) | ... | @@ -412,7 +425,7 @@ message_finalize (mu_message_t msg, int warn) |
412 | } | 425 | } |
413 | } | 426 | } |
414 | 427 | ||
415 | if (!have_to) | 428 | if (finalize_option && !have_to) |
416 | { | 429 | { |
417 | size_t n; | 430 | size_t n; |
418 | int c; | 431 | int c; | ... | ... |
... | @@ -47,6 +47,7 @@ struct _mu_message | ... | @@ -47,6 +47,7 @@ struct _mu_message |
47 | mu_mime_t mime; | 47 | mu_mime_t mime; |
48 | mu_observable_t observable; | 48 | mu_observable_t observable; |
49 | mu_mailbox_t mailbox; | 49 | mu_mailbox_t mailbox; |
50 | size_t orig_header_size; | ||
50 | 51 | ||
51 | /* Reference count. */ | 52 | /* Reference count. */ |
52 | int ref; | 53 | int ref; | ... | ... |
... | @@ -64,6 +64,7 @@ struct _mu_mime | ... | @@ -64,6 +64,7 @@ struct _mu_mime |
64 | size_t boundary_len; | 64 | size_t boundary_len; |
65 | size_t preamble; | 65 | size_t preamble; |
66 | size_t postamble; | 66 | size_t postamble; |
67 | mu_stream_t part_stream; | ||
67 | /* parser state */ | 68 | /* parser state */ |
68 | char *cur_line; | 69 | char *cur_line; |
69 | ssize_t line_ndx; | 70 | ssize_t line_ndx; | ... | ... |
... | @@ -154,7 +154,7 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) | ... | @@ -154,7 +154,7 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) |
154 | 154 | ||
155 | mu_message_create (&newmsg, NULL); | 155 | mu_message_create (&newmsg, NULL); |
156 | mu_message_get_body (newmsg, &body); | 156 | mu_message_get_body (newmsg, &body); |
157 | mu_body_get_stream (body, &stream); | 157 | mu_body_get_streamref (body, &stream); |
158 | 158 | ||
159 | time (&t); | 159 | time (&t); |
160 | tm = localtime (&t); | 160 | tm = localtime (&t); |
... | @@ -171,6 +171,8 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) | ... | @@ -171,6 +171,8 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text) |
171 | mu_stream_printf (stream, "Reason given was as follows:\n\n"); | 171 | mu_stream_printf (stream, "Reason given was as follows:\n\n"); |
172 | mu_stream_printf (stream, "%s", text); | 172 | mu_stream_printf (stream, "%s", text); |
173 | mu_stream_close (stream); | 173 | mu_stream_close (stream); |
174 | mu_stream_destroy (&stream); | ||
175 | |||
174 | mu_header_create (&hdr, content_header, strlen (content_header)); | 176 | mu_header_create (&hdr, content_header, strlen (content_header)); |
175 | mu_message_set_header (newmsg, hdr, NULL); | 177 | mu_message_set_header (newmsg, hdr, NULL); |
176 | mu_mime_add_part (mime, newmsg); | 178 | mu_mime_add_part (mime, newmsg); |
... | @@ -196,7 +198,7 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig) | ... | @@ -196,7 +198,7 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig) |
196 | mu_message_get_header (newmsg, &hdr); | 198 | mu_message_get_header (newmsg, &hdr); |
197 | mu_header_set_value (hdr, "Content-Type", "message/delivery-status", 1); | 199 | mu_header_set_value (hdr, "Content-Type", "message/delivery-status", 1); |
198 | mu_message_get_body (newmsg, &body); | 200 | mu_message_get_body (newmsg, &body); |
199 | mu_body_get_stream (body, &stream); | 201 | mu_body_get_streamref (body, &stream); |
200 | mu_stream_printf (stream, "Reporting-UA: sieve; %s\n", PACKAGE_STRING); | 202 | mu_stream_printf (stream, "Reporting-UA: sieve; %s\n", PACKAGE_STRING); |
201 | 203 | ||
202 | mu_message_get_envelope (orig, &env); | 204 | mu_message_get_envelope (orig, &env); |
... | @@ -226,7 +228,9 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig) | ... | @@ -226,7 +228,9 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig) |
226 | mu_stream_printf (stream, "Last-Attempt-Date: %s\n", datestr); | 228 | mu_stream_printf (stream, "Last-Attempt-Date: %s\n", datestr); |
227 | 229 | ||
228 | mu_stream_close (stream); | 230 | mu_stream_close (stream); |
229 | mu_mime_add_part(mime, newmsg); | 231 | mu_stream_destroy (&stream); |
232 | |||
233 | mu_mime_add_part (mime, newmsg); | ||
230 | mu_message_unref (newmsg); | 234 | mu_message_unref (newmsg); |
231 | } | 235 | } |
232 | 236 | ||
... | @@ -241,25 +245,30 @@ mime_create_quote (mu_mime_t mime, mu_message_t msg) | ... | @@ -241,25 +245,30 @@ mime_create_quote (mu_mime_t mime, mu_message_t msg) |
241 | size_t n; | 245 | size_t n; |
242 | char buffer[512]; | 246 | char buffer[512]; |
243 | mu_body_t body; | 247 | mu_body_t body; |
248 | int rc; | ||
244 | 249 | ||
245 | mu_message_create (&newmsg, NULL); | 250 | mu_message_create (&newmsg, NULL); |
246 | mu_message_get_header (newmsg, &hdr); | 251 | mu_message_get_header (newmsg, &hdr); |
247 | mu_header_set_value (hdr, "Content-Type", "message/rfc822", 1); | 252 | mu_header_set_value (hdr, "Content-Type", "message/rfc822", 1); |
248 | mu_message_get_body (newmsg, &body); | 253 | mu_message_get_body (newmsg, &body); |
249 | mu_body_get_stream (body, &ostream); | 254 | mu_body_get_streamref (body, &ostream); |
250 | mu_message_get_stream (msg, &istream); | 255 | mu_message_get_streamref (msg, &istream); |
251 | 256 | ||
257 | rc = 0;/* FIXME: use mu_stream_copy */ | ||
252 | while (mu_stream_read (istream, buffer, sizeof buffer - 1, &n) == 0 | 258 | while (mu_stream_read (istream, buffer, sizeof buffer - 1, &n) == 0 |
253 | && n != 0) | 259 | && n != 0) |
254 | { | 260 | { |
255 | int rc = mu_stream_write (ostream, buffer, n, NULL); | 261 | rc = mu_stream_write (ostream, buffer, n, NULL); |
256 | if (rc) | 262 | if (rc) |
257 | return EIO; | 263 | break; |
258 | } | 264 | } |
265 | mu_stream_destroy (&istream); | ||
259 | mu_stream_close (ostream); | 266 | mu_stream_close (ostream); |
267 | mu_stream_destroy (&ostream); | ||
268 | |||
260 | mu_mime_add_part (mime, newmsg); | 269 | mu_mime_add_part (mime, newmsg); |
261 | mu_message_unref (newmsg); | 270 | mu_message_unref (newmsg); |
262 | return 0; | 271 | return rc; |
263 | } | 272 | } |
264 | 273 | ||
265 | static int | 274 | static int |
... | @@ -292,6 +301,7 @@ sieve_action_reject (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) | ... | @@ -292,6 +301,7 @@ sieve_action_reject (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) |
292 | mu_message_t newmsg; | 301 | mu_message_t newmsg; |
293 | char *addrtext; | 302 | char *addrtext; |
294 | mu_address_t from, to; | 303 | mu_address_t from, to; |
304 | mu_header_t hdr; | ||
295 | 305 | ||
296 | mu_sieve_value_t *val = mu_sieve_value_get (args, 0); | 306 | mu_sieve_value_t *val = mu_sieve_value_get (args, 0); |
297 | if (!val) | 307 | if (!val) |
... | @@ -308,6 +318,9 @@ sieve_action_reject (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) | ... | @@ -308,6 +318,9 @@ sieve_action_reject (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) |
308 | mu_mime_get_message (mime, &newmsg); | 318 | mu_mime_get_message (mime, &newmsg); |
309 | 319 | ||
310 | mu_sieve_get_message_sender (mach->msg, &addrtext); | 320 | mu_sieve_get_message_sender (mach->msg, &addrtext); |
321 | mu_message_get_header (newmsg, &hdr); | ||
322 | mu_header_prepend (hdr, MU_HEADER_TO, addrtext); | ||
323 | |||
311 | rc = mu_address_create (&to, addrtext); | 324 | rc = mu_address_create (&to, addrtext); |
312 | if (rc) | 325 | if (rc) |
313 | { | 326 | { | ... | ... |
... | @@ -688,6 +688,9 @@ mu_message_get_header (mu_message_t msg, mu_header_t *phdr) | ... | @@ -688,6 +688,9 @@ mu_message_get_header (mu_message_t msg, mu_header_t *phdr) |
688 | return status; | 688 | return status; |
689 | if (msg->stream) | 689 | if (msg->stream) |
690 | mu_header_set_fill (header, message_header_fill, msg); | 690 | mu_header_set_fill (header, message_header_fill, msg); |
691 | status = mu_header_size (header, &msg->orig_header_size); | ||
692 | if (status) | ||
693 | return status; | ||
691 | msg->header = header; | 694 | msg->header = header; |
692 | } | 695 | } |
693 | *phdr = msg->header; | 696 | *phdr = msg->header; |
... | @@ -728,19 +731,15 @@ mu_message_get_body (mu_message_t msg, mu_body_t *pbody) | ... | @@ -728,19 +731,15 @@ mu_message_get_body (mu_message_t msg, mu_body_t *pbody) |
728 | /* FIXME: I'm not sure if the second condition is really needed */ | 731 | /* FIXME: I'm not sure if the second condition is really needed */ |
729 | if (msg->stream/* && (msg->flags & MESSAGE_INTERNAL_STREAM)*/) | 732 | if (msg->stream/* && (msg->flags & MESSAGE_INTERNAL_STREAM)*/) |
730 | { | 733 | { |
731 | size_t size = 0; | ||
732 | mu_stream_t stream; | 734 | mu_stream_t stream; |
733 | int flags = 0; | 735 | int flags = 0; |
734 | 736 | ||
735 | /* FIXME: The size cannot be used as offset, because | 737 | /* FIXME: The actual mu_header_size cannot be used as offset, |
736 | the headers might have been modified in between. */ | 738 | because the headers might have been modified in between. */ |
737 | status = mu_header_size (msg->header, &size); | ||
738 | if (status) | ||
739 | return status; | ||
740 | 739 | ||
741 | mu_stream_get_flags (msg->stream, &flags); | 740 | mu_stream_get_flags (msg->stream, &flags); |
742 | status = mu_streamref_create_abridged (&stream, msg->stream, | 741 | status = mu_streamref_create_abridged (&stream, msg->stream, |
743 | size, 0); | 742 | msg->orig_header_size, 0); |
744 | if (status) | 743 | if (status) |
745 | { | 744 | { |
746 | mu_body_destroy (&body, msg); | 745 | mu_body_destroy (&body, msg); | ... | ... |
... | @@ -536,15 +536,52 @@ _mime_set_content_type (mu_mime_t mime) | ... | @@ -536,15 +536,52 @@ _mime_set_content_type (mu_mime_t mime) |
536 | } | 536 | } |
537 | 537 | ||
538 | 538 | ||
539 | static int | ||
540 | _mime_part_size (mu_mime_t mime, size_t *psize) | ||
541 | { | ||
542 | int i, ret; | ||
543 | size_t size, total = 0; | ||
544 | |||
545 | if (mime->nmtp_parts == 0) | ||
546 | return EINVAL; | ||
547 | |||
548 | if ((ret = _mime_set_content_type (mime)) != 0) | ||
549 | return ret; | ||
550 | for (i = 0; i < mime->nmtp_parts; i++) | ||
551 | { | ||
552 | mu_message_size (mime->mtp_parts[i]->msg, &size); | ||
553 | total += size; | ||
554 | if (mime->nmtp_parts > 1) /* boundary line */ | ||
555 | total += strlen (mime->boundary) + 3; | ||
556 | } | ||
557 | if (mime->nmtp_parts > 1) /* ending boundary line */ | ||
558 | total += 2; | ||
559 | *psize = total; | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | |||
539 | struct _mime_body_stream | 564 | struct _mime_body_stream |
540 | { | 565 | { |
541 | struct _mu_stream stream; | 566 | struct _mu_stream stream; |
542 | mu_mime_t mime; | 567 | mu_mime_t mime; |
543 | }; | 568 | }; |
544 | 569 | ||
570 | static int | ||
571 | _mime_body_stream_size (mu_stream_t stream, mu_off_t *psize) | ||
572 | { | ||
573 | struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream; | ||
574 | mu_mime_t mime = mstr->mime; | ||
575 | size_t sz; | ||
576 | int rc = _mime_part_size (mime, &sz); | ||
577 | if (rc == 0) | ||
578 | *psize = sz; | ||
579 | return rc; | ||
580 | } | ||
581 | |||
545 | /* FIXME: The seek method is defective */ | 582 | /* FIXME: The seek method is defective */ |
546 | static int | 583 | static int |
547 | _mime_body_seek (mu_stream_t stream, mu_off_t off, mu_off_t *presult) | 584 | _mime_body_stream_seek (mu_stream_t stream, mu_off_t off, mu_off_t *presult) |
548 | { | 585 | { |
549 | struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream; | 586 | struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream; |
550 | mu_mime_t mime = mstr->mime; | 587 | mu_mime_t mime = mstr->mime; |
... | @@ -565,21 +602,27 @@ _mime_body_seek (mu_stream_t stream, mu_off_t off, mu_off_t *presult) | ... | @@ -565,21 +602,27 @@ _mime_body_seek (mu_stream_t stream, mu_off_t off, mu_off_t *presult) |
565 | return 0; | 602 | return 0; |
566 | } | 603 | } |
567 | 604 | ||
568 | #define ADD_CHAR(buf, c, offset, buflen, nbytes) do {\ | 605 | #define ADD_CHAR(buf, c, offset, buflen, total, nbytes) \ |
569 | *(buf)++ = c;\ | 606 | do \ |
570 | (offset)++;\ | 607 | { \ |
571 | (nbytes)++;\ | 608 | *(buf)++ = c; \ |
572 | if (--(buflen) == 0) return 0;\ | 609 | (offset)++; \ |
573 | } while (0) | 610 | (total)++; \ |
611 | if (--(buflen) == 0) \ | ||
612 | { \ | ||
613 | *(nbytes) = total; \ | ||
614 | return 0; \ | ||
615 | } \ | ||
616 | } \ | ||
617 | while (0) | ||
574 | 618 | ||
575 | static int | 619 | static int |
576 | _mime_body_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) | 620 | _mime_body_stream_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) |
577 | { | 621 | { |
578 | struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream; | 622 | struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream; |
579 | mu_mime_t mime = mstr->mime; | 623 | mu_mime_t mime = mstr->mime; |
580 | int ret = 0; | 624 | int ret = 0; |
581 | size_t part_nbytes = 0; | 625 | size_t total = 0; |
582 | mu_stream_t msg_stream = NULL; | ||
583 | 626 | ||
584 | if (mime->nmtp_parts == 0) | 627 | if (mime->nmtp_parts == 0) |
585 | return EINVAL; | 628 | return EINVAL; |
... | @@ -588,7 +631,10 @@ _mime_body_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) | ... | @@ -588,7 +631,10 @@ _mime_body_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) |
588 | { | 631 | { |
589 | do | 632 | do |
590 | { | 633 | { |
591 | mu_stream_destroy (&msg_stream); | 634 | size_t part_nbytes = 0; |
635 | |||
636 | if (buflen == 0) | ||
637 | break; | ||
592 | if (mime->nmtp_parts > 1) | 638 | if (mime->nmtp_parts > 1) |
593 | { | 639 | { |
594 | size_t len; | 640 | size_t len; |
... | @@ -606,7 +652,8 @@ _mime_body_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) | ... | @@ -606,7 +652,8 @@ _mime_body_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) |
606 | while (mime->preamble) | 652 | while (mime->preamble) |
607 | { | 653 | { |
608 | mime->preamble--; | 654 | mime->preamble--; |
609 | ADD_CHAR (buf, '-', mime->cur_offset, buflen, *nbytes); | 655 | ADD_CHAR (buf, '-', mime->cur_offset, buflen, |
656 | total, nbytes); | ||
610 | } | 657 | } |
611 | len = strlen (mime->boundary) - mime->boundary_len; | 658 | len = strlen (mime->boundary) - mime->boundary_len; |
612 | while (mime->boundary_len) | 659 | while (mime->boundary_len) |
... | @@ -614,57 +661,89 @@ _mime_body_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) | ... | @@ -614,57 +661,89 @@ _mime_body_read (mu_stream_t stream, char *buf, size_t buflen, size_t *nbytes) |
614 | mime->boundary_len--; | 661 | mime->boundary_len--; |
615 | ADD_CHAR (buf, | 662 | ADD_CHAR (buf, |
616 | mime->boundary[len++], | 663 | mime->boundary[len++], |
617 | mime->cur_offset, buflen, *nbytes); | 664 | mime->cur_offset, buflen, |
665 | total, nbytes); | ||
618 | } | 666 | } |
619 | while (mime->postamble) | 667 | while (mime->postamble) |
620 | { | 668 | { |
621 | mime->postamble--; | 669 | mime->postamble--; |
622 | ADD_CHAR (buf, '-', mime->cur_offset, buflen, *nbytes); | 670 | ADD_CHAR (buf, '-', mime->cur_offset, buflen, |
671 | total, nbytes); | ||
623 | } | 672 | } |
624 | mime->flags &= | 673 | mime->flags &= |
625 | ~(MIME_INSERT_BOUNDARY | MIME_ADDING_BOUNDARY); | 674 | ~(MIME_INSERT_BOUNDARY | MIME_ADDING_BOUNDARY); |
626 | mime->part_offset = 0; | 675 | mime->part_offset = 0; |
627 | ADD_CHAR (buf, '\n', mime->cur_offset, buflen, *nbytes); | 676 | ADD_CHAR (buf, '\n', mime->cur_offset, buflen, |
677 | total, nbytes); | ||
628 | } | 678 | } |
679 | |||
680 | if (!mime->part_stream) | ||
681 | { | ||
629 | if (mime->cur_part >= mime->nmtp_parts) | 682 | if (mime->cur_part >= mime->nmtp_parts) |
683 | { | ||
684 | *nbytes = total; | ||
630 | return 0; | 685 | return 0; |
631 | mu_message_get_streamref (mime->mtp_parts[mime->cur_part]->msg, | ||
632 | &msg_stream); | ||
633 | } | 686 | } |
634 | else | 687 | ret = mu_message_get_streamref (mime->mtp_parts[mime->cur_part]->msg, |
688 | &mime->part_stream); | ||
689 | } | ||
690 | } | ||
691 | else if (!mime->part_stream) | ||
635 | { | 692 | { |
636 | mu_body_t part_body; | 693 | mu_body_t part_body; |
637 | 694 | ||
638 | if (mime->cur_part >= mime->nmtp_parts) | 695 | if (mime->cur_part >= mime->nmtp_parts) |
696 | { | ||
697 | *nbytes = total; | ||
639 | return 0; | 698 | return 0; |
699 | } | ||
640 | mu_message_get_body (mime->mtp_parts[mime->cur_part]->msg, | 700 | mu_message_get_body (mime->mtp_parts[mime->cur_part]->msg, |
641 | &part_body); | 701 | &part_body); |
642 | mu_body_get_streamref (part_body, &msg_stream); | 702 | ret = mu_body_get_streamref (part_body, &mime->part_stream); |
643 | } | 703 | } |
644 | mu_stream_seek (msg_stream, mime->part_offset, MU_SEEK_SET, NULL); | 704 | if (ret) |
645 | ret = mu_stream_read (msg_stream, buf, buflen, &part_nbytes); | 705 | break; |
706 | ret = mu_stream_seek (mime->part_stream, mime->part_offset, | ||
707 | MU_SEEK_SET, NULL); | ||
708 | if (ret) | ||
709 | { | ||
710 | mu_stream_destroy (&mime->part_stream); | ||
711 | break; | ||
712 | } | ||
713 | while (buflen > 0 && | ||
714 | (ret = mu_stream_read (mime->part_stream, buf, buflen, | ||
715 | &part_nbytes)) == 0) | ||
716 | { | ||
646 | if (part_nbytes) | 717 | if (part_nbytes) |
647 | { | 718 | { |
648 | mime->part_offset += part_nbytes; | 719 | mime->part_offset += part_nbytes; |
649 | mime->cur_offset += part_nbytes; | 720 | mime->cur_offset += part_nbytes; |
650 | if (nbytes) | 721 | total += part_nbytes; |
651 | *nbytes += part_nbytes; | 722 | buflen -= part_nbytes; |
723 | buf += part_nbytes; | ||
652 | } | 724 | } |
653 | if (ret == 0 && part_nbytes == 0) | 725 | else |
654 | { | 726 | { |
727 | mu_stream_destroy (&mime->part_stream); | ||
655 | mime->flags |= MIME_INSERT_BOUNDARY; | 728 | mime->flags |= MIME_INSERT_BOUNDARY; |
656 | mime->cur_part++; | 729 | mime->cur_part++; |
657 | ADD_CHAR (buf, '\n', mime->cur_offset, buflen, *nbytes); | 730 | ADD_CHAR (buf, '\n', mime->cur_offset, buflen, |
731 | total, nbytes); | ||
732 | break; | ||
658 | } | 733 | } |
659 | } | 734 | } |
660 | while (ret == 0 && part_nbytes == 0 | ||
661 | && mime->cur_part <= mime->nmtp_parts); | ||
662 | } | 735 | } |
736 | while (ret == 0 && mime->cur_part <= mime->nmtp_parts); | ||
737 | } | ||
738 | if (ret) | ||
739 | mu_stream_destroy (&mime->part_stream); | ||
740 | |||
741 | *nbytes = total; | ||
663 | return ret; | 742 | return ret; |
664 | } | 743 | } |
665 | 744 | ||
666 | static int | 745 | static int |
667 | _mime_body_ioctl (mu_stream_t stream, int code, void *arg) | 746 | _mime_body_stream_ioctl (mu_stream_t stream, int code, void *arg) |
668 | { | 747 | { |
669 | struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream; | 748 | struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream; |
670 | mu_mime_t mime = mstr->mime; | 749 | mu_mime_t mime = mstr->mime; |
... | @@ -694,16 +773,18 @@ _mime_body_ioctl (mu_stream_t stream, int code, void *arg) | ... | @@ -694,16 +773,18 @@ _mime_body_ioctl (mu_stream_t stream, int code, void *arg) |
694 | } | 773 | } |
695 | 774 | ||
696 | static int | 775 | static int |
697 | create_mime_body_stream (mu_stream_t *pstr) | 776 | create_mime_body_stream (mu_stream_t *pstr, mu_mime_t mime) |
698 | { | 777 | { |
699 | struct _mime_body_stream *sp = | 778 | struct _mime_body_stream *sp = |
700 | (struct _mime_body_stream *)_mu_stream_create (sizeof (*sp), | 779 | (struct _mime_body_stream *)_mu_stream_create (sizeof (*sp), |
701 | MU_STREAM_READ | MU_STREAM_SEEK); | 780 | MU_STREAM_READ | MU_STREAM_SEEK); |
702 | if (!sp) | 781 | if (!sp) |
703 | return ENOMEM; | 782 | return ENOMEM; |
704 | sp->stream.read = _mime_body_read; | 783 | sp->stream.read = _mime_body_stream_read; |
705 | sp->stream.seek = _mime_body_seek; | 784 | sp->stream.seek = _mime_body_stream_seek; |
706 | sp->stream.ctl = _mime_body_ioctl; | 785 | sp->stream.ctl = _mime_body_stream_ioctl; |
786 | sp->stream.size = _mime_body_stream_size; | ||
787 | sp->mime = mime; | ||
707 | *pstr = (mu_stream_t) sp; | 788 | *pstr = (mu_stream_t) sp; |
708 | return 0; | 789 | return 0; |
709 | } | 790 | } |
... | @@ -714,25 +795,7 @@ _mime_body_size (mu_body_t body, size_t *psize) | ... | @@ -714,25 +795,7 @@ _mime_body_size (mu_body_t body, size_t *psize) |
714 | { | 795 | { |
715 | mu_message_t msg = mu_body_get_owner (body); | 796 | mu_message_t msg = mu_body_get_owner (body); |
716 | mu_mime_t mime = mu_message_get_owner (msg); | 797 | mu_mime_t mime = mu_message_get_owner (msg); |
717 | int i, ret; | 798 | return _mime_part_size (mime, psize); |
718 | size_t size; | ||
719 | |||
720 | if (mime->nmtp_parts == 0) | ||
721 | return EINVAL; | ||
722 | |||
723 | if ((ret = _mime_set_content_type (mime)) != 0) | ||
724 | return ret; | ||
725 | for (i = 0; i < mime->nmtp_parts; i++) | ||
726 | { | ||
727 | mu_message_size (mime->mtp_parts[i]->msg, &size); | ||
728 | *psize += size; | ||
729 | if (mime->nmtp_parts > 1) /* boundary line */ | ||
730 | *psize += strlen (mime->boundary) + 3; | ||
731 | } | ||
732 | if (mime->nmtp_parts > 1) /* ending boundary line */ | ||
733 | *psize += 2; | ||
734 | |||
735 | return 0; | ||
736 | } | 799 | } |
737 | 800 | ||
738 | static int | 801 | static int |
... | @@ -851,6 +914,7 @@ mu_mime_destroy (mu_mime_t *pmime) | ... | @@ -851,6 +914,7 @@ mu_mime_destroy (mu_mime_t *pmime) |
851 | free (mime->mtp_parts); | 914 | free (mime->mtp_parts); |
852 | } | 915 | } |
853 | mu_stream_destroy (&mime->stream); | 916 | mu_stream_destroy (&mime->stream); |
917 | mu_stream_destroy (&mime->part_stream); | ||
854 | if (mime->msg && mime->flags & MIME_NEW_MESSAGE) | 918 | if (mime->msg && mime->flags & MIME_NEW_MESSAGE) |
855 | mu_message_destroy (&mime->msg, mime); | 919 | mu_message_destroy (&mime->msg, mime); |
856 | if (mime->content_type) | 920 | if (mime->content_type) |
... | @@ -973,7 +1037,7 @@ mu_mime_get_message (mu_mime_t mime, mu_message_t *msg) | ... | @@ -973,7 +1037,7 @@ mu_mime_get_message (mu_mime_t mime, mu_message_t *msg) |
973 | mu_message_set_body (mime->msg, body, mime); | 1037 | mu_message_set_body (mime->msg, body, mime); |
974 | mu_body_set_size (body, _mime_body_size, mime->msg); | 1038 | mu_body_set_size (body, _mime_body_size, mime->msg); |
975 | mu_body_set_lines (body, _mime_body_lines, mime->msg); | 1039 | mu_body_set_lines (body, _mime_body_lines, mime->msg); |
976 | ret = create_mime_body_stream (&body_stream); | 1040 | ret = create_mime_body_stream (&body_stream, mime); |
977 | if (ret == 0) | 1041 | if (ret == 0) |
978 | { | 1042 | { |
979 | mu_body_set_stream (body, body_stream, mime->msg); | 1043 | mu_body_set_stream (body, body_stream, mime->msg); | ... | ... |
... | @@ -26,62 +26,56 @@ PATTERN END | ... | @@ -26,62 +26,56 @@ PATTERN END |
26 | FILE BEGIN | 26 | FILE BEGIN |
27 | ENVELOPE FROM: coyote@desert.example.org | 27 | ENVELOPE FROM: coyote@desert.example.org |
28 | ENVELOPE TO: <gray@gnu.org> | 28 | ENVELOPE TO: <gray@gnu.org> |
29 | -re | 29 | 0: X-Loop-Prevention: foobar@nonexistent.net |
30 | 0: X-Authentication-Warning: [^ \t]+ set sender using -f flag | 30 | 1: From: coyote@desert.example.org |
31 | 1: X-Loop-Prevention: foobar@nonexistent.net | 31 | 2: To: roadrunner@acme.example.com |
32 | 2: From: coyote@desert.example.org | 32 | 3: Subject: I have a present for you |
33 | 3: To: roadrunner@acme.example.com | 33 | 4: X-Caffeine: C8H10N4O2 |
34 | 4: Subject: I have a present for you | 34 | 5: |
35 | 5: X-Caffeine: C8H10N4O2 | 35 | 6: Look, I'm sorry about the whole anvil thing, and I really |
36 | 6: | 36 | 7: didn't mean to try and drop it on you from the top of the |
37 | 7: Look, I'm sorry about the whole anvil thing, and I really | 37 | 8: cliff. I want to try to make it up to you. I've got some |
38 | 8: didn't mean to try and drop it on you from the top of the | 38 | 9: great birdseed over here at my place--top of the line |
39 | 9: cliff. I want to try to make it up to you. I've got some | 39 | 10: stuff--and if you come by, I'll have it all wrapped up |
40 | 10: great birdseed over here at my place--top of the line | 40 | 11: for you. I'm really sorry for all the problems I've caused |
41 | 11: stuff--and if you come by, I'll have it all wrapped up | 41 | 12: for you over the years, but I know we can work this out. |
42 | 12: for you. I'm really sorry for all the problems I've caused | 42 | 13: |
43 | 13: for you over the years, but I know we can work this out. | 43 | 14: -- |
44 | 14: | 44 | 15: Wile E. Coyote "Super Genius" coyote@desert.example.org |
45 | 15: -- | 45 | 16: |
46 | 16: Wile E. Coyote "Super Genius" coyote@desert.example.org | ||
47 | 17: | ||
48 | END OF MESSAGE | 46 | END OF MESSAGE |
49 | ENVELOPE FROM: b1ff@de.res.example.com | 47 | ENVELOPE FROM: b1ff@de.res.example.com |
50 | ENVELOPE TO: <gray@gnu.org> | 48 | ENVELOPE TO: <gray@gnu.org> |
51 | -re | 49 | 0: X-Loop-Prevention: foobar@nonexistent.net |
52 | 0: X-Authentication-Warning: [^ \t]+ set sender using -f flag | 50 | 1: From: youcouldberich!@reply-by-postal-mail.invalid |
53 | 1: X-Loop-Prevention: foobar@nonexistent.net | 51 | 2: To: rube@landru.example.edu |
54 | 2: From: youcouldberich!@reply-by-postal-mail.invalid | 52 | 3: Subject: $$$ YOU, TOO, CAN BE A MILLIONAIRE! $$$ |
55 | 3: To: rube@landru.example.edu | 53 | 4: Date: TBD |
56 | 4: Subject: $$$ YOU, TOO, CAN BE A MILLIONAIRE! $$$ | 54 | 5: X-Number: 0015 |
57 | 5: Date: TBD | 55 | 6: |
58 | 6: X-Number: 0015 | 56 | 7: YOU MAY HAVE ALREADY WON TEN MILLION DOLLARS, BUT I DOUBT |
59 | 7: | 57 | 8: IT! SO JUST POST THIS TO SIX HUNDRED NEWSGROUPS! IT WILL |
60 | 8: YOU MAY HAVE ALREADY WON TEN MILLION DOLLARS, BUT I DOUBT | 58 | 9: GUARANTEE THAT YOU GET AT LEAST FIVE RESPONSES WITH MONEY! |
61 | 9: IT! SO JUST POST THIS TO SIX HUNDRED NEWSGROUPS! IT WILL | 59 | 10: MONEY! MONEY! COLD HARD CASH! YOU WILL RECEIVE OVER |
62 | 10: GUARANTEE THAT YOU GET AT LEAST FIVE RESPONSES WITH MONEY! | 60 | 11: $20,000 IN LESS THAN TWO MONTHS! AND IT'S LEGAL!!!!!!!!! |
63 | 11: MONEY! MONEY! COLD HARD CASH! YOU WILL RECEIVE OVER | 61 | 12: !!!!!!!!!!!!!!!!!!111111111!!!!!!!11111111111!!1 JUST |
64 | 12: $20,000 IN LESS THAN TWO MONTHS! AND IT'S LEGAL!!!!!!!!! | 62 | 13: SEND $5 IN SMALL, UNMARKED BILLS TO THE ADDRESSES BELOW! |
65 | 13: !!!!!!!!!!!!!!!!!!111111111!!!!!!!11111111111!!1 JUST | 63 | 14: |
66 | 14: SEND $5 IN SMALL, UNMARKED BILLS TO THE ADDRESSES BELOW! | ||
67 | 15: | ||
68 | END OF MESSAGE | 64 | END OF MESSAGE |
69 | ENVELOPE FROM: bar@dontmailme.org | 65 | ENVELOPE FROM: bar@dontmailme.org |
70 | ENVELOPE TO: <gray@gnu.org> | 66 | ENVELOPE TO: <gray@gnu.org> |
71 | -re | 67 | 0: X-Loop-Prevention: foobar@nonexistent.net |
72 | 0: X-Authentication-Warning: [^ \t]+ set sender using -f flag | 68 | 1: Received: (from bar@dontmailme.org) |
73 | 1: X-Loop-Prevention: foobar@nonexistent.net | 69 | 2: by dontmailme.org id fERKR9N16790 |
74 | 2: Received: (from bar@dontmailme.org) | 70 | 3: for foobar@nonexistent.net; Fri, 28 Dec 2001 22:18:08 +0200 |
75 | 3: by dontmailme.org id fERKR9N16790 | 71 | 4: Date: Fri, 28 Dec 2001 23:28:08 +0200 |
76 | 4: for foobar@nonexistent.net; Fri, 28 Dec 2001 22:18:08 +0200 | 72 | 5: From: Bar <bar@dontmailme.org> |
77 | 5: Date: Fri, 28 Dec 2001 23:28:08 +0200 | 73 | 6: To: Foo Bar <foobar@nonexistent.net> |
78 | 6: From: Bar <bar@dontmailme.org> | 74 | 7: Message-Id: <200112232808.fERKR9N16790@dontmailme.org> |
79 | 7: To: Foo Bar <foobar@nonexistent.net> | 75 | 8: Subject: Coffee |
80 | 8: Message-Id: <200112232808.fERKR9N16790@dontmailme.org> | 76 | 9: |
81 | 9: Subject: Coffee | 77 | 10: How about some coffee? |
82 | 10: | 78 | 11: |
83 | 11: How about some coffee? | ||
84 | 12: | ||
85 | END OF MESSAGE | 79 | END OF MESSAGE |
86 | FILE END | 80 | FILE END |
87 | TEST END | 81 | TEST END | ... | ... |
This diff is collapsed.
Click to expand it.
-
Please register or sign in to post a comment