Update the maildir header cache patch, which now also
implements the IMAP header cache. This is far more stable than the old IMAP header cache patch. PR: ports/70623 Submitted by: maintainer
This commit is contained in:
parent
2981113155
commit
0ab5af4b92
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=116612
@ -44,10 +44,7 @@
|
||||
# WITH_MUTT_QUOTE_PATCH
|
||||
# This is a default knob and can be disabled by WITHOUT_MUTT_QUOTE_PATCH
|
||||
#
|
||||
# If you want to have the IMAP header cache define:
|
||||
# WITH_MUTT_IMAP_HEADER_CACHE
|
||||
#
|
||||
# If you want to have the Maildir header cache define:
|
||||
# If you want to have the Maildir/IMAP header cache define:
|
||||
# WITH_MUTT_MAILDIR_HEADER_CACHE
|
||||
#
|
||||
# If you want to make SMIME outlook compatible define:
|
||||
@ -84,7 +81,7 @@
|
||||
|
||||
PORTNAME= mutt-devel
|
||||
PORTVERSION= 1.5.6
|
||||
PORTREVISION= 7
|
||||
PORTREVISION= 8
|
||||
CATEGORIES+= mail ipv6
|
||||
.if defined(WITH_MUTT_NNTP)
|
||||
CATEGORIES+= news
|
||||
@ -151,6 +148,9 @@ DW_PATCH_VERSION= ${PORTVERSION}
|
||||
.if !defined(DW_MBOX_PATCH_VERSION)
|
||||
DW_MBOX_PATCH_VERSION= ${DW_PATCH_VERSION}
|
||||
.endif
|
||||
.if defined(WITH_MUTT_IMAP_HEADER_CACHE)
|
||||
WITH_MUTT_MAILDIR_HEADER_CACHE= yes
|
||||
.endif
|
||||
|
||||
# XXX
|
||||
# this should be done automagically by aclocal but ....
|
||||
@ -215,13 +215,9 @@ CFLAGS+= -I${PREFIX}/include/db42
|
||||
pre-configure::
|
||||
@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-smime-outlook
|
||||
.endif
|
||||
.if defined(WITH_MUTT_IMAP_HEADER_CACHE)
|
||||
pre-configure::
|
||||
@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-imap-header-cache
|
||||
.endif
|
||||
.if defined(WITH_MUTT_MAILDIR_HEADER_CACHE)
|
||||
pre-configure::
|
||||
@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-maildir-header-cache
|
||||
@${PATCH} ${PATCH_ARGS} -p1 < ${PATCHDIR}/extra-patch-maildir-header-cache
|
||||
.endif
|
||||
.if defined(WITH_MUTT_MAILDIR_MTIME_PATCH)
|
||||
pre-configure::
|
||||
@ -323,9 +319,6 @@ SCRIPTS_ENV+= MUTT_COMPRESSED_FOLDERS="yes"
|
||||
.if ! defined(WITHOUT_MUTT_QUOTE_PATCH)
|
||||
SCRIPTS_ENV+= MUTT_QUOTE_PATCH="yes"
|
||||
.endif
|
||||
.if defined(WITH_MUTT_IMAP_HEADER_CACHE)
|
||||
SCRIPTS_ENV+= MUTT_IMAP_HEADER_CACHE="yes"
|
||||
.endif
|
||||
.if defined(WITH_MUTT_MAILDIR_HEADER_CACHE)
|
||||
SCRIPTS_ENV+= MUTT_MAILDIR_HEADER_CACHE="yes"
|
||||
CONFIGURE_ARGS+= --enable-hcache
|
||||
@ -403,33 +396,14 @@ post-install:
|
||||
.endif
|
||||
.endif
|
||||
.if defined(MUTT_USES_SLANG)
|
||||
@${ECHO} "====================================================" >> ${PKGMESSAGE}
|
||||
@${ECHO} "=====================================================" >> ${PKGMESSAGE}
|
||||
@${ECHO} "You have installed ${PORTNAME} with SLANG support." >> ${PKGMESSAGE}
|
||||
@${ECHO} "This may work for a color terminal only when defining" >> ${PKGMESSAGE}
|
||||
@${ECHO} "COLORTERM=yes and COLORFGBG=color,color in your" >> ${PKGMESSAGE}
|
||||
@${ECHO} "environment." >> ${PKGMESSAGE}
|
||||
@${ECHO} "====================================================" >> ${PKGMESSAGE}
|
||||
.endif
|
||||
.if defined(WITH_MUTT_IMAP_HEADER_CACHE)
|
||||
@${ECHO} "====================================================" >> ${PKGMESSAGE}
|
||||
@${ECHO} "You have installed ${PORTNAME} with the IMAP header cache enabled." >> ${PKGMESSAGE}
|
||||
@${ECHO} "Please be aware that this - at the moment - could result in" >> ${PKGMESSAGE}
|
||||
@${ECHO} "incorrect display of message flags if there is another client" >> ${PKGMESSAGE}
|
||||
@${ECHO} "simultaneously using the same mailbox." >> ${PKGMESSAGE}
|
||||
@${ECHO} "====================================================" >> ${PKGMESSAGE}
|
||||
.endif
|
||||
.if defined(WITH_MUTT_MAILDIR_HEADER_CACHE) && defined(WITH_MUTT_MAILDIR_MTIME_PATCH)
|
||||
@${ECHO} "====================================================" >> ${PKGMESSAGE}
|
||||
@${ECHO} "You have installed ${PORTNAME} with the Maildir header" >> ${PKGMESSAGE}
|
||||
@${ECHO} "cache and the MAILDIR_MTIME_PATCH enabled." >> ${PKGMESSAGE}
|
||||
@${ECHO} >> ${PKGMESSAGE}
|
||||
@${ECHO} "For this to work you may have to delete your old" >> ${PKGMESSAGE}
|
||||
@${ECHO} "Maildir header cache or otherwise you may face" >> ${PKGMESSAGE}
|
||||
@${ECHO} "an \"Out of memory\" error." >> ${PKGMESSAGE}
|
||||
@${ECHO} "====================================================" >> ${PKGMESSAGE}
|
||||
@${ECHO} "=====================================================" >> ${PKGMESSAGE}
|
||||
.endif
|
||||
.if !defined(BATCH)
|
||||
@${ECHO}
|
||||
@${CAT} ${PKGMESSAGE}
|
||||
@${ECHO}
|
||||
.endif
|
||||
|
@ -1,877 +0,0 @@
|
||||
diff -ru old/globals.h work/mutt-1.5.5.1/globals.h
|
||||
--- old/globals.h Wed Nov 5 10:41:31 2003
|
||||
+++ globals.h Fri Nov 28 18:30:37 2003
|
||||
@@ -57,6 +57,7 @@
|
||||
WHERE char *ImapHomeNamespace INITVAL (NULL);
|
||||
WHERE char *ImapPass INITVAL (NULL);
|
||||
WHERE char *ImapUser INITVAL (NULL);
|
||||
+WHERE char *ImapHeadercache INITVAL (NULL);
|
||||
#endif
|
||||
WHERE char *Inbox;
|
||||
WHERE char *Ispell;
|
||||
diff -ru old/imap/Makefile.am work/mutt-1.5.5.1/imap/Makefile.am
|
||||
--- old/imap/Makefile.am Thu Jan 24 14:35:57 2002
|
||||
+++ imap/Makefile.am Fri Nov 28 18:30:37 2003
|
||||
@@ -22,4 +22,5 @@
|
||||
noinst_HEADERS = auth.h imap_private.h message.h
|
||||
|
||||
libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \
|
||||
- message.c utf7.c util.c $(AUTHENTICATORS) $(GSSSOURCES)
|
||||
+ imap_headercache.c imap_headercache.h message.c utf7.c util.c \
|
||||
+ $(AUTHENTICATORS) $(GSSSOURCES)
|
||||
diff -ru old/imap/imap.c work/mutt-1.5.5.1/imap/imap.c
|
||||
--- old/imap/imap.c Wed Nov 5 10:41:36 2003
|
||||
+++ imap/imap.c Fri Nov 28 18:30:37 2003
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "browser.h"
|
||||
#include "message.h"
|
||||
#include "imap_private.h"
|
||||
+#include "imap_headercache.h"
|
||||
#ifdef USE_SSL
|
||||
# include "mutt_ssl.h"
|
||||
#endif
|
||||
@@ -546,6 +547,13 @@
|
||||
|
||||
/* Clean up path and replace the one in the ctx */
|
||||
imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
|
||||
+
|
||||
+ if (idata->hcache)
|
||||
+ {
|
||||
+ imap_headercache_close(idata->hcache);
|
||||
+ idata->hcache = NULL;
|
||||
+ }
|
||||
+
|
||||
FREE(&(idata->mailbox));
|
||||
idata->mailbox = safe_strdup (buf);
|
||||
imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox);
|
||||
@@ -556,6 +564,7 @@
|
||||
idata->ctx = ctx;
|
||||
|
||||
/* clear mailbox status */
|
||||
+ idata->uidvalidity = 0;
|
||||
idata->status = 0;
|
||||
memset (idata->rights, 0, (RIGHTSMAX+7)/8);
|
||||
idata->newMailCount = 0;
|
||||
@@ -601,6 +610,15 @@
|
||||
if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)
|
||||
goto fail;
|
||||
}
|
||||
+ /* save UIDVALIDITY for the header cache */
|
||||
+ else if (ascii_strncasecmp("OK [UIDVALIDITY", pc, 14) == 0)
|
||||
+ {
|
||||
+ dprint(2, (debugfile, "Getting mailbox UIDVALIDITY\n"));
|
||||
+ pc += 3;
|
||||
+ pc = imap_next_word(pc);
|
||||
+
|
||||
+ sscanf(pc, "%u", &(idata->uidvalidity));
|
||||
+ }
|
||||
else
|
||||
{
|
||||
pc = imap_next_word (pc);
|
||||
@@ -684,6 +702,9 @@
|
||||
ctx->hdrs = safe_calloc (count, sizeof (HEADER *));
|
||||
ctx->v2r = safe_calloc (count, sizeof (int));
|
||||
ctx->msgcount = 0;
|
||||
+
|
||||
+ idata->hcache = imap_headercache_open(idata);
|
||||
+
|
||||
if (count && (imap_read_headers (idata, 0, count-1) < 0))
|
||||
{
|
||||
mutt_error _("Error opening mailbox");
|
||||
@@ -693,6 +714,7 @@
|
||||
|
||||
dprint (2, (debugfile, "imap_open_mailbox: msgcount is %d\n", ctx->msgcount));
|
||||
FREE (&mx.mbox);
|
||||
+
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@@ -914,6 +936,7 @@
|
||||
int n;
|
||||
int err_continue = M_NO; /* continue on error? */
|
||||
int rc;
|
||||
+ IMAP_HEADER h;
|
||||
|
||||
idata = (IMAP_DATA*) ctx->data;
|
||||
|
||||
@@ -953,8 +976,20 @@
|
||||
/* mark these messages as unchanged so second pass ignores them. Done
|
||||
* here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
|
||||
for (n = 0; n < ctx->msgcount; n++)
|
||||
- if (ctx->hdrs[n]->deleted && ctx->hdrs[n]->changed)
|
||||
- ctx->hdrs[n]->active = 0;
|
||||
+ {
|
||||
+ if (ctx->hdrs[n]->deleted)
|
||||
+ {
|
||||
+ if (idata->hcache)
|
||||
+ {
|
||||
+ h.data = HEADER_DATA(ctx->hdrs[n]);
|
||||
+ imap_headercache_delete(idata->hcache, &h);
|
||||
+ }
|
||||
+
|
||||
+ if (ctx->hdrs[n]->changed)
|
||||
+ ctx->hdrs[n]->active = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (imap_exec (idata, cmd.data, 0) != 0)
|
||||
{
|
||||
mutt_error (_("Expunge failed"));
|
||||
@@ -972,6 +1007,23 @@
|
||||
{
|
||||
ctx->hdrs[n]->changed = 0;
|
||||
|
||||
+ if (idata->hcache)
|
||||
+ {
|
||||
+ h.data = HEADER_DATA(ctx->hdrs[n]);
|
||||
+
|
||||
+ h.read = ctx->hdrs[n]->read;
|
||||
+ h.old = ctx->hdrs[n]->old;
|
||||
+ h.deleted = ctx->hdrs[n]->deleted;
|
||||
+ h.flagged = ctx->hdrs[n]->flagged;
|
||||
+ h.replied = ctx->hdrs[n]->replied;
|
||||
+ h.changed = ctx->hdrs[n]->changed;
|
||||
+ h.sid = ctx->hdrs[n]->index + 1;
|
||||
+ h.received = ctx->hdrs[n]->received;
|
||||
+ h.content_length = ctx->hdrs[n]->content->length;
|
||||
+
|
||||
+ imap_headercache_update(idata->hcache, &h);
|
||||
+ }
|
||||
+
|
||||
mutt_message (_("Saving message status flags... [%d/%d]"), n+1,
|
||||
ctx->msgcount);
|
||||
|
||||
@@ -1099,6 +1151,11 @@
|
||||
|
||||
idata->reopen &= IMAP_REOPEN_ALLOW;
|
||||
idata->state = IMAP_AUTHENTICATED;
|
||||
+ if (idata->hcache)
|
||||
+ {
|
||||
+ imap_headercache_close(idata->hcache);
|
||||
+ idata->hcache = NULL;
|
||||
+ }
|
||||
FREE (&(idata->mailbox));
|
||||
mutt_free_list (&idata->flags);
|
||||
idata->ctx = NULL;
|
||||
diff -ru old/imap/imap_private.h work/mutt-1.5.5.1/imap/imap_private.h
|
||||
--- old/imap/imap_private.h Wed Nov 5 10:41:36 2003
|
||||
+++ imap/imap_private.h Fri Nov 28 18:30:37 2003
|
||||
@@ -21,6 +21,7 @@
|
||||
#define _IMAP_PRIVATE_H 1
|
||||
|
||||
#include "imap.h"
|
||||
+#include "imap_headercache.h"
|
||||
#include "mutt_socket.h"
|
||||
|
||||
/* -- symbols -- */
|
||||
@@ -148,7 +149,7 @@
|
||||
int state;
|
||||
} IMAP_COMMAND;
|
||||
|
||||
-typedef struct
|
||||
+typedef struct IMAP_DATA
|
||||
{
|
||||
/* This data is specific to a CONNECTION to an IMAP server */
|
||||
CONNECTION *conn;
|
||||
@@ -175,6 +176,7 @@
|
||||
char *mailbox;
|
||||
unsigned short check_status;
|
||||
unsigned char reopen;
|
||||
+ unsigned int uidvalidity;
|
||||
unsigned char rights[(RIGHTSMAX + 7)/8];
|
||||
unsigned int newMailCount;
|
||||
IMAP_CACHE cache[IMAP_CACHE_LEN];
|
||||
@@ -182,6 +184,7 @@
|
||||
|
||||
/* all folder flags - system flags AND keywords */
|
||||
LIST *flags;
|
||||
+ IMAP_HEADERCACHE *hcache;
|
||||
} IMAP_DATA;
|
||||
/* I wish that were called IMAP_CONTEXT :( */
|
||||
|
||||
diff -ru old/imap/message.c work/mutt-1.5.5.1/imap/message.c
|
||||
--- old/imap/message.c Wed Nov 5 10:41:36 2003
|
||||
+++ imap/message.c Fri Nov 28 18:30:38 2003
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "mutt.h"
|
||||
#include "mutt_curses.h"
|
||||
#include "imap_private.h"
|
||||
+#include "imap_headercache.h"
|
||||
#include "message.h"
|
||||
#include "mx.h"
|
||||
|
||||
@@ -54,9 +55,14 @@
|
||||
int msgno;
|
||||
IMAP_HEADER h;
|
||||
int rc, mfhrc, oldmsgcount;
|
||||
+ IMAP_HEADERCACHE *hc = NULL;
|
||||
+ int msgbegin_hc;
|
||||
int fetchlast = 0;
|
||||
+
|
||||
const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL";
|
||||
|
||||
+ msgno = msgbegin;
|
||||
+
|
||||
ctx = idata->ctx;
|
||||
|
||||
if (mutt_bit_isset (idata->capabilities,IMAP4REV1))
|
||||
@@ -87,36 +93,150 @@
|
||||
}
|
||||
unlink (tempfile);
|
||||
|
||||
+ oldmsgcount = ctx->msgcount;
|
||||
+
|
||||
+ msgbegin_hc = msgbegin;
|
||||
+
|
||||
+ hc = idata->hcache;
|
||||
+
|
||||
+restart:
|
||||
/* make sure context has room to hold the mailbox */
|
||||
while ((msgend) >= idata->ctx->hdrmax)
|
||||
mx_alloc_memory (idata->ctx);
|
||||
|
||||
- oldmsgcount = ctx->msgcount;
|
||||
idata->reopen &= ~IMAP_NEWMAIL_PENDING;
|
||||
idata->newMailCount = 0;
|
||||
|
||||
+ if (hc)
|
||||
+ {
|
||||
+ snprintf(buf, sizeof(buf), "FETCH %d:%d (UID)", msgbegin_hc + 1,
|
||||
+ msgend + 1);
|
||||
+ imap_cmd_start(idata, buf);
|
||||
+
|
||||
+ for (msgno = msgbegin_hc; msgno <= msgend; msgno++)
|
||||
+ {
|
||||
+ if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0)))
|
||||
+ mutt_message (_("Fetching message UIDs... [%d/%d]"), msgno + 1,
|
||||
+ msgend + 1);
|
||||
+
|
||||
+ /* XXX */
|
||||
+ ctx->hdrs[msgno] = NULL;
|
||||
+
|
||||
+ /* XXX leaking h.data on successful exit */
|
||||
+ memset (&h, 0, sizeof (h));
|
||||
+ h.data = safe_calloc (1, sizeof (IMAP_HEADER_DATA));
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ FILE *cache_fp;
|
||||
+
|
||||
+ mfhrc = 0;
|
||||
+
|
||||
+ rc = imap_cmd_step (idata);
|
||||
+ if (rc != IMAP_CMD_CONTINUE)
|
||||
+ break;
|
||||
+
|
||||
+ if ((mfhrc = msg_fetch_header (idata->ctx, &h, idata->cmd.buf, NULL)) == -1)
|
||||
+ continue;
|
||||
+ else if (mfhrc < 0)
|
||||
+ break;
|
||||
+
|
||||
+ cache_fp = imap_headercache_find(hc, &h);
|
||||
+ if (cache_fp)
|
||||
+ {
|
||||
+ /* update context with message header */
|
||||
+ ctx->hdrs[msgno] = mutt_new_header ();
|
||||
+
|
||||
+ ctx->hdrs[msgno]->index = h.sid - 1;
|
||||
+
|
||||
+ /* messages which have not been expunged are ACTIVE (borrowed from mh
|
||||
+ * folders) */
|
||||
+ ctx->hdrs[msgno]->active = 1;
|
||||
+ ctx->hdrs[msgno]->read = h.read;
|
||||
+ ctx->hdrs[msgno]->old = h.old;
|
||||
+ ctx->hdrs[msgno]->deleted = h.deleted;
|
||||
+ ctx->hdrs[msgno]->flagged = h.flagged;
|
||||
+ ctx->hdrs[msgno]->replied = h.replied;
|
||||
+ ctx->hdrs[msgno]->changed = h.changed;
|
||||
+ ctx->hdrs[msgno]->received = h.received;
|
||||
+ ctx->hdrs[msgno]->data = (void *) (h.data);
|
||||
+
|
||||
+ /* NOTE: if Date: header is missing, mutt_read_rfc822_header depends
|
||||
+ * on h.received being set */
|
||||
+ ctx->hdrs[msgno]->env = mutt_read_rfc822_header (cache_fp, ctx->hdrs[msgno],
|
||||
+ 0, 0);
|
||||
+ /* content built as a side-effect of mutt_read_rfc822_header */
|
||||
+ ctx->hdrs[msgno]->content->length = h.content_length;
|
||||
+
|
||||
+ imap_headercache_done(hc, cache_fp);
|
||||
+ }
|
||||
+ }
|
||||
+ while (mfhrc == -1);
|
||||
+
|
||||
+ /* in case we get new mail while fetching the headers */
|
||||
+ if (idata->reopen & IMAP_NEWMAIL_PENDING)
|
||||
+ {
|
||||
+ msgbegin_hc = msgno + 1;
|
||||
+ msgend = idata->newMailCount - 1;
|
||||
+ goto restart;
|
||||
+ }
|
||||
+ /* XXX freshen... etc */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Remember where we left if we get new mail while fetching actual headers */
|
||||
+ msgbegin_hc = msgno;
|
||||
+
|
||||
+ /* Now, either one of the following is true:
|
||||
+ * 1. We don't have a headercache (hc == 0)
|
||||
+ * 2. All messages found in the cache have ctx->hdrs[msgno] != NULL, and
|
||||
+ * filled up.
|
||||
+ */
|
||||
+
|
||||
+ /*
|
||||
+ * Make one request for everything. This makes fetching headers an
|
||||
+ * order of magnitude faster if you have a large mailbox.
|
||||
+ *
|
||||
+ * If we get more messages while doing this, we make another
|
||||
+ * request for all the new messages.
|
||||
+ */
|
||||
+ if (!hc)
|
||||
+ {
|
||||
+ snprintf (buf, sizeof (buf),
|
||||
+ "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgbegin + 1,
|
||||
+ msgend + 1, hdrreq);
|
||||
+
|
||||
+ imap_cmd_start (idata, buf);
|
||||
+ }
|
||||
+
|
||||
for (msgno = msgbegin; msgno <= msgend ; msgno++)
|
||||
{
|
||||
if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0)))
|
||||
mutt_message (_("Fetching message headers... [%d/%d]"), msgno + 1,
|
||||
msgend + 1);
|
||||
|
||||
- if (msgno + 1 > fetchlast)
|
||||
+ /* If the message is in the cache, skip it */
|
||||
+ if (hc)
|
||||
{
|
||||
- /*
|
||||
- * Make one request for everything. This makes fetching headers an
|
||||
- * order of magnitude faster if you have a large mailbox.
|
||||
- *
|
||||
- * If we get more messages while doing this, we make another
|
||||
- * request for all the new messages.
|
||||
- */
|
||||
- snprintf (buf, sizeof (buf),
|
||||
- "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1,
|
||||
- msgend + 1, hdrreq);
|
||||
-
|
||||
- imap_cmd_start (idata, buf);
|
||||
+ if (ctx->hdrs[msgno])
|
||||
+ {
|
||||
+ ctx->msgcount++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (msgno >= fetchlast)
|
||||
+ {
|
||||
+ /* Find the longest "run" of messages not in the cache and fetch it in
|
||||
+ * one go
|
||||
+ */
|
||||
+ for (fetchlast = msgno + 1;
|
||||
+ fetchlast <= msgend && !ctx->hdrs[fetchlast]; fetchlast++);
|
||||
+
|
||||
+ snprintf (buf, sizeof (buf),
|
||||
+ "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1,
|
||||
+ fetchlast, hdrreq);
|
||||
|
||||
- fetchlast = msgend + 1;
|
||||
+ imap_cmd_start (idata, buf);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* freshen fp, h */
|
||||
@@ -130,6 +250,8 @@
|
||||
*/
|
||||
do
|
||||
{
|
||||
+ size_t hdrsz;
|
||||
+
|
||||
mfhrc = 0;
|
||||
|
||||
rc = imap_cmd_step (idata);
|
||||
@@ -144,12 +266,16 @@
|
||||
/* make sure we don't get remnants from older larger message headers */
|
||||
fputs ("\n\n", fp);
|
||||
|
||||
+ hdrsz = (size_t)ftell(fp);
|
||||
+
|
||||
/* update context with message header */
|
||||
ctx->hdrs[msgno] = mutt_new_header ();
|
||||
|
||||
ctx->hdrs[msgno]->index = h.sid - 1;
|
||||
+#if 0
|
||||
if (h.sid != ctx->msgcount + 1)
|
||||
dprint (1, (debugfile, "imap_read_headers: msgcount and sequence ID are inconsistent!"));
|
||||
+#endif
|
||||
/* messages which have not been expunged are ACTIVE (borrowed from mh
|
||||
* folders) */
|
||||
ctx->hdrs[msgno]->active = 1;
|
||||
@@ -163,6 +289,13 @@
|
||||
ctx->hdrs[msgno]->data = (void *) (h.data);
|
||||
|
||||
rewind (fp);
|
||||
+
|
||||
+ if (hc)
|
||||
+ {
|
||||
+ imap_headercache_add(hc, &h, fp, hdrsz);
|
||||
+ rewind(fp);
|
||||
+ }
|
||||
+
|
||||
/* NOTE: if Date: header is missing, mutt_read_rfc822_header depends
|
||||
* on h.received being set */
|
||||
ctx->hdrs[msgno]->env = mutt_read_rfc822_header (fp, ctx->hdrs[msgno],
|
||||
@@ -172,8 +305,7 @@
|
||||
|
||||
ctx->msgcount++;
|
||||
}
|
||||
- while ((rc != IMAP_CMD_OK) && ((mfhrc == -1) ||
|
||||
- ((msgno + 1) >= fetchlast)));
|
||||
+ while (mfhrc == -1);
|
||||
|
||||
if ((mfhrc < -1) || ((rc != IMAP_CMD_CONTINUE) && (rc != IMAP_CMD_OK)))
|
||||
{
|
||||
@@ -186,11 +318,9 @@
|
||||
/* in case we get new mail while fetching the headers */
|
||||
if (idata->reopen & IMAP_NEWMAIL_PENDING)
|
||||
{
|
||||
+ msgbegin = msgno + 1;
|
||||
msgend = idata->newMailCount - 1;
|
||||
- while ((msgend) >= ctx->hdrmax)
|
||||
- mx_alloc_memory (ctx);
|
||||
- idata->reopen &= ~IMAP_NEWMAIL_PENDING;
|
||||
- idata->newMailCount = 0;
|
||||
+ goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,6 +865,7 @@
|
||||
IMAP_DATA* idata;
|
||||
long bytes;
|
||||
int rc = -1; /* default now is that string isn't FETCH response*/
|
||||
+ int fetch_rc;
|
||||
|
||||
idata = (IMAP_DATA*) ctx->data;
|
||||
|
||||
@@ -757,9 +888,15 @@
|
||||
|
||||
/* FIXME: current implementation - call msg_parse_fetch - if it returns -2,
|
||||
* read header lines and call it again. Silly. */
|
||||
- if (msg_parse_fetch (h, buf) != -2)
|
||||
+ fetch_rc = msg_parse_fetch(h, buf);
|
||||
+ if (fetch_rc == 0)
|
||||
+ return 0;
|
||||
+ else if (fetch_rc != -2)
|
||||
return rc;
|
||||
-
|
||||
+
|
||||
+ if (!fp)
|
||||
+ return -2;
|
||||
+
|
||||
if (imap_get_literal_count (buf, &bytes) < 0)
|
||||
return rc;
|
||||
imap_read_literal (fp, idata, bytes);
|
||||
diff -ru old/init.h work/mutt-1.5.5.1/init.h
|
||||
--- old/init.h Wed Nov 5 10:41:32 2003
|
||||
+++ init.h Fri Nov 28 18:30:37 2003
|
||||
@@ -856,6 +856,11 @@
|
||||
** .pp
|
||||
** This variable defaults to your user name on the local machine.
|
||||
*/
|
||||
+ { "imap_headercache", DT_STR, R_NONE, UL &ImapHeadercache, UL 0 },
|
||||
+ /*
|
||||
+ ** .pp
|
||||
+ ** The location of the IMAP headercache directory.
|
||||
+ */
|
||||
#endif
|
||||
{ "implicit_autoview", DT_BOOL,R_NONE, OPTIMPLICITAUTOVIEW, 0},
|
||||
/*
|
||||
diff -ruN old/imap/imap_headercache.c work/mutt-1.5.5.1/imap/imap_headercache.c
|
||||
--- old/imap/imap_headercache.c Thu Jan 1 01:00:00 1970
|
||||
+++ imap/imap_headercache.c Fri Nov 28 18:30:55 2003
|
||||
@@ -0,0 +1,330 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2002 Tudor Bosman <tudorb-mutt@dwyn.net>
|
||||
+ *
|
||||
+ * 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 2 of the License, 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, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
+ */
|
||||
+
|
||||
+#include "mutt.h"
|
||||
+#include "imap.h"
|
||||
+#include "imap_private.h"
|
||||
+#include "imap_headercache.h"
|
||||
+#include "mx.h"
|
||||
+#include <stdio.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <errno.h>
|
||||
+#include <unistd.h>
|
||||
+#include <dirent.h>
|
||||
+#include <assert.h>
|
||||
+
|
||||
+/* Delete all messages from headercache */
|
||||
+static int imap_headercache_purge(IMAP_HEADERCACHE *hc)
|
||||
+{
|
||||
+ int rc = -1;
|
||||
+ DIR *dir;
|
||||
+ struct dirent *ent;
|
||||
+
|
||||
+ dir = opendir(hc->name);
|
||||
+ if (!dir)
|
||||
+ {
|
||||
+ mutt_error(_("IMAP headercache: can't purge directory %s: %s"), hc->name,
|
||||
+ strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ while ((ent = readdir(dir)) != NULL)
|
||||
+ {
|
||||
+ if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||
+ continue;
|
||||
+
|
||||
+ sprintf(hc->tmpname, "%s/%s", hc->name, ent->d_name);
|
||||
+ if (unlink(hc->tmpname) == -1)
|
||||
+ {
|
||||
+ mutt_error(_("IMAP headercache: can't unlink file %s: %s"), hc->tmpname,
|
||||
+ strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rc = 0;
|
||||
+
|
||||
+bail:
|
||||
+ closedir(dir);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* Open headercache */
|
||||
+IMAP_HEADERCACHE *imap_headercache_open(IMAP_DATA *idata)
|
||||
+{
|
||||
+ IMAP_HEADERCACHE *hc;
|
||||
+ char hcdir[_POSIX_PATH_MAX + 1];
|
||||
+ FILE *f;
|
||||
+ size_t len;
|
||||
+ char *p;
|
||||
+
|
||||
+ if (!ImapHeadercache || ImapHeadercache[0] == '\0')
|
||||
+ return NULL;
|
||||
+
|
||||
+ strfcpy(hcdir, ImapHeadercache, _POSIX_PATH_MAX);
|
||||
+ mutt_expand_path(hcdir, _POSIX_PATH_MAX);
|
||||
+
|
||||
+ hc = safe_malloc(sizeof(IMAP_HEADERCACHE));
|
||||
+
|
||||
+ len = strlen(hcdir) + strlen(idata->conn->account.host) +
|
||||
+ strlen(idata->mailbox) + 5;
|
||||
+
|
||||
+ hc->name = safe_malloc(len);
|
||||
+ hc->tmpname = safe_malloc(len + NAME_MAX + 2);
|
||||
+
|
||||
+ sprintf(hc->name, "%s/%s", hcdir, idata->conn->account.host);
|
||||
+
|
||||
+ if (mkdir(hcdir, 0777) == -1 && errno != EEXIST)
|
||||
+ {
|
||||
+ mutt_error(_("Can't create IMAP headercache root directory %s: %s"),
|
||||
+ hcdir, strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ if (mkdir(hc->name, 0700) == -1 && errno != EEXIST)
|
||||
+ {
|
||||
+ mutt_error(_("Can't create IMAP headercache server directory %s: %s"),
|
||||
+ hc->name, strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ p = idata->mailbox;
|
||||
+ while ((p = strchr(p, '/')) != NULL)
|
||||
+ {
|
||||
+ *p = '\0';
|
||||
+ sprintf(hc->name, "%s/%s/%s", hcdir,
|
||||
+ idata->conn->account.host, idata->mailbox);
|
||||
+
|
||||
+ if (mkdir(hc->name, 0700) == -1 && errno != EEXIST)
|
||||
+ {
|
||||
+ mutt_error(_("Can't create IMAP headercache mailbox directory %s: %s"),
|
||||
+ hc->name, strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ *p = '/';
|
||||
+ p++;
|
||||
+ }
|
||||
+
|
||||
+ sprintf(hc->name, "%s/%s/%s", hcdir,
|
||||
+ idata->conn->account.host, idata->mailbox);
|
||||
+
|
||||
+ if (mkdir(hc->name, 0700) == -1 && errno != EEXIST)
|
||||
+ {
|
||||
+ mutt_error(_("Can't create IMAP headercache mailbox directory %s: %s"),
|
||||
+ hc->name, strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ sprintf(hc->tmpname, "%s/uidvalidity", hc->name);
|
||||
+ f = fopen(hc->tmpname, "r");
|
||||
+
|
||||
+ if (f)
|
||||
+ {
|
||||
+ fscanf(f, "%u", &hc->uidvalidity);
|
||||
+ if (idata->uidvalidity != hc->uidvalidity)
|
||||
+ {
|
||||
+ fclose(f);
|
||||
+ f = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!f)
|
||||
+ {
|
||||
+ if (imap_headercache_purge(hc) == -1)
|
||||
+ goto bail;
|
||||
+
|
||||
+ sprintf(hc->tmpname, "%s/uidvalidity", hc->name);
|
||||
+ f = fopen(hc->tmpname, "w");
|
||||
+ if (!f)
|
||||
+ {
|
||||
+ mutt_error(_("Can't create IMAP headercache uidvalidity file %s: %s"),
|
||||
+ hc->tmpname, strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ hc->uidvalidity = idata->uidvalidity;
|
||||
+
|
||||
+ fprintf(f, "%u\n", hc->uidvalidity);
|
||||
+ fclose(f);
|
||||
+ }
|
||||
+
|
||||
+ return hc;
|
||||
+
|
||||
+bail:
|
||||
+ safe_free((void **)&hc->tmpname);
|
||||
+ safe_free((void **)&hc->name);
|
||||
+ safe_free((void **)&hc);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* Close headercache */
|
||||
+void imap_headercache_close(IMAP_HEADERCACHE *hc)
|
||||
+{
|
||||
+ safe_free((void **)&hc->tmpname);
|
||||
+ safe_free((void **)&hc->name);
|
||||
+ safe_free((void **)&hc);
|
||||
+}
|
||||
+
|
||||
+static void imap_headercache_writehdr(FILE *f, IMAP_HEADER *h)
|
||||
+{
|
||||
+ /* Write the stuff in the header. This must have a fixed length, as it is
|
||||
+ * overwritten in case of imap_headercache_update
|
||||
+ */
|
||||
+ fprintf(f, "%1x %1x %1x %1x %1x %1x %8x %16lx %16lx %8x\n",
|
||||
+ h->read, h->old, h->deleted, h->flagged, h->replied, h->changed,
|
||||
+ h->sid, h->received, h->content_length, HEADER_DATA(h)->uid);
|
||||
+}
|
||||
+
|
||||
+/* Add message to headercache */
|
||||
+int imap_headercache_add(IMAP_HEADERCACHE *hc, IMAP_HEADER *h, FILE *from,
|
||||
+ size_t hdrsz)
|
||||
+{
|
||||
+ FILE *f;
|
||||
+#define BUFSIZE 4096
|
||||
+ char buf[BUFSIZE];
|
||||
+ size_t sz;
|
||||
+ int rc = -1;
|
||||
+
|
||||
+ sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
|
||||
+
|
||||
+ f = fopen(hc->tmpname, "w");
|
||||
+ if (!f)
|
||||
+ {
|
||||
+ mutt_error(_("Can't create IMAP headercache message file %s: %s"),
|
||||
+ hc->tmpname, strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ imap_headercache_writehdr(f, h);
|
||||
+
|
||||
+ while ((sz = fread(buf, 1, (hdrsz < BUFSIZE ? hdrsz : BUFSIZE), from)) != 0)
|
||||
+ {
|
||||
+ hdrsz -= sz;
|
||||
+ fwrite(buf, 1, sz, f);
|
||||
+ }
|
||||
+
|
||||
+ fclose(f);
|
||||
+
|
||||
+ rc = 0;
|
||||
+
|
||||
+bail:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* Update flags in headercache message */
|
||||
+int imap_headercache_update(IMAP_HEADERCACHE *hc, IMAP_HEADER *h)
|
||||
+{
|
||||
+ FILE *f;
|
||||
+ int rc = -1;
|
||||
+
|
||||
+ sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
|
||||
+
|
||||
+ f = fopen(hc->tmpname, "r+");
|
||||
+ if (!f)
|
||||
+ goto bail;
|
||||
+
|
||||
+ imap_headercache_writehdr(f, h);
|
||||
+
|
||||
+ fclose(f);
|
||||
+
|
||||
+ rc = 0;
|
||||
+
|
||||
+bail:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* Delete message from headercache */
|
||||
+int imap_headercache_delete(IMAP_HEADERCACHE *hc, IMAP_HEADER *h)
|
||||
+{
|
||||
+ int rc = -1;
|
||||
+
|
||||
+ sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
|
||||
+
|
||||
+ if (unlink(hc->tmpname) == -1)
|
||||
+ {
|
||||
+ mutt_error(_("Can't delete IMAP headercache message %s: %s"),
|
||||
+ hc->tmpname, strerror(errno));
|
||||
+ mutt_sleep(2);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ rc = 0;
|
||||
+
|
||||
+bail:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* Find message in headercache */
|
||||
+FILE *imap_headercache_find(IMAP_HEADERCACHE *hc, IMAP_HEADER *h)
|
||||
+{
|
||||
+ FILE *f = NULL;
|
||||
+ unsigned int flag_read, flag_old, flag_deleted, flag_flagged, flag_replied;
|
||||
+ unsigned int flag_changed;
|
||||
+ unsigned int uid;
|
||||
+ unsigned long received;
|
||||
+ unsigned long content_length;
|
||||
+
|
||||
+ sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
|
||||
+
|
||||
+ f = fopen(hc->tmpname, "r");
|
||||
+ if (!f)
|
||||
+ goto bail;
|
||||
+
|
||||
+ fscanf(f, "%x %x %x %x %x %x %x %lx %lx %x\n",
|
||||
+ &flag_read, &flag_old, &flag_deleted, &flag_flagged, &flag_replied,
|
||||
+ &flag_changed, &h->sid, &received, &content_length, &uid);
|
||||
+
|
||||
+ if (uid != HEADER_DATA(h)->uid)
|
||||
+ {
|
||||
+ fclose(f);
|
||||
+ f = NULL;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ h->received = received;
|
||||
+ h->read = flag_read;
|
||||
+ h->old = flag_old;
|
||||
+ h->deleted = flag_deleted;
|
||||
+ h->flagged = flag_flagged;
|
||||
+ h->replied = flag_replied;
|
||||
+ h->changed = flag_changed;
|
||||
+ h->content_length = (long)content_length;
|
||||
+
|
||||
+bail:
|
||||
+ return f;
|
||||
+}
|
||||
+
|
||||
+/* Close file returned by imap_headercache_find */
|
||||
+void imap_headercache_done(IMAP_HEADERCACHE *hc, FILE *f)
|
||||
+{
|
||||
+ fclose(f);
|
||||
+}
|
||||
+
|
||||
diff -ruN old/imap/imap_headercache.h work/mutt-1.5.5.1/imap/imap_headercache.h
|
||||
--- old/imap/imap_headercache.h Thu Jan 1 01:00:00 1970
|
||||
+++ imap/imap_headercache.h Fri Nov 28 18:30:55 2003
|
||||
@@ -0,0 +1,47 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2002 Tudor Bosman <tudorb-mutt@dwyn.net>
|
||||
+ *
|
||||
+ * 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 2 of the License, 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, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _IMAP_HEADERCACHE_H
|
||||
+#define _IMAP_HEADERCACHE_H
|
||||
+#include "imap_private.h"
|
||||
+#include "message.h"
|
||||
+
|
||||
+typedef struct IMAP_HEADERCACHE
|
||||
+{
|
||||
+ char *name;
|
||||
+ char *tmpname;
|
||||
+ unsigned int uidvalidity;
|
||||
+ int exists;
|
||||
+} IMAP_HEADERCACHE;
|
||||
+
|
||||
+struct IMAP_DATA;
|
||||
+
|
||||
+IMAP_HEADERCACHE *imap_headercache_open(struct IMAP_DATA *idata);
|
||||
+
|
||||
+void imap_headercache_close(IMAP_HEADERCACHE *hc);
|
||||
+
|
||||
+int imap_headercache_add(IMAP_HEADERCACHE *hc, IMAP_HEADER *h, FILE *from,
|
||||
+ size_t hdrsz);
|
||||
+int imap_headercache_update(IMAP_HEADERCACHE *hc, IMAP_HEADER *h);
|
||||
+int imap_headercache_delete(IMAP_HEADERCACHE *hc, IMAP_HEADER *h);
|
||||
+
|
||||
+FILE *imap_headercache_find(IMAP_HEADERCACHE *hc, IMAP_HEADER *h);
|
||||
+void imap_headercache_done(IMAP_HEADERCACHE *hc, FILE *f);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
--- PATCHES.orig Tue Nov 6 19:59:33 2001
|
||||
+++ PATCHES Tue Nov 6 19:59:42 2001
|
||||
@@ -1,0 +1 @@
|
||||
+imap-header-cache.1
|
File diff suppressed because it is too large
Load Diff
@ -146,9 +146,6 @@ EOF
|
||||
if [ "$MUTT_EDIT_THREADS" = "yes" ]; then
|
||||
html=$(($html + 3))
|
||||
fi
|
||||
if [ "$MUTT_IMAP_HEADER_CACHE" = "yes" ]; then
|
||||
html=$(($html + 1))
|
||||
fi
|
||||
if [ "$MUTT_MAILDIR_HEADER_CACHE" = "yes" ]; then
|
||||
html=$(($html + 3))
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user