diff options
Diffstat (limited to 'mail/mutt-devel/files/extra-patch-imap-header-cache')
| -rw-r--r-- | mail/mutt-devel/files/extra-patch-imap-header-cache | 877 | 
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 | 
