summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-08-07 17:29:30 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-08-07 17:51:48 +0300
commitb8553fee2f6da26406b7571e5dcfd2f4d604fe57 (patch)
treeb8d285178e8dbadf9fb606dd4b3150a25a33e4ae
parent5fe88d71121bd4a5c3afb83b5ed1b8d775429fa4 (diff)
downloadmailutils-b8553fee2f6da26406b7571e5dcfd2f4d604fe57.tar.gz
mailutils-b8553fee2f6da26406b7571e5dcfd2f4d604fe57.tar.bz2
stream API: remove the readdelim method
The method is superfluous as the API itself provides the necessary functionality. Besides, it interacted poorly with positioning in buffered streams. * include/mailutils/sys/stream.h (struct _mu_stream): Remove the readdelim method. * libmailutils/stream/stream.c (mu_stream_readdelim) (mu_stream_getdelim): Remove uses of the readdelim method. * libmailutils/tests/.gitignore: Update. * libmailutils/tests/Makefile.am: Add new test. * libmailutils/tests/testsuite.at: Likewise. * libmailutils/tests/getdelim.at: New test. * libmailutils/tests/stream-getdelim.c: New test program. * libmailutils/base/amd.c: Remove readdelim implementation. * libmailutils/mailbox/msgstream.c: Likewise. * libmailutils/stream/iostream.c: Likewise. * libmailutils/stream/streamref.c: Likewise. * libmailutils/stream/xscript-stream.c: Likewise. * libproto/pop/pop3_stream.c: Likewise. * mail/decode.c (mime_descend): Handle errors from mu_message_unencapsulate graciously. On failure, treat message/rfc822 as text/plain.
-rw-r--r--include/mailutils/sys/stream.h1
-rw-r--r--libmailutils/base/amd.c62
-rw-r--r--libmailutils/mailbox/msgstream.c32
-rw-r--r--libmailutils/stream/iostream.c14
-rw-r--r--libmailutils/stream/stream.c21
-rw-r--r--libmailutils/stream/streamref.c36
-rw-r--r--libmailutils/stream/xscript-stream.c10
-rw-r--r--libmailutils/tests/.gitignore1
-rw-r--r--libmailutils/tests/Makefile.am2
-rw-r--r--libmailutils/tests/getdelim.at12
-rw-r--r--libmailutils/tests/stream-getdelim.c218
-rw-r--r--libmailutils/tests/testsuite.at1
-rw-r--r--libproto/pop/pop3_stream.c26
-rw-r--r--mail/decode.c59
14 files changed, 297 insertions, 198 deletions
diff --git a/include/mailutils/sys/stream.h b/include/mailutils/sys/stream.h
index 203ddf64e..44349bddd 100644
--- a/include/mailutils/sys/stream.h
+++ b/include/mailutils/sys/stream.h
@@ -53,7 +53,6 @@ struct _mu_stream
int last_err;
int (*read) (struct _mu_stream *, char *, size_t, size_t *);
- int (*readdelim) (struct _mu_stream *, char *, size_t, int, size_t *);
int (*write) (struct _mu_stream *, const char *, size_t, size_t *);
int (*flush) (struct _mu_stream *);
int (*open) (struct _mu_stream *);
diff --git a/libmailutils/base/amd.c b/libmailutils/base/amd.c
index 115f9e73d..04a373160 100644
--- a/libmailutils/base/amd.c
+++ b/libmailutils/base/amd.c
@@ -111,10 +111,6 @@ static int amd_remove_mbox (mu_mailbox_t mailbox);
static int amd_body_stream_read (mu_stream_t str, char *buffer,
size_t buflen,
size_t *pnread);
-static int amd_body_stream_readdelim (mu_stream_t is,
- char *buffer, size_t buflen,
- int delim,
- size_t *pnread);
static int amd_body_stream_size (mu_stream_t str, mu_off_t *psize);
static int amd_body_stream_seek (mu_stream_t str, mu_off_t off,
mu_off_t *presult);
@@ -617,7 +613,6 @@ _amd_attach_message (mu_mailbox_t mailbox, struct _amd_message *mhm,
return ENOMEM;
}
str->stream.read = amd_body_stream_read;
- str->stream.readdelim = amd_body_stream_readdelim;
str->stream.size = amd_body_stream_size;
str->stream.seek = amd_body_stream_seek;
mu_body_set_stream (body, (mu_stream_t) str, msg);
@@ -1921,63 +1916,6 @@ amd_body_stream_read (mu_stream_t is, char *buffer, size_t buflen,
}
static int
-amd_body_stream_readdelim (mu_stream_t is, char *buffer, size_t buflen,
- int delim,
- size_t *pnread)
-{
- struct _amd_body_stream *amdstr = (struct _amd_body_stream *)is;
- mu_body_t body = amdstr->body;
- mu_message_t msg = mu_body_get_owner (body);
- struct _amd_message *mhm = mu_message_get_owner (msg);
- int status = 0;
-
- status = amd_pool_open (mhm);
- if (status)
- return status;
-
- if (buffer == NULL || buflen == 0)
- {
- if (pnread)
- *pnread = 0;
- return 0;
- }
-
- mu_monitor_rdlock (mhm->amd->mailbox->monitor);
-#ifdef WITH_PTHREAD
- /* read() is cancellation point since we're doing a potentially
- long operation. Lets make sure we clean the state. */
- pthread_cleanup_push (amd_cleanup, (void *)mhm->amd->mailbox);
-#endif
-
- status = mu_stream_seek (mhm->stream, mhm->body_start + amdstr->off,
- MU_SEEK_SET, NULL);
- if (status == 0)
- {
- size_t nread = 0;
- size_t ln;
-
- ln = mhm->body_end - (mhm->body_start + amdstr->off) + 1;
- if (ln > 0)
- {
- size_t rdsize = ((size_t)ln < buflen) ? (size_t)ln : buflen;
- status = mu_stream_readdelim (mhm->stream, buffer, rdsize,
- delim, &nread);
- amdstr->off += nread;
- }
-
- if (pnread)
- *pnread = nread;
- }
-
- mu_monitor_unlock (mhm->amd->mailbox->monitor);
-#ifdef WITH_PTHREAD
- pthread_cleanup_pop (0);
-#endif
-
- return status;
-}
-
-static int
amd_body_stream_seek (mu_stream_t str, mu_off_t off, mu_off_t *presult)
{
int rc;
diff --git a/libmailutils/mailbox/msgstream.c b/libmailutils/mailbox/msgstream.c
index a1cf4825b..f43d765cd 100644
--- a/libmailutils/mailbox/msgstream.c
+++ b/libmailutils/mailbox/msgstream.c
@@ -206,37 +206,6 @@ _message_stream_read (struct _mu_stream *str, char *buf, size_t bufsize,
return rc;
}
-static int
-_message_stream_readdelim (struct _mu_stream *str, char *buf, size_t bufsize,
- int delim, size_t *pnread)
-{
- struct _mu_message_stream *sp = (struct _mu_message_stream *)str;
- size_t nread = 0;
- int rc;
-
- while (bufsize)
- {
- size_t n;
- rc = _check_stream_state (sp);
- if (rc)
- break;
- if (sp->state == _mss_eof)
- break;
- rc = mu_stream_readdelim (sp->transport, buf, bufsize, delim, &n);
- if (rc)
- break;
- if (n == 0)
- continue;
- nread += n;
- if (buf[n-1] == delim)
- break;
- buf += n;
- bufsize -= n;
- }
- *pnread = nread;
- return rc;
-}
-
#if 0
static int
_message_stream_write (struct _mu_stream *str,
@@ -262,7 +231,6 @@ _message_stream_create (mu_stream_t *pmsg, mu_message_t msg, int flags)
return ENOMEM;
sp->stream.read = _message_stream_read;
- sp->stream.readdelim = _message_stream_readdelim;
/* FIXME: Write is not defined */
/* sp->stream.write = _message_stream_write;*/
sp->stream.done = _message_stream_done;
diff --git a/libmailutils/stream/iostream.c b/libmailutils/stream/iostream.c
index 7045bb508..4a4647480 100644
--- a/libmailutils/stream/iostream.c
+++ b/libmailutils/stream/iostream.c
@@ -43,18 +43,6 @@ _iostream_read (struct _mu_stream *str, char *buf, size_t bufsize,
}
static int
-_iostream_readdelim (struct _mu_stream *str, char *buf, size_t bufsize,
- int delim, size_t *pnread)
-{
- struct _mu_iostream *sp = (struct _mu_iostream *)str;
- int rc = mu_stream_readdelim (sp->transport[_MU_STREAM_INPUT], buf,
- bufsize, delim, pnread);
- if (rc)
- sp->last_err_str = _MU_STREAM_INPUT;
- return rc;
-}
-
-static int
_iostream_write (struct _mu_stream *str, const char *buf, size_t bufsize,
size_t *pnwrite)
{
@@ -275,8 +263,6 @@ mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out)
sp->stream.flags |= _MU_STR_OPEN;
sp->stream.read = _iostream_read;
- if (in->readdelim)
- sp->stream.readdelim = _iostream_readdelim;
sp->stream.write = _iostream_write;
sp->stream.flush = _iostream_flush;
sp->stream.open = _iostream_open;
diff --git a/libmailutils/stream/stream.c b/libmailutils/stream/stream.c
index 97af34054..0131e3b52 100644
--- a/libmailutils/stream/stream.c
+++ b/libmailutils/stream/stream.c
@@ -864,16 +864,7 @@ mu_stream_readdelim (mu_stream_t stream, char *buf, size_t size,
if (stream->buftype == mu_buffer_none)
{
- if (stream->readdelim)
- {
- size_t nread;
- rc = stream->readdelim (stream, buf, size, delim, &nread);
- if (pread)
- *pread = nread;
- stream->offset += nread;
- }
- else
- rc = _stream_readdelim (stream, buf, size, delim, pread);
+ rc = _stream_readdelim (stream, buf, size, delim, pread);
}
else
{
@@ -952,14 +943,12 @@ mu_stream_getdelim (mu_stream_t stream, char **pbuf, size_t *psize,
n = needed;
}
- if (stream->readdelim)
- rc = stream->readdelim (stream, lineptr + cur_len, n - cur_len, delim,
- &rdn);
- else if (stream->buftype != mu_buffer_none)
+ if (stream->buftype == mu_buffer_none)
+ rc = _stream_readdelim (stream, lineptr + cur_len, n - cur_len, delim,
+ &rdn);
+ else
rc = _stream_scandelim (stream, lineptr + cur_len, n - cur_len, delim,
&rdn);
- else
- rc = mu_stream_read (stream, lineptr + cur_len, 1, &rdn);
if (rc || rdn == 0)
break;
diff --git a/libmailutils/stream/streamref.c b/libmailutils/stream/streamref.c
index 74a5f5f92..65a3b9ed2 100644
--- a/libmailutils/stream/streamref.c
+++ b/libmailutils/stream/streamref.c
@@ -59,40 +59,6 @@ _streamref_read (struct _mu_stream *str, char *buf, size_t bufsize,
}
static int
-_streamref_readdelim (struct _mu_stream *str, char *buf, size_t bufsize,
- int delim, size_t *pnread)
-{
- struct _mu_streamref *sp = (struct _mu_streamref *)str;
- int rc;
- size_t nread;
- mu_off_t off;
-
- rc = mu_stream_seek (sp->transport, sp->offset, MU_SEEK_SET, &off);
- if (rc == 0)
- {
- rc = mu_stream_readdelim (sp->transport, buf, bufsize, delim, &nread);
- if (rc == 0)
- {
- if (sp->end)
- {
- size_t size = sp->end - off + 1;
- if (nread > size)
- nread = size;
- }
- sp->offset += nread;
- *pnread = nread;
- }
- }
- else if (rc == ESPIPE)
- {
- *pnread = 0;
- mu_stream_clearerr (sp->transport);
- return 0;
- }
- return rc;
-}
-
-static int
_streamref_write (struct _mu_stream *str, const char *buf, size_t bufsize,
size_t *pnwrite)
{
@@ -274,8 +240,6 @@ mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str,
mu_stream_ref (str);
sp->stream.read = _streamref_read;
- if (str->readdelim)
- sp->stream.readdelim = _streamref_readdelim;
sp->stream.write = _streamref_write;
sp->stream.flush = _streamref_flush;
sp->stream.open = _streamref_open;
diff --git a/libmailutils/stream/xscript-stream.c b/libmailutils/stream/xscript-stream.c
index 581110d70..3a3f09598 100644
--- a/libmailutils/stream/xscript-stream.c
+++ b/libmailutils/stream/xscript-stream.c
@@ -310,14 +310,6 @@ _xscript_read (struct _mu_stream *str, char *buf, size_t bufsize,
}
static int
-_xscript_readdelim (struct _mu_stream *str, char *buf, size_t bufsize,
- int delim, size_t *pnread)
-{
- struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
- return mu_stream_readdelim (sp->transport, buf, bufsize, delim, pnread);
-}
-
-static int
_xscript_write (struct _mu_stream *str, const char *buf, size_t bufsize,
size_t *pnwrite)
{
@@ -582,8 +574,6 @@ mu_xscript_stream_create (mu_stream_t *pref, mu_stream_t transport,
return ENOMEM;
sp->stream.read = _xscript_read;
- if (transport->readdelim)
- sp->stream.readdelim = _xscript_readdelim;
sp->stream.write = _xscript_write;
sp->stream.flush = _xscript_flush;
sp->stream.open = _xscript_open;
diff --git a/libmailutils/tests/.gitignore b/libmailutils/tests/.gitignore
index 6b4229a6b..591f9befd 100644
--- a/libmailutils/tests/.gitignore
+++ b/libmailutils/tests/.gitignore
@@ -55,3 +55,4 @@ t1-stream
t-streamshift
recenv
readmesg
+stream-getdelim
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index bd0b781c0..cdaec679f 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -59,6 +59,7 @@ noinst_PROGRAMS = \
readmesg\
recenv\
scantime\
+ stream-getdelim\
strftime\
strin\
strout\
@@ -108,6 +109,7 @@ TESTSUITE_AT += \
fsfolder02.at\
fsfolder03.at\
fsfolder04.at\
+ getdelim.at\
hdrcpy.at\
hdrflt.at\
htmlent.at\
diff --git a/libmailutils/tests/getdelim.at b/libmailutils/tests/getdelim.at
new file mode 100644
index 000000000..493412e64
--- /dev/null
+++ b/libmailutils/tests/getdelim.at
@@ -0,0 +1,12 @@
+AT_SETUP([getdelim])
+AT_CHECK([stream-getdelim],
+[0],
+[0: No buffering
+1: Linear buffering
+2: Linear buffering (small buffer)
+3: Full buffering (big buffer)
+4: Full buffering (moderate buffer)
+5: Full buffering (small buffer)
+])
+AT_CLEANUP
+
diff --git a/libmailutils/tests/stream-getdelim.c b/libmailutils/tests/stream-getdelim.c
new file mode 100644
index 000000000..075afa9f9
--- /dev/null
+++ b/libmailutils/tests/stream-getdelim.c
@@ -0,0 +1,218 @@
+/*
+NAME
+ stream-getdelim - test the mu_stream_getdelim function.
+
+DESCRIPTION
+ This implements a simple memory-based stream implementation and
+ tests mu_stream_getdelim on a predefined stream content with various
+ combinations of buffering type and buffer size settings.
+
+ On success, returns 0. On error, prints diagnostics on stderr and
+ exits with a non-0 code or aborts.
+
+ Before running each test, its short description is printed on stdout.
+
+ For obvious reasons, libc functions are used for output.
+
+LICENSE
+ This file is part of GNU mailutils.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <mailutils/types.h>
+#include <mailutils/debug.h>
+#include <mailutils/errno.h>
+#include <mailutils/stream.h>
+#include <mailutils/sys/stream.h>
+
+char content[] =
+ "AB\n"
+ "\n"
+ "\n"
+ "CDEFG\n"
+ "H\n"
+ "IJ\n"
+ "KLMNOPQRST\n"
+ "UVWXYZ";
+
+struct test_stream
+{
+ struct _mu_stream stream;
+ char *ptr;
+ size_t size;
+ mu_off_t offset;
+};
+
+static int
+ts_open (mu_stream_t stream)
+{
+ struct test_stream *ts = (struct test_stream *) stream;
+ ts->ptr = content;
+ ts->size = strlen (content);
+ ts->offset = 0;
+ return 0;
+}
+
+static int
+ts_read (mu_stream_t stream, char *optr, size_t osize, size_t *nbytes)
+{
+ struct test_stream *ts = (struct test_stream *) stream;
+ size_t n = 0;
+ if (ts->ptr != NULL && ((size_t)ts->offset <= ts->size))
+ {
+ n = ts->size - ts->offset;
+ if (n > osize)
+ n = osize;
+ memcpy (optr, ts->ptr + ts->offset, n);
+ ts->offset += n;
+ }
+ if (nbytes)
+ *nbytes = n;
+ return 0;
+}
+
+static int
+ts_seek (mu_stream_t stream, mu_off_t off, mu_off_t *presult)
+{
+ struct test_stream *ts = (struct test_stream *) stream;
+
+ if (off < 0)
+ return ESPIPE;
+ ts->offset = off;
+ *presult = off;
+ return 0;
+}
+
+static int
+ts_size (mu_stream_t stream, mu_off_t *psize)
+{
+ struct test_stream *ts = (struct test_stream *) stream;
+ *psize = ts->size;
+ return 0;
+}
+
+int
+test_stream_create (mu_stream_t *pstream)
+{
+ int rc;
+ mu_stream_t stream;
+
+ stream = _mu_stream_create (sizeof (struct test_stream), MU_STREAM_READ|MU_STREAM_SEEK);
+ assert (stream != NULL);
+
+ stream->open = ts_open;
+ stream->read = ts_read;
+ stream->size = ts_size;
+ stream->seek = ts_seek;
+
+ rc = mu_stream_open (stream);
+ if (rc)
+ mu_stream_destroy (&stream);
+ else
+ *pstream = stream;
+
+ return rc;
+}
+
+void
+runtest (mu_stream_t str)
+{
+ char *buf = NULL;
+ size_t size = 0;
+ mu_off_t off;
+ size_t n;
+ int rc;
+ unsigned long start = 0;
+
+ MU_ASSERT (mu_stream_seek (str, 0, MU_SEEK_SET, NULL));
+
+ while ((rc = mu_stream_getdelim (str, &buf, &size, '\n', &n)) == 0
+ && n > 0)
+ {
+ size_t blen = strlen (buf);
+ size_t len = strcspn (content + start, "\n");
+ if (content[start+len] == '\n')
+ len++;
+ if (len != blen || memcmp (content + start, buf, len))
+ {
+ fprintf (stderr, "at %lu: expected:\n", start);
+ fwrite (content + start, blen, 1, stderr);
+ fprintf (stderr, "\nfound:\n");
+ fwrite (buf, blen, 1, stderr);
+ fputc ('\n', stderr);
+ exit (1);
+ }
+ start += len;
+
+ MU_ASSERT (mu_stream_seek (str, 0, MU_SEEK_CUR, &off));
+ if (off != start)
+ {
+ fprintf (stderr, "wrong offset reported (%lu, expected %lu\n",
+ (unsigned long)off, (unsigned long)start);
+ exit (2);
+ }
+ }
+ if (rc)
+ {
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_getline", NULL, rc);
+ exit (1);
+ }
+ free (buf);
+}
+
+#define TESTBUFSIZE 512
+
+static struct test
+{
+ char *name;
+ enum mu_buffer_type type;
+ size_t size;
+} testtab[] = {
+ { "No buffering", mu_buffer_none, 0 },
+ { "Linear buffering", mu_buffer_line, TESTBUFSIZE },
+ { "Linear buffering (small buffer)", mu_buffer_line, 1 },
+ { "Full buffering (big buffer)", mu_buffer_full, TESTBUFSIZE },
+ { "Full buffering (moderate buffer)", mu_buffer_full, sizeof(content)/2 },
+ { "Full buffering (small buffer)", mu_buffer_full, 1 },
+ { NULL }
+};
+
+int
+main (int argc, char **argv)
+{
+ mu_stream_t str;
+ int i;
+
+ MU_ASSERT (test_stream_create (&str));
+
+ for (i = 0; testtab[i].name; i++)
+ {
+ printf ("%d: %s\n", i, testtab[i].name);
+ MU_ASSERT (mu_stream_set_buffer (str, testtab[i].type, testtab[i].size));
+ runtest (str);
+ }
+
+ mu_stream_destroy (&str);
+ return 0;
+}
diff --git a/libmailutils/tests/testsuite.at b/libmailutils/tests/testsuite.at
index 01bdfc33e..2ca2f7386 100644
--- a/libmailutils/tests/testsuite.at
+++ b/libmailutils/tests/testsuite.at
@@ -102,6 +102,7 @@ AT_BANNER([Basic streams])
m4_include([t0-stream.at])
m4_include([t1-stream.at])
m4_include([streamshift.at])
+m4_include([getdelim.at])
AT_BANNER([Conversions])
m4_include([strtoc.at])
diff --git a/libproto/pop/pop3_stream.c b/libproto/pop/pop3_stream.c
index 3a2b0e4d2..3b58ca6ae 100644
--- a/libproto/pop/pop3_stream.c
+++ b/libproto/pop/pop3_stream.c
@@ -127,31 +127,6 @@ _mu_pop3_read (struct _mu_stream *str, char *buf, size_t bufsize,
}
static int
-_mu_pop3_readdelim (struct _mu_stream *str, char *buf, size_t bufsize,
- int delim, size_t *pnread)
-{
- struct mu_pop3_stream *sp = (struct mu_pop3_stream *)str;
- mu_pop3_t pop3 = sp->pop3;
- size_t nread;
- int status = 0;
-
- if (sp->flags & _POP3F_DONE)
- nread = 0;
- else
- {
- status = mu_stream_readdelim (pop3->carrier, buf, bufsize, delim,
- &nread);
- if (status == 0 && nread == 0)
- {
- pop3->state = MU_POP3_NO_STATE;
- sp->flags |= _POP3F_DONE;
- }
- }
- *pnread = nread;
- return status;
-}
-
-static int
_mu_pop3_flush (struct _mu_stream *str)
{
struct mu_pop3_stream *sp = (struct mu_pop3_stream *)str;
@@ -180,7 +155,6 @@ mu_pop3_stream_create (mu_pop3_t pop3, mu_stream_t *pstream)
if (!sp)
return ENOMEM;
sp->stream.read = _mu_pop3_read;
- sp->stream.readdelim = _mu_pop3_readdelim;
sp->stream.flush = _mu_pop3_flush;
sp->stream.wait = _mu_pop3_wait;
diff --git a/mail/decode.c b/mail/decode.c
index 4f06a0dce..6b3f71b42 100644
--- a/mail/decode.c
+++ b/mail/decode.c
@@ -207,12 +207,69 @@ mime_descend (struct mime_descend_closure *closure,
{
mu_message_t submsg = NULL;
- if (mu_message_unencapsulate (closure->message, &submsg, NULL) == 0)
+ switch (mu_message_unencapsulate (closure->message, &submsg, NULL))
{
+ case 0:
subclosure.hints = MDHINT_SELECTED_HEADERS;
subclosure.msgset = closure->msgset;
subclosure.message = submsg;
status = mime_descend (&subclosure, fun, data);
+ break;
+
+ case MU_ERR_INVALID_EMAIL:
+ /*
+ * The mu_message_unencapsulate function returns this code
+ * if it was unable to parse the message body as a RFC822
+ * message (this code is propagated from mu_stream_to_message,
+ * which does the actual work).
+ *
+ * If the enclosing messgae(part) is of message/digest type, it
+ * is possible that messages are packed into it without MIME
+ * headers. That violates RFC 1341, but such digests are
+ * reported to exist (re. email conversation with Karl on
+ * 2020-08-07, <202008070138.0771cfHn003390@freefriends.org>).
+ *
+ * Try to see whether the part has one of the normal RFC822 headers
+ * and if so treat it as the message. Otherwise, treat it as
+ * text/plain.
+ *
+ * FIXME: Do all this only if the upper-level message is of
+ * message/digest type.
+ */
+ {
+ char *names[] = { "From", "To", "Subject" };
+ mu_header_t hdr;
+
+ if (mu_message_get_header (closure->message, &hdr) == 0 &&
+ mu_header_sget_firstof (hdr, names, NULL, NULL) == 0)
+ {
+ mu_stream_t str;
+ if (mu_message_get_streamref (closure->message, &str) == 0)
+ {
+ status = mu_stream_to_message (str, &submsg);
+ mu_stream_unref (str);
+ if (status == 0)
+ {
+ mu_header_t subhdr;
+ if (mu_message_get_header (submsg, &subhdr) == 0)
+ {
+ mu_header_remove (subhdr,
+ MU_HEADER_CONTENT_TYPE, 1);
+ subclosure.hints = MDHINT_SELECTED_HEADERS;
+ subclosure.msgset = closure->msgset;
+ subclosure.message = submsg;
+ status = mime_descend (&subclosure, fun, data);
+ break;
+ }
+ }
+ }
+ }
+ }
+ /* FALLTHROUGH */
+
+ default:
+ /* Treat as text/plain */
+ status = fun (closure, data);
}
}
else

Return to:

Send suggestions and report system problems to the System administrator.