summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-08-06 21:13:17 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-08-06 21:23:26 +0300
commit6b4df0a20f5a18a4be266fade0a4979a4decf23b (patch)
treed11b72596c97a77e5c1f4b5171496c254f30100d
parentad04463ee93ebd10a65fe9e128919a2dd735a534 (diff)
downloadmailutils-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.c35
-rw-r--r--include/mailutils/stream.h6
-rw-r--r--libmailutils/stream/streamcpy.c71
-rw-r--r--libproto/mbox/mbox.c6
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)

Return to:

Send suggestions and report system problems to the System administrator.