[33674] trunk/dports/mail/mutt

ryandesign at macports.org ryandesign at macports.org
Sat Feb 2 14:51:48 PST 2008


Revision: 33674
          http://trac.macosforge.org/projects/macports/changeset/33674
Author:   ryandesign at macports.org
Date:     2008-02-02 14:51:46 -0800 (Sat, 02 Feb 2008)

Log Message:
-----------
mutt: variant imap-headercache => imap_headercache (hyphen is not valid in variant names)

Modified Paths:
--------------
    trunk/dports/mail/mutt/Portfile

Added Paths:
-----------
    trunk/dports/mail/mutt/files/patch-headercache.diff

Modified: trunk/dports/mail/mutt/Portfile
===================================================================
--- trunk/dports/mail/mutt/Portfile	2008-02-02 22:46:10 UTC (rev 33673)
+++ trunk/dports/mail/mutt/Portfile	2008-02-02 22:51:46 UTC (rev 33674)
@@ -54,7 +54,7 @@
 					b50484f8b12328c3ee69222a3eb1da11
 }
 
-variant imap-headercache requires imap {
+variant imap_headercache requires imap {
     configure.args-append	--enable-compressed
     patch_sites-append		http://dwyn.net/mutt/
     patchfiles-append		mutt-1.4-headercache.patch

Added: trunk/dports/mail/mutt/files/patch-headercache.diff
===================================================================
--- trunk/dports/mail/mutt/files/patch-headercache.diff	                        (rev 0)
+++ trunk/dports/mail/mutt/files/patch-headercache.diff	2008-02-02 22:51:46 UTC (rev 33674)
@@ -0,0 +1,884 @@
+diff -urN -X exclude-diff mutt-1.4/globals.h mutt-1.4-headercache/globals.h
+--- mutt-1.4/globals.h	2002-01-03 12:57:19.000000000 -0800
++++ mutt-1.4-headercache/globals.h	2002-12-14 11:20:58.000000000 -0800
+@@ -56,6 +56,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 -urN -X exclude-diff mutt-1.4/imap/imap.c mutt-1.4-headercache/imap/imap.c
+--- mutt-1.4/imap/imap.c	2002-04-07 14:19:14.000000000 -0700
++++ mutt-1.4-headercache/imap/imap.c	2002-12-14 18:44:07.000000000 -0800
+@@ -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
+@@ -530,6 +531,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);
+@@ -540,6 +548,7 @@
+   idata->ctx = ctx;
+ 
+   /* clear mailbox status */
++  idata->uidvalidity = 0;
+   idata->status = 0;
+   memset (idata->rights, 0, (RIGHTSMAX+7)/8);
+   idata->newMailCount = 0;
+@@ -585,6 +594,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);
+@@ -662,6 +680,9 @@
+   ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
+   ctx->v2r = safe_malloc (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");
+@@ -671,6 +692,7 @@
+ 
+   dprint (2, (debugfile, "imap_open_mailbox: msgcount is %d\n", ctx->msgcount));
+   FREE (&mx.mbox);
++
+   return 0;
+ 
+  fail:
+@@ -891,6 +913,7 @@
+   int n;
+   int err_continue = M_NO;	/* continue on error? */
+   int rc;
++  IMAP_HEADER h;
+ 
+   idata = (IMAP_DATA*) ctx->data;
+ 
+@@ -930,8 +953,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"));
+@@ -949,6 +984,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);
+ 
+@@ -1076,6 +1128,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);
+   }
+diff -urN -X exclude-diff mutt-1.4/imap/imap_headercache.c mutt-1.4-headercache/imap/imap_headercache.c
+--- mutt-1.4/imap/imap_headercache.c	1969-12-31 16:00:00.000000000 -0800
++++ mutt-1.4-headercache/imap/imap_headercache.c	2002-12-14 19:13:47.000000000 -0800
+@@ -0,0 +1,330 @@
++/*
++ * Copyright (C) 2002 Tudor Bosman <tudorb-mutt at 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 -urN -X exclude-diff mutt-1.4/imap/imap_headercache.h mutt-1.4-headercache/imap/imap_headercache.h
+--- mutt-1.4/imap/imap_headercache.h	1969-12-31 16:00:00.000000000 -0800
++++ mutt-1.4-headercache/imap/imap_headercache.h	2002-12-14 19:13:40.000000000 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (C) 2002 Tudor Bosman <tudorb-mutt at 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
++
+diff -urN -X exclude-diff mutt-1.4/imap/imap_private.h mutt-1.4-headercache/imap/imap_private.h
+--- mutt-1.4/imap/imap_private.h	2001-07-03 02:50:05.000000000 -0700
++++ mutt-1.4-headercache/imap/imap_private.h	2002-12-14 16:23:05.000000000 -0800
+@@ -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;
+@@ -174,6 +175,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];
+@@ -181,6 +183,7 @@
+   
+   /* all folder flags - system flags AND keywords */
+   LIST *flags;
++  IMAP_HEADERCACHE *hcache;
+ } IMAP_DATA;
+ /* I wish that were called IMAP_CONTEXT :( */
+ 
+diff -urN -X exclude-diff mutt-1.4/imap/Makefile.am mutt-1.4-headercache/imap/Makefile.am
+--- mutt-1.4/imap/Makefile.am	2001-05-28 12:14:31.000000000 -0700
++++ mutt-1.4-headercache/imap/Makefile.am	2002-12-14 19:27:05.000000000 -0800
+@@ -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 -urN -X exclude-diff mutt-1.4/imap/message.c mutt-1.4-headercache/imap/message.c
+--- mutt-1.4/imap/message.c	2002-04-07 14:19:14.000000000 -0700
++++ mutt-1.4-headercache/imap/message.c	2002-12-14 15:57:44.000000000 -0800
+@@ -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;
+     }
+   }
+ 
+@@ -731,6 +861,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;
+ 
+@@ -753,9 +884,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 -urN -X exclude-diff mutt-1.4/imap/util.c mutt-1.4-headercache/imap/util.c
+--- mutt-1.4/imap/util.c	2002-04-29 05:08:03.000000000 -0700
++++ mutt-1.4-headercache/imap/util.c	2002-12-14 16:25:14.000000000 -0800
+@@ -255,6 +255,7 @@
+   if (!idata)
+     return NULL;
+ 
++  idata->hcache = NULL;
+   idata->conn = NULL;
+   idata->capstr = NULL;
+   idata->state = IMAP_DISCONNECTED;
+diff -urN -X exclude-diff mutt-1.4/init.h mutt-1.4-headercache/init.h
+--- mutt-1.4/init.h	2002-04-25 06:26:37.000000000 -0700
++++ mutt-1.4-headercache/init.h	2002-12-14 11:18:41.000000000 -0800
+@@ -818,6 +818,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},
+   /*

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20080202/44937f4a/attachment-0001.html


More information about the macports-changes mailing list