summaryrefslogtreecommitdiff
path: root/mail/mutt-devel/files/extra-patch-imap-header-cache
diff options
context:
space:
mode:
authorKirill Ponomarev <krion@FreeBSD.org>2004-08-18 18:02:36 +0000
committerKirill Ponomarev <krion@FreeBSD.org>2004-08-18 18:02:36 +0000
commit0ab5af4b92d71d93251666a7716be6959a9b4d1b (patch)
treeb1a37d81e54a5d0fdcc6cfaedd22eb35f5aa406e /mail/mutt-devel/files/extra-patch-imap-header-cache
parentUpdate to 2.0.1. (diff)
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
Notes
Notes: svn path=/head/; revision=116612
Diffstat (limited to 'mail/mutt-devel/files/extra-patch-imap-header-cache')
-rw-r--r--mail/mutt-devel/files/extra-patch-imap-header-cache877
1 files changed, 0 insertions, 877 deletions
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