diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-01-18 17:23:26 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-01-18 17:30:24 +0200 |
commit | 29a837b1126c701191affceb092afbb8de5d5ffc (patch) | |
tree | 02c01f31f1a891f89226ff8caadc2d14476b1516 | |
parent | 99b6b6f02c3cf94ebe1daf7233a702c743d6a2b5 (diff) | |
download | mailutils-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.h | 1 | ||||
-rw-r--r-- | libproto/imap/mbox.c | 96 |
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])"; |