summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-01-18 17:23:26 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-01-18 17:30:24 +0200
commit29a837b1126c701191affceb092afbb8de5d5ffc (patch)
tree02c01f31f1a891f89226ff8caadc2d14476b1516
parent99b6b6f02c3cf94ebe1daf7233a702c743d6a2b5 (diff)
downloadmailutils-29a837b1126c701191affceb092afbb8de5d5ffc.tar.gz
mailutils-29a837b1126c701191affceb092afbb8de5d5ffc.tar.bz2
Read message headers during initial scan of an imap mailbox
This considerably speeds up the operation of such tools as mail (initial loading), frm or from. * include/mailutils/sys/imap.h (_mu_imap_message): New member: header_stream. * libproto/imap/mbox.c (_imap_msg_free): Destroy header_stream. (_imap_hdr_fill): Rewrite. (fetch_response_parser): Handle MU_IMAP_FETCH_BODY. (_imap_mbx_scan): Fetch BODY.PEEK[HEADER].
-rw-r--r--include/mailutils/sys/imap.h1
-rw-r--r--libproto/imap/mbox.c96
2 files changed, 47 insertions, 50 deletions
diff --git a/include/mailutils/sys/imap.h b/include/mailutils/sys/imap.h
index 75af27dbe..a1b743fea 100644
--- a/include/mailutils/sys/imap.h
+++ b/include/mailutils/sys/imap.h
@@ -265,2 +265,3 @@ struct _mu_imap_message
struct mu_imapenvelope *env; /* IMAP envelope */
+ mu_stream_t header_stream; /* Memory stream with message headers */
mu_message_t message; /* Pointer to the message structure */
diff --git a/libproto/imap/mbox.c b/libproto/imap/mbox.c
index 18005c7c1..1442e6254 100644
--- a/libproto/imap/mbox.c
+++ b/libproto/imap/mbox.c
@@ -76,2 +76,3 @@ _imap_msg_free (struct _mu_imap_message *msg)
mu_message_imapenvelope_free (msg->env);
+ mu_stream_destroy (&msg->header_stream);
mu_message_destroy (&msg->message, msg);
@@ -142,3 +143,3 @@ _save_message_parser (void *item, void *data)
static void
-_save_message (void *data, int code, size_t sdat, void *pdat)
+_save_message_callback (void *data, int code, size_t sdat, void *pdat)
{
@@ -190,3 +191,3 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno,
rc = _imap_fetch_with_callback (imap, msgset, "BODY[]",
- _save_message, &clos);
+ _save_message_callback, &clos);
}
@@ -368,52 +369,26 @@ _imap_hdr_fill (void *data, char **pbuf, size_t *plen)
struct _mu_imap_message *imsg = data;
- struct _mu_imap_mailbox *imbx = imsg->imbx;
- mu_imap_t imap = imbx->mbox->folder->data;
- struct save_closure clos;
- mu_msgset_t msgset;
- unsigned long msgno = _imap_msg_no (imsg);
- int rc;
-
- rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
- if (rc == 0)
+ mu_stream_t str = imsg->header_stream;
+ char *buf;
+ mu_off_t size;
+ int rc = 0;
+
+ mu_stream_size (str, &size);
+ buf = malloc (size + 1);
+ if (!buf)
+ rc = ENOMEM;
+ else
{
- rc = mu_msgset_add_range (msgset, msgno, msgno, MU_MSGSET_NUM);
+ mu_stream_seek (str, 0, MU_SEEK_SET, NULL);
+ rc = mu_stream_read (str, buf, size, NULL);
if (rc == 0)
{
- clos.imsg = imsg;
- rc = mu_memory_stream_create (&clos.save_stream, MU_STREAM_RDWR);
- if (rc == 0)
- {
- mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
- (_("message %lu: reading headers"),
- (unsigned long) msgno));
- _imap_mbx_clrerr (imbx);
- rc = _imap_fetch_with_callback (imap, msgset,
- "BODY.PEEK[HEADER]",
- _save_message, &clos);
- if (rc == 0)
- {
- char *buf;
- mu_off_t size;
-
- mu_stream_size (clos.save_stream, &size);
- buf = malloc (size + 1);
- if (!buf)
- rc = ENOMEM;
- else
- {
- mu_stream_seek (clos.save_stream, 0, MU_SEEK_SET, NULL);
- rc = mu_stream_read (clos.save_stream, buf, size, NULL);
- if (rc == 0)
- {
- *pbuf = buf;
- *plen = size;
- }
- else
- free (buf);
- }
- }
- mu_stream_destroy (&clos.save_stream);
- }
+ *pbuf = buf;
+ *plen = size;
+ }
+ else
+ {
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+ ("mu_stream_read: %s", mu_strerror (rc)));
+ free (buf);
}
- mu_msgset_free (msgset);
}
@@ -1188,3 +1163,24 @@ fetch_response_parser (void *item, void *data)
break;
-
+
+ case MU_IMAP_FETCH_BODY:
+ {
+ int rc;
+ struct save_closure clos;
+ clos.imsg = imsg;
+ rc = mu_memory_stream_create (&clos.save_stream, MU_STREAM_RDWR);
+ if (rc == 0)
+ {
+ rc = _save_message_parser (resp, &clos);
+ if (rc == 0)
+ imsg->header_stream = clos.save_stream;
+ else
+ mu_stream_destroy (&clos.save_stream);
+ }
+ else
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+ ("mu_static_memory_stream_create: %s",
+ mu_strerror (rc)));
+ }
+ break;
+
default:
@@ -1238,3 +1234,3 @@ _imap_mbx_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
int rc;
- static char _imap_scan_items[] = "(UID FLAGS ENVELOPE RFC822.SIZE BODY)";
+ static char _imap_scan_items[] = "(UID FLAGS ENVELOPE RFC822.SIZE BODY BODY.PEEK[HEADER])";

Return to:

Send suggestions and report system problems to the System administrator.