diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-08-01 22:24:56 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-08-01 22:24:56 +0300 |
commit | b1d907181773eac9a53d70f7af1c6abc8a8d74f4 (patch) | |
tree | e02e5bf65003d02b3e5005aaf094bdc0868aa324 | |
parent | 2843c4054207db33a1237a6991143564c086b3d2 (diff) | |
download | mailutils-b1d907181773eac9a53d70f7af1c6abc8a8d74f4.tar.gz mailutils-b1d907181773eac9a53d70f7af1c6abc8a8d74f4.tar.bz2 |
New function to reconstruct message envelope from the headers.
* include/mailutils/sys/message_stream.h (_mu_message_stream): Reorganize
structure.
* libmailutils/base/amd.c: Use mu_message_reconstruct_envelope instead
of the amd-specific envelope functions.
* libmailutils/stream/message_stream.c: Likewise.
* libmailutils/tests/readmesg.at: New test case.
* libmailutils/tests/readmesg.c: New test program.
* libmailutils/tests/Makefile.am: Add new tests.
* libmailutils/tests/testsuite.at: Likewise.
* mh/tests/mhl.at: Update expected output.
* mh/tests/mhn.at: Likewise.
* testsuite/mh/mbox1/: Fix timestamps in X-Envelope-Date
* testsuite/mh/teaparty/: Likewise.
109 files changed, 385 insertions, 360 deletions
diff --git a/include/mailutils/sys/message_stream.h b/include/mailutils/sys/message_stream.h index 296f0d7c0..66f321a57 100644 --- a/include/mailutils/sys/message_stream.h +++ b/include/mailutils/sys/message_stream.h @@ -19,22 +19,31 @@ #include <mailutils/sys/stream.h> +struct mu_substring_location +{ + size_t start; + size_t length; +}; + struct _mu_message_stream { struct _mu_stream stream; mu_stream_t transport; /* Actual stream */ mu_off_t offset; - int construct_envelope; - char *envelope_string; - size_t envelope_length; - char *from; - char *date; - size_t mark_offset; /* Offset of the header separator */ - size_t mark_length; /* Length of the header separator (not counting the - newline) */ - mu_off_t body_start; - mu_off_t body_end; + int construct_envelope; /* If 1, construct the envelope. */ + char *envelope_string; /* The From_ line, if found. */ + size_t envelope_length; /* Total length of the From_ line, + including trailing whitespace (if any) + and final \n. */ + struct mu_substring_location from; /* Sender location in envelope_string. */ + struct mu_substring_location date; /* Date location in envelope_string. */ + + struct mu_substring_location mark; /* Location of the header separator in + stream. */ + + mu_off_t body_start; /* Start of the body. */ + mu_off_t body_end; /* End of the body. */ }; struct _mu_body_stream diff --git a/libmailutils/base/amd.c b/libmailutils/base/amd.c index 2bc8d4bb9..a4e9daf49 100644 --- a/libmailutils/base/amd.c +++ b/libmailutils/base/amd.c @@ -105,10 +105,6 @@ static int amd_pool_open_count (struct _amd_data *amd); static void amd_pool_flush (struct _amd_data *amd); static struct _amd_message **amd_pool_lookup (struct _amd_message *mhm); -static int amd_envelope_date (mu_envelope_t envelope, char *buf, size_t len, - size_t *psize); -static int amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, - size_t *psize); static int amd_remove_mbox (mu_mailbox_t mailbox); @@ -634,14 +630,12 @@ _amd_attach_message (mu_mailbox_t mailbox, struct _amd_message *mhm, /* Set the envelope. */ { mu_envelope_t envelope = NULL; - status = mu_envelope_create (&envelope, msg); + status = mu_message_reconstruct_envelope (msg, &envelope); if (status != 0) { mu_message_destroy (&msg, mhm); return status; } - mu_envelope_set_sender (envelope, amd_envelope_sender, msg); - mu_envelope_set_date (envelope, amd_envelope_date, msg); mu_message_set_envelope (msg, envelope, mhm); } @@ -2126,97 +2120,6 @@ amd_unset_attr_flags (mu_attribute_t attr, int flags) return 0; } -/* Envelope */ -static int -amd_envelope_date (mu_envelope_t envelope, char *buf, size_t len, - size_t *psize) -{ - mu_message_t msg = mu_envelope_get_owner (envelope); - struct _amd_message *mhm = mu_message_get_owner (msg); - mu_header_t hdr = NULL; - const char *date; - char datebuf[25]; /* Buffer for the output of ctime (terminating nl being - replaced by 0) */ - int status; - - if (mhm == NULL) - return EINVAL; - - if ((status = mu_message_get_header (msg, &hdr)) != 0) - return status; - if (mu_header_sget_value (hdr, MU_HEADER_ENV_DATE, &date) - && mu_header_sget_value (hdr, MU_HEADER_DELIVERY_DATE, &date)) - return MU_ERR_NOENT; - else - { - time_t t; - int rc; - - /* Convert to ctime format */ - rc = mu_parse_date (date, &t, NULL); /* FIXME: TZ info is lost */ - if (rc) - return MU_ERR_NOENT; - memcpy (datebuf, ctime (&t), sizeof (datebuf) - 1); - datebuf[sizeof (datebuf) - 1] = 0; /* Kill the terminating newline */ - date = datebuf; - } - - /* Format: "sender date" */ - if (buf && len > 0) - { - len--; /* Leave space for the null. */ - strncpy (buf, date, len); - if (strlen (date) < len) - { - len = strlen (buf); - if (buf[len-1] != '\n') - buf[len++] = '\n'; - } - buf[len] = '\0'; - } - else - len = strlen (date); - - if (psize) - *psize = len; - return 0; -} - -static int -amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *psize) -{ - mu_message_t msg = mu_envelope_get_owner (envelope); - struct _amd_message *mhm = mu_message_get_owner (msg); - mu_header_t hdr = NULL; - char *from; - int status; - - if (mhm == NULL) - return EINVAL; - - if ((status = mu_message_get_header (msg, &hdr))) - return status; - if ((status = mu_header_aget_value (hdr, MU_HEADER_ENV_SENDER, &from))) - return status; - - if (buf && len > 0) - { - int slen = strlen (from); - - if (len < slen + 1) - slen = len - 1; - memcpy (buf, from, slen); - buf[slen] = 0; - } - else - len = strlen (from); - - if (psize) - *psize = len; - free (from); - return 0; -} - int amd_remove_dir (const char *name) diff --git a/libmailutils/stream/message_stream.c b/libmailutils/stream/message_stream.c index 3a103678d..95ce08f5c 100644 --- a/libmailutils/stream/message_stream.c +++ b/libmailutils/stream/message_stream.c @@ -44,47 +44,50 @@ static int -_env_msg_date (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite) +envelope_substr (struct _mu_message_stream *str, + struct mu_substring_location *loc, + char *buf, size_t len, size_t *pnwrite) { - struct _mu_message_stream *str = mu_message_get_owner (mu_envelope_get_owner (envelope)); - - if (!str || !str->date) - return EINVAL; if (buf) { - strncpy (buf, str->date, len); - buf[len-1] = 0; + if (len == 0) + return EINVAL; + --len; + if (len > loc->length) + len = loc->length; + strncpy (buf, str->envelope_string + loc->start, len); + buf[len] = 0; if (pnwrite) *pnwrite = len; } else if (!pnwrite) return EINVAL; else - *pnwrite = strlen (str->date); + *pnwrite = loc->length; return 0; } static int +_env_msg_date (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite) +{ + struct _mu_message_stream *str = + mu_message_get_owner (mu_envelope_get_owner (envelope)); + + if (!str) + return EINVAL; + return envelope_substr (str, &str->date, buf, len, pnwrite); +} + +static int _env_msg_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite) { - struct _mu_message_stream *str = mu_message_get_owner (mu_envelope_get_owner (envelope)); + struct _mu_message_stream *str = + mu_message_get_owner (mu_envelope_get_owner (envelope)); - if (!str || !str->from) - return EINVAL; - if (buf) - { - strncpy (buf, str->from, len); - buf[len-1] = 0; - if (pnwrite) - *pnwrite = len; - } - else if (!pnwrite) + if (!str) return EINVAL; - else - *pnwrite = strlen (str->from); - - return 0; + return envelope_substr (str, &str->from, buf, len, pnwrite); } @@ -96,13 +99,13 @@ _message_read (mu_stream_t stream, char *optr, size_t osize, size_t *nbytes) mu_off_t offset = s->offset + s->envelope_length; size_t rsize; - if (offset < s->mark_offset) + if (offs |