diff options
author | krion <krion@FreeBSD.org> | 2004-08-19 02:02:36 +0800 |
---|---|---|
committer | krion <krion@FreeBSD.org> | 2004-08-19 02:02:36 +0800 |
commit | aca4b7c26495c651aadb22dbe20d33194f8e9ad7 (patch) | |
tree | 5f55ff8861f15977732afa3a125262c603cccb03 | |
parent | 0b7710c75da407c600845670dd8183864c891b16 (diff) | |
download | freebsd-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/Makefile | 42 | ||||
-rw-r--r-- | mail/mutt-devel/files/extra-patch-imap-header-cache | 877 | ||||
-rw-r--r-- | mail/mutt-devel/files/extra-patch-maildir-header-cache | 703 | ||||
-rw-r--r-- | mail/mutt-devel/scripts/generate-plist | 3 |
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 |