diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-08-06 21:13:17 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-08-06 21:23:26 +0300 |
commit | 6b4df0a20f5a18a4be266fade0a4979a4decf23b (patch) | |
tree | d11b72596c97a77e5c1f4b5171496c254f30100d | |
parent | ad04463ee93ebd10a65fe9e128919a2dd735a534 (diff) | |
download | mailutils-6b4df0a20f5a18a4be266fade0a4979a4decf23b.tar.gz mailutils-6b4df0a20f5a18a4be266fade0a4979a4decf23b.tar.bz2 |
decodemail: make sure each message has the final newline on its own
* include/mailutils/stream.h (mu_stream_copy_wcb)
(mu_stream_copy_nl): New protos.
* libmailutils/stream/streamcpy.c (mu_stream_copy_wcb)
(mu_stream_copy_nl): New functions.
* libproto/mbox/mbox.c (append_message_to_stream): Use mu_stream_copy_nl.
* decodemail/decodemail.c (hdr_print, body_print): Remove.
(message_store_stdout): Use message stream instead of piping
header and body separately.
Use mu_stream_copy_nl to ensure the message has a final newline.
-rw-r--r-- | decodemail/decodemail.c | 35 | ||||
-rw-r--r-- | include/mailutils/stream.h | 6 | ||||
-rw-r--r-- | libmailutils/stream/streamcpy.c | 71 | ||||
-rw-r--r-- | libproto/mbox/mbox.c | 6 |
4 files changed, 72 insertions, 46 deletions
diff --git a/decodemail/decodemail.c b/decodemail/decodemail.c index ea0e981fa..e954eaec0 100644 --- a/decodemail/decodemail.c +++ b/decodemail/decodemail.c @@ -310,41 +310,14 @@ env_print (mu_message_t msg) } static void -hdr_print (mu_message_t msg) +message_store_stdout (mu_message_t msg, mu_mailbox_t mbx) { - mu_header_t hdr; mu_stream_t str; - - mu_message_get_header (msg, &hdr); - mu_header_get_streamref (hdr, &str); - mu_stream_copy (mu_strout, str, 0, NULL); - mu_stream_destroy (&str); -} -static void -body_print (mu_message_t msg) -{ - int rc; - mu_body_t body; - mu_stream_t str; - - mu_message_get_body (msg, &body); - rc = mu_body_get_streamref (body, &str); - if (rc) - { - mu_error (_("cannot get body stream: %s"), mu_strerror (rc)); - exit (EX_OSERR); - } - mu_stream_copy (mu_strout, str, 0, NULL); - mu_stream_destroy (&str); -} - -static void -message_store_stdout (mu_message_t msg, mu_mailbox_t mbx) -{ env_print (msg); - hdr_print (msg); - body_print (msg); + mu_message_get_streamref (msg, &str); + mu_stream_copy_nl (mu_strout, str, 0, NULL); + mu_stream_destroy (&str); mu_printf ("\n"); } diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h index 4843dc178..a91f168de 100644 --- a/include/mailutils/stream.h +++ b/include/mailutils/stream.h @@ -371,6 +371,12 @@ int mu_stream_printf (mu_stream_t stream, const char *fmt, ...) int mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, mu_off_t *pcsz); +int mu_stream_copy_wcb (mu_stream_t dst, mu_stream_t src, mu_off_t size, + void (*cbf) (char *, size_t, void *), void *cbd, + mu_off_t *pcsz); +int mu_stream_copy_nl (mu_stream_t dst, mu_stream_t src, mu_off_t size, + mu_off_t *pcsz); + int mu_stream_header_copy (mu_stream_t dst, mu_stream_t src, char **exclude_names); int mu_stream_shift (mu_stream_t str, mu_off_t off_a, mu_off_t off_b, diff --git a/libmailutils/stream/streamcpy.c b/libmailutils/stream/streamcpy.c index d375d6941..884b997d2 100644 --- a/libmailutils/stream/streamcpy.c +++ b/libmailutils/stream/streamcpy.c @@ -29,10 +29,16 @@ #define STREAMCPY_MAX_BUF_SIZE 16384 /* Copy SIZE bytes from SRC to DST. If SIZE is 0, copy everything up to - EOF. */ + EOF. + If the callback function CBF is not NULL, it will be called for + each buffer-full of data read with the following arguments: pointer to + the buffer, length of the data portion in buffer, pointer to the user- + supplied callback data (CBD). +*/ int -mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, - mu_off_t *pcsz) +mu_stream_copy_wcb (mu_stream_t dst, mu_stream_t src, mu_off_t size, + void (*cbf) (char *, size_t, void *), void *cbd, + mu_off_t *pcsz) { int status; size_t bufsize, n; @@ -100,6 +106,8 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, break; if (n == 0) break; + if (cbf) + cbf (buf, n, cbd); status = mu_stream_write (dst, buf, n, NULL); if (status) break; @@ -111,15 +119,19 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, status = EIO; } else - while ((status = mu_stream_read (src, buf, bufsize, &n)) == 0 - && n > 0) - { - status = mu_stream_write (dst, buf, n, NULL); - if (status) - break; - total += n; - } - + { + while ((status = mu_stream_read (src, buf, bufsize, &n)) == 0 + && n > 0) + { + if (cbf) + cbf (buf, n, cbd); + status = mu_stream_write (dst, buf, n, NULL); + if (status) + break; + total += n; + } + } + if (pcsz) *pcsz = total; /* FIXME: When EOF error code is implemented: @@ -129,3 +141,38 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, free (buf); return status; } + +/* Copy SIZE bytes from SRC to DST. If SIZE is 0, copy everything up to + EOF. */ +int +mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, + mu_off_t *pcsz) +{ + return mu_stream_copy_wcb (dst, src, size, NULL, NULL, pcsz); +} + +static void +capture_last_char (char *buf, size_t size, void *data) +{ + *(char*)data = buf[size-1]; +} + +/* Same as mu_stream_copy, but also ensures that the copied data end with + a '\n' character. */ +int +mu_stream_copy_nl (mu_stream_t dst, mu_stream_t src, mu_off_t size, + mu_off_t *pcsz) +{ + char lc; + int status = mu_stream_copy_wcb (dst, src, size, capture_last_char, &lc, + pcsz); + if (status == 0 && lc != '\n') + { + status = mu_stream_write (dst, "\n", 1, NULL); + if (status == 0 && pcsz) + ++ *pcsz; + } + return status; +} + + diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c index 0eecfb080..7e0a2c69e 100644 --- a/libproto/mbox/mbox.c +++ b/libproto/mbox/mbox.c @@ -1099,10 +1099,10 @@ append_message_to_stream (mu_stream_t ostr, mu_message_t msg, mu_stream_unref (istr); if (status == 0) { - status = mu_stream_copy (ostr, flt, 0, NULL); + status = mu_stream_copy_nl (ostr, flt, 0, NULL); mu_stream_destroy (&flt); if (status == 0) - status = mu_stream_write (ostr, "\n", 1, NULL); + status = mu_stream_write (ostr, "\n", 1, NULL); } return status; @@ -1270,7 +1270,7 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t dirty, int remove_deleted, } status = mu_stream_copy (tempstr, mailbox->stream, mum->body_end - mum->envel_from, NULL); - /* Terminate messate with an empty line */ + /* Terminate message with an empty line */ if (status == 0) status = mu_stream_write (tempstr, "\n", 1, NULL); if (status) |