aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrion <krion@FreeBSD.org>2004-08-19 02:02:36 +0800
committerkrion <krion@FreeBSD.org>2004-08-19 02:02:36 +0800
commitaca4b7c26495c651aadb22dbe20d33194f8e9ad7 (patch)
tree5f55ff8861f15977732afa3a125262c603cccb03
parent0b7710c75da407c600845670dd8183864c891b16 (diff)
downloadfreebsd-ports-gnome-aca4b7c26495c651aadb22dbe20d33194f8e9ad7.tar.gz
freebsd-ports-gnome-aca4b7c26495c651aadb22dbe20d33194f8e9ad7.tar.zst
freebsd-ports-gnome-aca4b7c26495c651aadb22dbe20d33194f8e9ad7.zip
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
-rw-r--r--mail/mutt-devel/Makefile42
-rw-r--r--mail/mutt-devel/files/extra-patch-imap-header-cache877
-rw-r--r--mail/mutt-devel/files/extra-patch-maildir-header-cache703
-rw-r--r--mail/mutt-devel/scripts/generate-plist3
4 files changed, 565 insertions, 1060 deletions
diff --git a/mail/mutt-devel/Makefile b/mail/mutt-devel/Makefile
index a9215374b9fd..9b64be2a7951 100644
--- a/mail/mutt-devel/Makefile
+++ b/mail/mutt-devel/Makefile
@@ -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
diff --git a/mail/mutt-devel/files/extra-patch-imap-header-cache b/mail/mutt-devel/files/extra-patch-imap-header-cache
deleted file mode 100644
index 221a5d439109..000000000000
--- a/mail/mutt-devel/files/extra-patch-imap-header-cache
+++ /dev/null
@@ -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
diff --git a/mail/mutt-devel/files/extra-patch-maildir-header-cache b/mail/mutt-devel/files/extra-patch-maildir-header-cache
index 170d52e44c10..807b3f21b466 100644
--- a/mail/mutt-devel/files/extra-patch-maildir-header-cache
+++ b/mail/mutt-devel/files/extra-patch-maildir-header-cache
@@ -1,20 +1,21 @@
---- Makefile.am.orig Fri Mar 5 15:34:57 2004
-+++ Makefile.am Fri Mar 5 15:35:55 2004
+diff -Nru a/Makefile.am b/Makefile.am
+--- a/Makefile.am 2004-08-18 10:08:12 +02:00
++++ b/Makefile.am 2004-08-18 10:08:12 +02:00
@@ -20,2 +20,3 @@
mutt_SOURCES = $(BUILT_SOURCES) \
+ hcache.c \
addrbook.c alias.c attach.c base64.c browser.c buffy.c color.c \
diff -Nru a/configure.in b/configure.in
---- configure.in.orig Sat Jun 12 09:49:17 2004
-+++ configure.in Sat Jun 12 09:50:18 2004
-@@ -773,6 +773,80 @@
+--- a/configure.in 2004-08-18 10:08:12 +02:00
++++ b/configure.in 2004-08-18 10:08:12 +02:00
+@@ -768,6 +768,80 @@
fi])
+dnl -- start cache --
-+AC_ARG_ENABLE(hcache, [ --enable-hcache Enable header caching for Maildir folders],
++AC_ARG_ENABLE(hcache, [ --enable-hcache Enable header caching],
+[if test x$enableval = xyes; then
-+ AC_DEFINE(USE_HCACHE, 1, [Enable header caching for Maildir style mailboxes])
++ AC_DEFINE(USE_HCACHE, 1, [Enable header caching])
+
+ OLDCPPFLAGS="$CPPFLAGS"
+ OLDLIBS="$LIBS"
@@ -44,17 +45,17 @@ diff -Nru a/configure.in b/configure.in
+ for v in `echo $BDB_VERSIONS`; do
+ CPPFLAGS="$OLDCPPFLAGS -I$BDB_INCLUDE_DIR"
+ LIBS="$OLDLIBS -L$BDB_LIB_DIR -l$v"
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-+ #include <stdlib.h>
++ AC_TRY_LINK([
++ #include <stdlib.h>
+ #include <db.h>
-+ ]],[[
++ ],[
+ DB *db = NULL;
+ db->open(db,NULL,NULL,NULL,0,0,0);
-+ ]])],[
++ ],[
+ ac_cv_dbcreate=yes
+ BDB_LIB="$v"
+ break
-+ ])
++ ])
+ done
+ test x$BDB_LIB != x && break
+ done
@@ -89,25 +90,26 @@ diff -Nru a/configure.in b/configure.in
AC_SUBST(MUTT_LIB_OBJECTS)
AC_SUBST(LIBIMAP)
diff -Nru a/globals.h b/globals.h
---- globals.h 2004-06-10 14:03:44 +02:00
-+++ globals.h 2004-06-10 14:03:44 +02:00
+--- a/globals.h 2004-08-18 10:08:12 +02:00
++++ b/globals.h 2004-08-18 10:08:12 +02:00
@@ -63,6 +63,10 @@
WHERE char *Locale;
WHERE char *MailcapPath;
WHERE char *Maildir;
+#if USE_HCACHE
-+WHERE char *MaildirCache;
-+WHERE short MaildirCachePageSize;
++WHERE char *HeaderCache;
++WHERE short HeaderCachePageSize;
+#endif
WHERE char *MhFlagged;
WHERE char *MhReplied;
WHERE char *MhUnseen;
diff -Nru a/hcache.c b/hcache.c
---- hcache.c.orig Sat Jun 12 09:52:31 2004
-+++ hcache.c Sat Jun 12 09:52:56 2004
-@@ -0,0 +1,676 @@
+--- /dev/null Wed Dec 31 16:00:00 196900
++++ b/hcache.c 2004-08-18 10:08:12 +02:00
+@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2004 Thomas Glanzmann <sithglan@stud.uni-erlangen.de>
++ * Copyright (C) 2004 Tobias Werth <sitowert@stud.uni-erlangen.de>
+ * Copyright (C) 2004 Brian Fundakowski Feldman <green@FreeBSD.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
@@ -138,10 +140,39 @@ diff -Nru a/hcache.c b/hcache.c
+#include <errno.h>
+#include <fcntl.h>
+#include "mutt.h"
++#ifdef USE_IMAP
++#include "message.h"
++#endif
+#include "mime.h"
+#include "mx.h"
+#include "lib.h"
+
++#if HAVE_GDBM
++static struct
++header_cache
++{
++ GDBM_FILE db;
++ char *folder;
++ unsigned int crc;
++} HEADER_CACHE;
++#elif HAVE_DB4
++static struct
++header_cache
++{
++ DB_ENV *env;
++ DB *db;
++ unsigned int crc;
++ int fd;
++ char lockfile[_POSIX_PATH_MAX];
++} HEADER_CACHE;
++#endif
++
++typedef union
++{
++ struct timeval timeval;
++ unsigned long long uid_validity;
++} validate;
++
+static unsigned char *
+dump_int(unsigned int i, unsigned char *d, int *off)
+{
@@ -170,7 +201,24 @@ diff -Nru a/hcache.c b/hcache.c
+ return d;
+ }
+
-+ size = strlen(c) + 1;
++ size = mutt_strlen(c) + 1;
++ d = dump_int(size, d, off);
++ safe_realloc(&d, *off + size);
++ memcpy(d + *off, c, size);
++ *off += size;
++
++ return d;
++}
++
++static unsigned char *
++dump_char_size(char *c, unsigned char *d, int *off, ssize_t size)
++{
++ if (c == NULL) {
++ size = 0;
++ d = dump_int(size, d, off);
++ return d;
++ }
++
+ d = dump_int(size, d, off);
+ safe_realloc(&d, *off + size);
+ memcpy(d + *off, c, size);
@@ -195,14 +243,6 @@ diff -Nru a/hcache.c b/hcache.c
+ *off += size;
+}
+
-+static void
-+skip_char(const unsigned char *d, int *off)
-+{
-+ unsigned int size;
-+ restore_int(&size, d, off);
-+ *off += size;
-+}
-+
+static unsigned char *
+dump_address(ADDRESS *a, unsigned char *d, int *off)
+{
@@ -247,7 +287,6 @@ diff -Nru a/hcache.c b/hcache.c
+ }
+
+ *a = NULL;
-+ return;
+}
+
+static unsigned char *
@@ -284,7 +323,43 @@ diff -Nru a/hcache.c b/hcache.c
+ }
+
+ *l = NULL;
-+ return;
++}
++
++static unsigned char *
++dump_buffer(BUFFER *b, unsigned char *d, int *off)
++{
++ if (! b) {
++ d = dump_int(0, d, off);
++ return d;
++ } else {
++ d = dump_int(1, d, off);
++ }
++
++ d = dump_char_size(b->data, d, off, b->dsize + 1);
++ d = dump_int(b->dptr - b->data, d, off);
++ d = dump_int(b->dsize, d, off);
++ d = dump_int(b->destroy, d, off);
++
++ return d;
++}
++
++static void
++restore_buffer(BUFFER **b, const unsigned char *d, int *off)
++{
++ unsigned int used;
++ unsigned int offset;
++ restore_int(&used, d, off);
++ if (! used) {
++ return;
++ }
++
++ *b = safe_malloc(sizeof(BUFFER));
++
++ restore_char(& (*b)->data, d, off);
++ restore_int(& offset, d, off);
++ (*b)->dptr = (*b)->data + offset;
++ restore_int(& (*b)->dsize, d, off);
++ restore_int((unsigned int *) & (*b)->destroy, d, off);
+}
+
+static unsigned char *
@@ -323,7 +398,6 @@ diff -Nru a/hcache.c b/hcache.c
+ }
+
+ *p = NULL;
-+ return;
+}
+
+static unsigned char *
@@ -408,7 +482,7 @@ diff -Nru a/hcache.c b/hcache.c
+ restore_address(& e->mail_followup_to, d, off);
+
+ restore_char(& e->subject, d, off);
-+ restore_int(& real_subj_off, d, off);
++ restore_int((unsigned int *) (& real_subj_off), d, off);
+ if (0 <= real_subj_off) {
+ e->real_subj = e->subject + real_subj_off;
+ } else {
@@ -424,42 +498,72 @@ diff -Nru a/hcache.c b/hcache.c
+ restore_list(& e->userhdrs, d, off);
+}
+
++static
++unsigned int crc32(unsigned int crc, unsigned char const *p, size_t len)
++{
++ int i;
++ while (len--) {
++ crc ^= *p++;
++ for (i = 0; i < 8; i++)
++ crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
++ }
++ return crc;
++}
+
-+/* This function transforms a header into a char so that it is useable by
-+ * gdbm_store */
++static int
++generate_crc32()
++{
++ int crc = 0;
++
++ crc = crc32(crc, (unsigned char const *) "HCACHE V1", mutt_strlen("HCACHE V1"));
+
+#if HAVE_LANGINFO_CODESET
-+int
-+mutt_hcache_charset_matches(const char *d)
++ crc = crc32(crc, (unsigned char const *) Charset, mutt_strlen(Charset));
++ crc = crc32(crc, (unsigned char const *) "HAVE_LANGINFO_CODESET", mutt_strlen("HAVE_LANGINFO_CODESET"));
++#endif
++
++#if EXACT_ADDRESS
++ crc = crc32(crc, (unsigned char const *) "EXACT_ADDRESS", mutt_strlen("EXACT_ADDRESS"));
++#endif
++ return crc;
++}
++
++static int
++crc32_matches(const char *d, unsigned int crc)
+{
-+ int matches;
-+ int off = sizeof(struct timeval);
-+ char *charset = NULL;
++ int off = sizeof(validate);
++ unsigned int mycrc = 0;
++
++ if (! d) {
++ return 0;
++ }
+
-+ restore_char(&charset, (unsigned char *) d, &off);
-+ matches = (0 == mutt_strcmp(charset, Charset));
-+ FREE(&charset);
++ restore_int(&mycrc, (unsigned char *) d, &off);
+
-+ return (matches);
++ return (crc == mycrc);
+}
-+#endif /* HAVE_LANGINFO_CODESET */
+
++/* This function transforms a header into a char so that it is useable by
++ * db_store */
+static void *
-+mutt_hcache_dump(HEADER *h, int *off)
++mutt_hcache_dump(void *_db, HEADER *h, int *off, unsigned long long uid_validity)
+{
++ struct header_cache *db = _db;
+ unsigned char *d = NULL;
-+ struct timeval now;
+ *off = 0;
+
-+ d = safe_malloc(sizeof(struct timeval));
-+ gettimeofday(&now, NULL);
-+ memcpy(d, &now, sizeof(struct timeval));
-+ *off += sizeof(struct timeval);
++ d = safe_malloc(sizeof(validate));
+
-+#if HAVE_LANGINFO_CODESET
-+ d = dump_char(Charset, d, off);
-+#endif /* HAVE_LANGINFO_CODESET */
++ if (uid_validity) {
++ memcpy(d, &uid_validity, sizeof(long long));
++ } else {
++ struct timeval now;
++ gettimeofday(&now, NULL);
++ memcpy(d, &now, sizeof(struct timeval));
++ }
++ *off += sizeof(validate);
+
++ d = dump_int(db->crc, d, off);
+
+ safe_realloc(&d, *off + sizeof(HEADER));
+ memcpy(d + *off, h, sizeof(HEADER));
@@ -478,12 +582,11 @@ diff -Nru a/hcache.c b/hcache.c
+ int off = 0;
+ HEADER *h = mutt_new_header();
+
-+ /* skip timeval */
-+ off += sizeof(struct timeval);
++ /* skip validate */
++ off += sizeof(validate);
+
-+#if HAVE_LANGINFO_CODESET
-+ skip_char(d, &off);
-+#endif /* HAVE_LANGINFO_CODESET */
++ /* skip crc */
++ off += sizeof(unsigned int);
+
+ memcpy(h, d + off, sizeof(HEADER));
+ off += sizeof(HEADER);
@@ -496,45 +599,39 @@ diff -Nru a/hcache.c b/hcache.c
+
+ restore_char(&h->maildir_flags, d, &off);
+
-+ h->old = (*oh)->old;
-+ h->path = safe_strdup((*oh)->path);
-+ mutt_free_header (oh);
++ /* this is needed for maildir style mailboxes */
++ if (oh) {
++ h->old = (*oh)->old;
++ h->path = safe_strdup((*oh)->path);
++ mutt_free_header (oh);
++ }
+
+ return h;
+}
+
-+static size_t mutt_hcache_keylen (const char *fn)
-+{
-+ const char * p = strchr (fn, ':');
-+ return p ? (size_t) (p - fn) : strlen (fn);
-+}
-+
+#if HAVE_GDBM
-+static struct
-+header_cache
-+{
-+ GDBM_FILE db;
-+ char *folder;
-+} HEADER_CACHE;
+
+void *
+mutt_hcache_open(const char *path, const char *folder)
+{
-+ struct header_cache *h = malloc(sizeof(HEADER_CACHE));
++ struct header_cache *h = safe_calloc(1, sizeof(HEADER_CACHE));
+ h->db = NULL;
+ h->folder = safe_strdup (folder);
++ h->crc = generate_crc32();
+
+ if (! path || path[0] == '\0') {
++ FREE(& h->folder);
++ FREE(& h);
+ return NULL;
+ }
+
-+ h->db = gdbm_open((char *) path, (int) MaildirCachePageSize, GDBM_WRCREAT, 00600, NULL);
++ h->db = gdbm_open((char *) path, (int) HeaderCachePageSize, GDBM_WRCREAT, 00600, NULL);
+ if (h->db) {
+ return h;
+ }
+
+ /* if rw failed try ro */
-+ h->db = gdbm_open((char *) path, (int) MaildirCachePageSize, GDBM_READER, 00600, NULL);
++ h->db = gdbm_open((char *) path, (int) HeaderCachePageSize, GDBM_READER, 00600, NULL);
+ if(h->db) {
+ return h;
+ } else {
@@ -560,7 +657,7 @@ diff -Nru a/hcache.c b/hcache.c
+}
+
+void *
-+mutt_hcache_fetch(void *db, const char *filename)
++mutt_hcache_fetch(void *db, const char *filename, size_t (*keylen)(const char *fn))
+{
+ struct header_cache *h = db;
+ datum key;
@@ -572,18 +669,23 @@ diff -Nru a/hcache.c b/hcache.c
+ }
+
+ strncpy(path, h->folder, sizeof(path));
-+ strncat(path, filename, sizeof(path) - strlen(path));
++ strncat(path, filename, sizeof(path) - mutt_strlen(path));
+
+ key.dptr = path;
-+ key.dsize = mutt_hcache_keylen(path);
++ key.dsize = keylen(path);
+
+ data = gdbm_fetch(h->db, key);
+
++ if (! crc32_matches(data.dptr, h->crc)) {
++ free(data.dptr);
++ return NULL;
++ }
++
+ return data.dptr;
+}
+
+int
-+mutt_hcache_store(void *db, const char *filename, HEADER *header)
++mutt_hcache_store(void *db, const char *filename, HEADER *header, unsigned long long uid_validity, size_t (*keylen)(const char *fn))
+{
+ struct header_cache *h = db;
+ datum key;
@@ -596,12 +698,12 @@ diff -Nru a/hcache.c b/hcache.c
+ }
+
+ strncpy(path, h->folder, sizeof(path));
-+ strncat(path, filename, sizeof(path) - strlen(path));
++ strncat(path, filename, sizeof(path) - mutt_strlen(path));
+
+ key.dptr = path;
-+ key.dsize = mutt_hcache_keylen(path);
++ key.dsize = keylen(path);
+
-+ data.dptr = mutt_hcache_dump(header, &data.dsize);
++ data.dptr = mutt_hcache_dump(db, header, &data.dsize, uid_validity);
+
+ ret = gdbm_store(h->db, key, data, GDBM_REPLACE);
+
@@ -611,7 +713,7 @@ diff -Nru a/hcache.c b/hcache.c
+}
+
+int
-+mutt_hcache_delete(void *db, const char *filename)
++mutt_hcache_delete(void *db, const char *filename, size_t (*keylen)(const char *fn))
+{
+ datum key;
+ struct header_cache *h = db;
@@ -622,22 +724,15 @@ diff -Nru a/hcache.c b/hcache.c
+ }
+
+ strncpy(path, h->folder, sizeof(path));
-+ strncat(path, filename, sizeof(path) - strlen(path));
++ strncat(path, filename, sizeof(path) - mutt_strlen(path));
+
+ key.dptr = path;
-+ key.dsize = mutt_hcache_keylen(path);
++ key.dsize = keylen(path);
+
+ return gdbm_delete(h->db, key);
+}
+#elif HAVE_DB4
+
-+static struct
-+header_cache
-+{
-+ DB_ENV *env;
-+ DB *db;
-+} HEADER_CACHE;
-+
+static void
+mutt_hcache_dbt_init(DBT *dbt, void *data, size_t len)
+{
@@ -661,15 +756,32 @@ diff -Nru a/hcache.c b/hcache.c
+ struct stat sb;
+ u_int32_t createflags = DB_CREATE;
+ int ret;
-+ struct header_cache *h = malloc(sizeof(HEADER_CACHE));
++ struct header_cache *h = calloc(1, sizeof(HEADER_CACHE));
++
++ h->crc = generate_crc32();
+
+ if (! path || path[0] == '\0') {
+ FREE(& h);
+ return NULL;
+ }
+
++ snprintf (h->lockfile, _POSIX_PATH_MAX, "%s-lock-hack", path);
++
++ h->fd = open(h->lockfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
++ if (h->fd < 0) {
++ FREE (&h);
++ return NULL;
++ }
++
++ if (mx_lock_file(h->lockfile, h->fd, 1, 0, 5)) {
++ close(h->fd);
++ FREE (&h);
++ return NULL;
++ }
++
+ ret = db_env_create(&h->env, 0);
+ if (ret) {
++ mx_unlock_file(h->lockfile, h->fd, 0);
+ FREE(& h);
+ return NULL;
+ }
@@ -679,6 +791,7 @@ diff -Nru a/hcache.c b/hcache.c
+ ret = db_create(&h->db, h->env, 0);
+ if (ret) {
+ h->env->close(h->env, 0);
++ mx_unlock_file(h->lockfile, h->fd, 0);
+ FREE(& h);
+ return NULL;
+ }
@@ -686,13 +799,14 @@ diff -Nru a/hcache.c b/hcache.c
+
+ if (stat(path, &sb) != 0 && errno == ENOENT) {
+ createflags |= DB_EXCL;
-+ h->db->set_pagesize(h->db, (int) MaildirCachePageSize);
++ h->db->set_pagesize(h->db, (int) HeaderCachePageSize);
+ }
+
+ ret = h->db->open(h->db, NULL, path, folder, DB_BTREE, createflags, 0600);
+ if (ret) {
+ h->db->close(h->db, 0);
+ h->env->close(h->env, 0);
++ mx_unlock_file(h->lockfile, h->fd, 0);
+ FREE(& h);
+ return NULL;
+ }
@@ -712,12 +826,12 @@ diff -Nru a/hcache.c b/hcache.c
+
+ h->db->close(h->db, 0);
+ h->env->close(h->env, 0);
-+
++ mx_unlock_file(h->lockfile, h->fd, 0);
+ FREE(& h);
+}
+
+void *
-+mutt_hcache_fetch(void *db, const char *filename)
++mutt_hcache_fetch(void *db, const char *filename, size_t (*keylen)(const char *fn))
+{
+ DBT key;
+ DBT data;
@@ -729,17 +843,22 @@ diff -Nru a/hcache.c b/hcache.c
+
+ filename++; /* skip '/' */
+
-+ mutt_hcache_dbt_init(&key, (void *) filename, mutt_hcache_keylen(filename));
++ mutt_hcache_dbt_init(&key, (void *) filename, keylen(filename));
+ mutt_hcache_dbt_empty_init(&data);
+ data.flags = DB_DBT_MALLOC;
+
+ h->db->get(h->db, NULL, &key, &data, 0);
+
++ if (! crc32_matches(data.data, h->crc)) {
++ free(data.data);
++ return NULL;
++ }
++
+ return data.data;
+}
+
+int
-+mutt_hcache_store(void *db, const char *filename, HEADER *header)
++mutt_hcache_store(void *db, const char *filename, HEADER *header, unsigned long long uid_validity, size_t (*keylen)(const char *fn))
+{
+ DBT key;
+ DBT data;
@@ -752,11 +871,11 @@ diff -Nru a/hcache.c b/hcache.c
+
+ filename++; /* skip '/' */
+
-+ mutt_hcache_dbt_init(&key, (void *) filename, mutt_hcache_keylen(filename));
++ mutt_hcache_dbt_init(&key, (void *) filename, keylen(filename));
+
+ mutt_hcache_dbt_empty_init(&data);
+ data.flags = DB_DBT_USERMEM;
-+ data.data = mutt_hcache_dump(header, (signed int *) &data.size);
++ data.data = mutt_hcache_dump(db, header, (signed int *) &data.size, uid_validity);
+ data.ulen = data.size;
+
+ ret = h->db->put(h->db, NULL, &key, &data, 0);
@@ -767,7 +886,7 @@ diff -Nru a/hcache.c b/hcache.c
+}
+
+int
-+mutt_hcache_delete(void *db, const char *filename)
++mutt_hcache_delete(void *db, const char *filename, size_t (*keylen)(const char *fn))
+{
+ DBT key;
+ struct header_cache *h = db;
@@ -778,31 +897,323 @@ diff -Nru a/hcache.c b/hcache.c
+
+ filename++; /* skip '/' */
+
-+ mutt_hcache_dbt_init(&key, (void *) filename, mutt_hcache_keylen(filename));
++ mutt_hcache_dbt_init(&key, (void *) filename, keylen(filename));
+ return h->db->del(h->db, NULL, &key, 0);
+}
+#endif
+diff -Nru a/imap/imap.c b/imap/imap.c
+--- a/imap/imap.c 2004-08-18 10:08:12 +02:00
++++ b/imap/imap.c 2004-08-18 10:08:12 +02:00
+@@ -602,6 +602,17 @@
+ if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)
+ goto fail;
+ }
++#ifdef USE_HCACHE
++ /* 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->uid_validity));
++ }
++#endif
+ else
+ {
+ pc = imap_next_word (pc);
+diff -Nru a/imap/imap_private.h b/imap/imap_private.h
+--- a/imap/imap_private.h 2004-08-18 10:08:12 +02:00
++++ b/imap/imap_private.h 2004-08-18 10:08:12 +02:00
+@@ -179,6 +179,9 @@
+ unsigned int newMailCount;
+ IMAP_CACHE cache[IMAP_CACHE_LEN];
+ int noclose : 1;
++#ifdef USE_HCACHE
++ unsigned long long uid_validity;
++#endif
+
+ /* all folder flags - system flags AND keywords */
+ LIST *flags;
+diff -Nru a/imap/message.c b/imap/message.c
+--- a/imap/message.c 2004-08-18 10:08:12 +02:00
++++ b/imap/message.c 2004-08-18 10:08:12 +02:00
+@@ -39,6 +39,12 @@
+ static int msg_parse_fetch (IMAP_HEADER* h, char* s);
+ static char* msg_parse_flags (IMAP_HEADER* h, char* s);
+
++#if USE_HCACHE
++static int msg_fetch_header_fetch (CONTEXT* ctx, IMAP_HEADER* h, char* buf,
++ FILE* fp);
++static size_t imap_hcache_keylen (const char *fn);
++#endif /* USE_HCACHE */
++
+ /* imap_read_headers:
+ * Changed to read many headers instead of just one. It will return the
+ * msgno of the last message read. It will return a value other than
+@@ -57,8 +63,18 @@
+ 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";
+
++#if USE_HCACHE
++ void *hc = NULL;
++ unsigned long long *uid_validity = NULL;
++ char uid_buf[64];
++#endif /* USE_HCACHE */
++
+ ctx = idata->ctx;
+
++#if USE_HCACHE
++ hc = mutt_hcache_open (HeaderCache, ctx->path);
++#endif /* USE_HCACHE */
++
+ if (mutt_bit_isset (idata->capabilities,IMAP4REV1))
+ {
+ snprintf (hdrreq, sizeof (hdrreq), "BODY.PEEK[HEADER.FIELDS (%s)]",
+@@ -73,6 +89,9 @@
+ { /* Unable to fetch headers for lower versions */
+ mutt_error _("Unable to fetch headers from this IMAP server version.");
+ mutt_sleep (2); /* pause a moment to let the user see the error */
++#if USE_HCACHE
++ mutt_hcache_close (hc);
++#endif /* USE_HCACHE */
+ return -1;
+ }
+
+@@ -83,6 +102,9 @@
+ {
+ mutt_error (_("Could not create temporary file %s"), tempfile);
+ mutt_sleep (2);
++#if USE_HCACHE
++ mutt_hcache_close (hc);
++#endif /* USE_HCACHE */
+ return -1;
+ }
+ unlink (tempfile);
+@@ -95,14 +117,88 @@
+ idata->reopen &= ~IMAP_NEWMAIL_PENDING;
+ idata->newMailCount = 0;
+
++#if USE_HCACHE
++ snprintf (buf, sizeof (buf),
++ "FETCH %d:%d (UID FLAGS)", msgbegin + 1, msgend + 1);
++ fetchlast = msgend + 1;
++
++ imap_cmd_start (idata, buf);
++
++ for (msgno = msgbegin; msgno <= msgend ; msgno++)
++ {
++ if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0)))
++ mutt_message (_("Evaluating cache... [%d/%d]"), msgno + 1,
++ msgend + 1);
++
++ rewind (fp);
++ memset (&h, 0, sizeof (h));
++ h.data = safe_calloc (1, sizeof (IMAP_HEADER_DATA));
++ do
++ {
++ mfhrc = 0;
++
++ rc = imap_cmd_step (idata);
++ if (rc != IMAP_CMD_CONTINUE)
++ break;
++
++ if ((mfhrc = msg_fetch_header_fetch (idata->ctx, &h, idata->cmd.buf, fp)) == -1)
++ continue;
++ else if (mfhrc < 0)
++ break;
++
++ /* make sure we don't get remnants from older larger message headers */
++ fputs ("\n\n", fp);
++
++ sprintf(uid_buf, "/%u", h.data->uid); /* XXX --tg 21:41 04-07-11 */
++ uid_validity = (unsigned long long *) mutt_hcache_fetch (hc, uid_buf, &imap_hcache_keylen);
++
++ if (uid_validity != NULL
++ && *uid_validity == idata->uid_validity) {
++ ctx->hdrs[msgno] = mutt_hcache_restore((unsigned char *) uid_validity, 0);
++ ctx->hdrs[msgno]->index = h.sid - 1;
++ if (h.sid != ctx->msgcount + 1)
++ dprint (1, (debugfile, "imap_read_headers: msgcount and sequence ID are inconsistent!"));
++ /* 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 is restored from mutt_hcache_restore */
++ ctx->hdrs[msgno]->data = (void *) (h.data);
++
++ ctx->msgcount++;
++ }
++ rewind (fp);
++
++ FREE(&uid_validity);
++
++ }
++ while ((rc != IMAP_CMD_OK) && ((mfhrc == -1) ||
++ ((msgno + 1) >= fetchlast)));
++ }
++
++ fetchlast = msgbegin;
++#endif /* USE_HCACHE */
++
+ 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 (ctx->hdrs[msgno])
++ continue;
++
+ if (msgno + 1 > fetchlast)
+ {
++ fetchlast = msgno + 1;
++ while((fetchlast <= msgend) && (! ctx->hdrs[fetchlast]))
++ fetchlast++;
++
+ /*
+ * Make one request for everything. This makes fetching headers an
+ * order of magnitude faster if you have a large mailbox.
+@@ -112,11 +208,9 @@
+ */
+ snprintf (buf, sizeof (buf),
+ "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1,
+- msgend + 1, hdrreq);
++ fetchlast, hdrreq);
+
+ imap_cmd_start (idata, buf);
+-
+- fetchlast = msgend + 1;
+ }
+
+ /* freshen fp, h */
+@@ -170,6 +264,11 @@
+ /* content built as a side-effect of mutt_read_rfc822_header */
+ ctx->hdrs[msgno]->content->length = h.content_length;
+
++#if USE_HCACHE
++ sprintf(uid_buf, "/%u", h.data->uid);
++ mutt_hcache_store(hc, uid_buf, ctx->hdrs[msgno], idata->uid_validity, &imap_hcache_keylen);
++#endif /* USE_HCACHE */
++
+ ctx->msgcount++;
+ }
+ while ((rc != IMAP_CMD_OK) && ((mfhrc == -1) ||
+@@ -179,7 +278,9 @@
+ {
+ imap_free_header_data ((void**) &h.data);
+ fclose (fp);
+-
++#if USE_HCACHE
++ mutt_hcache_close (hc);
++#endif /* USE_HCACHE */
+ return -1;
+ }
+
+@@ -194,6 +295,10 @@
+ }
+ }
+
++#if USE_HCACHE
++ mutt_hcache_close (hc);
++#endif /* USE_HCACHE */
++
+ fclose(fp);
+
+ if (ctx->msgcount > oldmsgcount)
+@@ -724,6 +829,7 @@
+ return s;
+ }
+
++
+ /* msg_fetch_header: import IMAP FETCH response into an IMAP_HEADER.
+ * Expects string beginning with * n FETCH.
+ * Returns:
+@@ -782,6 +888,56 @@
+
+ return rc;
+ }
++
++#if USE_HCACHE
++static size_t imap_hcache_keylen (const char *fn)
++{
++ return mutt_strlen(fn);
++}
++
++/* msg_fetch_header: import IMAP FETCH response into an IMAP_HEADER.
++ * Expects string beginning with * n FETCH.
++ * Returns:
++ * 0 on success
++ * -1 if the string is not a fetch response
++ * -2 if the string is a corrupt fetch response */
++static int msg_fetch_header_fetch (CONTEXT* ctx, IMAP_HEADER* h, char* buf, FILE* fp)
++{
++ IMAP_DATA* idata;
++ long bytes;
++ int rc = -1; /* default now is that string isn't FETCH response*/
++
++ idata = (IMAP_DATA*) ctx->data;
++
++ if (buf[0] != '*')
++ return rc;
++
++ /* skip to message number */
++ buf = imap_next_word (buf);
++ h->sid = atoi (buf);
++
++ /* find FETCH tag */
++ buf = imap_next_word (buf);
++ if (ascii_strncasecmp ("FETCH", buf, 5))
++ return rc;
++
++ rc = -2; /* we've got a FETCH response, for better or worse */
++ if (!(buf = strchr (buf, '(')))
++ return rc;
++ buf++;
++
++ if (msg_parse_fetch (h, buf) < 0) {
++ return -2;
++ }
++
++ if (!(buf = strchr (buf, ')')))
++ return rc;
++ buf++;
++
++ return 0;
++}
++#endif /* USE_HCACHE */
++
+
+ /* msg_has_flag: do a caseless comparison of the flag against a flag list,
+ * return 1 if found or flag list has '\*', 0 otherwise */
diff -Nru a/init.h b/init.h
---- init.h 2004-06-10 14:03:44 +02:00
-+++ init.h 2004-06-10 14:03:44 +02:00
-@@ -981,6 +981,28 @@
+--- a/init.h 2004-08-18 10:08:12 +02:00
++++ b/init.h 2004-08-18 10:08:12 +02:00
+@@ -981,6 +981,30 @@
** \fBDON'T CHANGE THIS SETTING UNLESS YOU ARE REALLY SURE WHAT YOU ARE
** DOING!\fP
*/
+#if USE_HCACHE
-+ { "maildir_cache", DT_PATH, R_NONE, UL &MaildirCache, 0 },
++
++ { "header_cache", DT_PATH, R_NONE, UL &HeaderCache, 0 },
+ /*
+ ** .pp
-+ ** Path to the maildir cache file. If unset no cache will be used.
++ ** Path to the header cache file. If unset no cache will be used. Otherwise
++ ** the cache will be enabled for Maildir and IMAP mailboxes.
+ */
-+ { "maildir_cache_verify", DT_BOOL, R_NONE, OPTHCACHEVERIFY, 1 },
++ { "maildir_header_cache_verify", DT_BOOL, R_NONE, OPTHCACHEVERIFY, 1 },
+ /*
+ ** .pp
-+ ** Check for programs other than mutt having modified maildir
-+ ** files when the header cache is in use. This incurs one stat(2)
-+ ** per message every time the folder is opened.
++ ** Check for Maildir unaware programs other than mutt having modified maildir
++ ** files when the header cache is in use. This incurs one stat(2) per
++ ** message every time the folder is opened.
+ */
-+ { "maildir_cache_page_size", DT_NUM, R_NONE, UL &MaildirCachePageSize, 16384 },
++ { "header_cache_pagesize", DT_NUM, R_NONE, UL &HeaderCachePageSize, 16384 },
+ /*
+ ** .pp
+ ** Change the maildir header cache database page size. Too large
@@ -815,8 +1226,8 @@ diff -Nru a/init.h b/init.h
/*
** .pp
diff -Nru a/main.c b/main.c
---- main.c 2004-06-10 14:03:44 +02:00
-+++ main.c 2004-06-10 14:03:44 +02:00
+--- a/main.c 2004-08-18 10:08:12 +02:00
++++ b/main.c 2004-08-18 10:08:12 +02:00
@@ -411,6 +411,12 @@
"-HAVE_GETADDRINFO "
#endif
@@ -831,13 +1242,20 @@ diff -Nru a/main.c b/main.c
#ifdef ISPELL
diff -Nru a/mh.c b/mh.c
---- mh.c 2004-06-10 14:03:44 +02:00
-+++ mh.c 2004-06-10 14:03:44 +02:00
-@@ -779,11 +779,65 @@
+--- a/mh.c 2004-08-18 10:08:12 +02:00
++++ b/mh.c 2004-08-18 10:08:12 +02:00
+@@ -779,11 +779,68 @@
return r;
}
+#if USE_HCACHE
++
++static size_t maildir_hcache_keylen (const char *fn)
++{
++ const char * p = strchr (fn, ':');
++ return p ? (size_t) (p - fn) : mutt_strlen(fn);
++}
++
/*
* This function does the second parsing pass for a maildir-style
@@ -854,14 +1272,14 @@ diff -Nru a/mh.c b/mh.c
+ struct stat lastchanged;
+ int ret;
+
-+ hc = mutt_hcache_open (MaildirCache, ctx->path);
++ hc = mutt_hcache_open (HeaderCache, ctx->path);
+
+ for (p = md; p; p = p->next) {
+ if (! (p && p->h && !p->header_parsed)) {
+ continue;
+ }
+
-+ data = mutt_hcache_fetch (hc, p->h->path + 3);
++ data = mutt_hcache_fetch (hc, p->h->path + 3, &maildir_hcache_keylen);
+ when = (struct timeval *) data;
+
+ snprintf(fn, sizeof (fn), "%s/%s", ctx->path, p->h->path);
@@ -875,18 +1293,14 @@ diff -Nru a/mh.c b/mh.c
+
+ if (data != NULL
+ && ret == 0
-+ && lastchanged.st_mtime <= when->tv_sec
-+#if HAVE_LANGINFO_CODESET
-+ && mutt_hcache_charset_matches (data)
-+#endif /* HAVE_LANGINFO_CODESET */
-+ ) {
++ && lastchanged.st_mtime <= when->tv_sec) {
+ p->h = mutt_hcache_restore ((unsigned char *)data, &p->h);
+ maildir_parse_flags (p->h, fn);
+
+ } else if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h)) {
+ maildir_parse_flags(p->h, fn);
+ p->header_parsed = 1;
-+ mutt_hcache_store (hc, p->h->path + 3, p->h);
++ mutt_hcache_store (hc, p->h->path + 3, p->h, 0, &maildir_hcache_keylen);
+ } else {
+ mutt_free_header (&p->h);
+ }
@@ -899,7 +1313,7 @@ diff -Nru a/mh.c b/mh.c
void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md)
{
-@@ -801,7 +855,7 @@
+@@ -801,7 +858,7 @@
}
}
@@ -908,7 +1322,7 @@ diff -Nru a/mh.c b/mh.c
/* Read a MH/maildir style mailbox.
*
-@@ -1293,6 +1347,9 @@
+@@ -1293,6 +1350,9 @@
{
char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX];
int i, j;
@@ -918,33 +1332,33 @@ diff -Nru a/mh.c b/mh.c
if (ctx->magic == M_MH)
i = mh_check_mailbox (ctx, index_hint);
-@@ -1302,6 +1359,11 @@
+@@ -1302,6 +1362,11 @@
if (i != 0)
return i;
+#if USE_HCACHE
+ if (ctx->magic == M_MAILDIR)
-+ hc = mutt_hcache_open(MaildirCache, ctx->path);
++ hc = mutt_hcache_open(HeaderCache, ctx->path);
+#endif /* USE_HCACHE */
+
for (i = 0; i < ctx->msgcount; i++)
{
if (ctx->hdrs[i]->deleted
-@@ -1310,7 +1372,13 @@
+@@ -1310,7 +1375,13 @@
snprintf (path, sizeof (path), "%s/%s", ctx->path, ctx->hdrs[i]->path);
if (ctx->magic == M_MAILDIR
|| (option (OPTMHPURGE) && ctx->magic == M_MH))
+ {
+#if USE_HCACHE
+ if (ctx->magic == M_MAILDIR)
-+ mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3);
++ mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3, &maildir_hcache_keylen);
+#endif /* USE_HCACHE */
unlink (path);
+ }
else if (ctx->magic == M_MH)
{
/* MH just moves files out of the way when you delete them */
-@@ -1332,16 +1400,21 @@
+@@ -1332,16 +1403,21 @@
if (ctx->magic == M_MAILDIR)
{
if (maildir_sync_message (ctx, i) == -1)
@@ -968,7 +1382,7 @@ diff -Nru a/mh.c b/mh.c
if (ctx->magic == M_MH)
mh_update_sequences (ctx);
-@@ -1362,6 +1435,13 @@
+@@ -1362,6 +1438,13 @@
}
return 0;
@@ -983,8 +1397,8 @@ diff -Nru a/mh.c b/mh.c
static char *maildir_canon_filename (char *dest, const char *src, size_t l)
diff -Nru a/mutt.h b/mutt.h
---- mutt.h 2004-06-10 14:03:44 +02:00
-+++ mutt.h 2004-06-10 14:03:44 +02:00
+--- a/mutt.h 2004-08-18 10:08:12 +02:00
++++ b/mutt.h 2004-08-18 10:08:12 +02:00
@@ -345,6 +345,9 @@
OPTFORCENAME,
OPTFORWDECODE,
@@ -996,9 +1410,9 @@ diff -Nru a/mutt.h b/mutt.h
OPTHEADER,
OPTHELP,
diff -Nru a/protos.h b/protos.h
---- protos.h 2004-06-10 14:03:44 +02:00
-+++ protos.h 2004-06-10 14:03:44 +02:00
-@@ -99,6 +99,19 @@
+--- a/protos.h 2004-08-18 10:08:12 +02:00
++++ b/protos.h 2004-08-18 10:08:12 +02:00
+@@ -99,6 +99,16 @@
ENVELOPE *mutt_read_rfc822_header (FILE *, HEADER *, short, short);
HEADER *mutt_dup_header (HEADER *);
@@ -1006,12 +1420,9 @@ diff -Nru a/protos.h b/protos.h
+void *mutt_hcache_open(const char *path, const char *folder);
+void mutt_hcache_close(void *db);
+HEADER *mutt_hcache_restore(const unsigned char *d, HEADER **oh);
-+void *mutt_hcache_fetch(void *db, const char *filename);
-+int mutt_hcache_store(void *db, const char *filename, HEADER *h);
-+int mutt_hcache_delete(void *db, const char *filename);
-+#if HAVE_LANGINFO_CODESET
-+int mutt_hcache_charset_matches(const char *d);
-+#endif /* HAVE_LANGINFO_CODESET */
++void *mutt_hcache_fetch(void *db, const char *filename, size_t (*keylen)(const char *fn));
++int mutt_hcache_store(void *db, const char *filename, HEADER *h, unsigned long long uid_validity, size_t (*keylen)(const char *fn));
++int mutt_hcache_delete(void *db, const char *filename, size_t (*keylen)(const char *fn));
+#endif /* USE_HCACHE */
+
+
@@ -1021,4 +1432,4 @@ diff -Nru a/protos.h b/protos.h
--- PATCHES.orig Tue Nov 6 19:59:33 2001
+++ PATCHES Tue Nov 6 19:59:42 2001
@@ -1,0 +1 @@
-+maildir-header-cache.19
++patch-1.5.6.tg.hcache.0
diff --git a/mail/mutt-devel/scripts/generate-plist b/mail/mutt-devel/scripts/generate-plist
index 4d2791716c83..1599a4383093 100644
--- a/mail/mutt-devel/scripts/generate-plist
+++ b/mail/mutt-devel/scripts/generate-plist
@@ -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