Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 55240
Collapse All | Expand All

(-)mutt-1.4/globals.h (+1 lines)
Lines 56-61 Link Here
56
WHERE char *ImapHomeNamespace INITVAL (NULL);
56
WHERE char *ImapHomeNamespace INITVAL (NULL);
57
WHERE char *ImapPass INITVAL (NULL);
57
WHERE char *ImapPass INITVAL (NULL);
58
WHERE char *ImapUser INITVAL (NULL);
58
WHERE char *ImapUser INITVAL (NULL);
59
WHERE char *ImapHeadercache INITVAL (NULL);
59
#endif
60
#endif
60
WHERE char *Inbox;
61
WHERE char *Inbox;
61
WHERE char *Ispell;
62
WHERE char *Ispell;
(-)mutt-1.4/imap/imap.c (-2 / +59 lines)
Lines 29-34 Link Here
29
#include "browser.h"
29
#include "browser.h"
30
#include "message.h"
30
#include "message.h"
31
#include "imap_private.h"
31
#include "imap_private.h"
32
#include "imap_headercache.h"
32
#ifdef USE_SSL
33
#ifdef USE_SSL
33
# include "mutt_ssl.h"
34
# include "mutt_ssl.h"
34
#endif
35
#endif
Lines 530-535 Link Here
530
531
531
  /* Clean up path and replace the one in the ctx */
532
  /* Clean up path and replace the one in the ctx */
532
  imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
533
  imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
534
535
  if (idata->hcache)
536
  {
537
    imap_headercache_close(idata->hcache);
538
    idata->hcache = NULL;
539
  }
540
533
  FREE(&(idata->mailbox));
541
  FREE(&(idata->mailbox));
534
  idata->mailbox = safe_strdup (buf);
542
  idata->mailbox = safe_strdup (buf);
535
  imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox);
543
  imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox);
Lines 540-545 Link Here
540
  idata->ctx = ctx;
548
  idata->ctx = ctx;
541
549
542
  /* clear mailbox status */
550
  /* clear mailbox status */
551
  idata->uidvalidity = 0;
543
  idata->status = 0;
552
  idata->status = 0;
544
  memset (idata->rights, 0, (RIGHTSMAX+7)/8);
553
  memset (idata->rights, 0, (RIGHTSMAX+7)/8);
545
  idata->newMailCount = 0;
554
  idata->newMailCount = 0;
Lines 585-590 Link Here
585
      if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)
594
      if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)
586
	goto fail;
595
	goto fail;
587
    }
596
    }
597
    /* save UIDVALIDITY for the header cache */
598
    else if (ascii_strncasecmp("OK [UIDVALIDITY", pc, 14) == 0)
599
    {
600
      dprint(2, (debugfile, "Getting mailbox UIDVALIDITY\n"));
601
      pc += 3;
602
      pc = imap_next_word(pc);
603
604
      sscanf(pc, "%u", &(idata->uidvalidity));
605
    }
588
    else
606
    else
589
    {
607
    {
590
      pc = imap_next_word (pc);
608
      pc = imap_next_word (pc);
Lines 662-667 Link Here
662
  ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
680
  ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
663
  ctx->v2r = safe_malloc (count * sizeof (int));
681
  ctx->v2r = safe_malloc (count * sizeof (int));
664
  ctx->msgcount = 0;
682
  ctx->msgcount = 0;
683
684
  idata->hcache = imap_headercache_open(idata);
685
665
  if (count && (imap_read_headers (idata, 0, count-1) < 0))
686
  if (count && (imap_read_headers (idata, 0, count-1) < 0))
666
  {
687
  {
667
    mutt_error _("Error opening mailbox");
688
    mutt_error _("Error opening mailbox");
Lines 671-676 Link Here
671
692
672
  dprint (2, (debugfile, "imap_open_mailbox: msgcount is %d\n", ctx->msgcount));
693
  dprint (2, (debugfile, "imap_open_mailbox: msgcount is %d\n", ctx->msgcount));
673
  FREE (&mx.mbox);
694
  FREE (&mx.mbox);
695
674
  return 0;
696
  return 0;
675
697
676
 fail:
698
 fail:
Lines 891-896 Link Here
891
  int n;
913
  int n;
892
  int err_continue = M_NO;	/* continue on error? */
914
  int err_continue = M_NO;	/* continue on error? */
893
  int rc;
915
  int rc;
916
  IMAP_HEADER h;
894
917
895
  idata = (IMAP_DATA*) ctx->data;
918
  idata = (IMAP_DATA*) ctx->data;
896
919
Lines 930-937 Link Here
930
      /* mark these messages as unchanged so second pass ignores them. Done
953
      /* mark these messages as unchanged so second pass ignores them. Done
931
       * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
954
       * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
932
      for (n = 0; n < ctx->msgcount; n++)
955
      for (n = 0; n < ctx->msgcount; n++)
933
	if (ctx->hdrs[n]->deleted && ctx->hdrs[n]->changed)
956
      {
934
	  ctx->hdrs[n]->active = 0;
957
	if (ctx->hdrs[n]->deleted)
958
        {
959
          if (idata->hcache)
960
          {
961
            h.data = HEADER_DATA(ctx->hdrs[n]);
962
            imap_headercache_delete(idata->hcache, &h);
963
          }
964
965
          if (ctx->hdrs[n]->changed)
966
            ctx->hdrs[n]->active = 0;
967
        }
968
      }
969
935
      if (imap_exec (idata, cmd.data, 0) != 0)
970
      if (imap_exec (idata, cmd.data, 0) != 0)
936
      {
971
      {
937
	mutt_error (_("Expunge failed"));
972
	mutt_error (_("Expunge failed"));
Lines 949-954 Link Here
949
    {
984
    {
950
      ctx->hdrs[n]->changed = 0;
985
      ctx->hdrs[n]->changed = 0;
951
986
987
      if (idata->hcache)
988
      {
989
        h.data = HEADER_DATA(ctx->hdrs[n]);
990
991
        h.read     = ctx->hdrs[n]->read;
992
        h.old      = ctx->hdrs[n]->old;
993
        h.deleted  = ctx->hdrs[n]->deleted;
994
        h.flagged  = ctx->hdrs[n]->flagged;
995
        h.replied  = ctx->hdrs[n]->replied;
996
        h.changed  = ctx->hdrs[n]->changed;
997
        h.sid      = ctx->hdrs[n]->index + 1;
998
        h.received = ctx->hdrs[n]->received;
999
        h.content_length = ctx->hdrs[n]->content->length;
1000
        
1001
        imap_headercache_update(idata->hcache, &h);
1002
      }
1003
952
      mutt_message (_("Saving message status flags... [%d/%d]"), n+1,
1004
      mutt_message (_("Saving message status flags... [%d/%d]"), n+1,
953
        ctx->msgcount);
1005
        ctx->msgcount);
954
1006
Lines 1076-1081 Link Here
1076
1128
1077
    idata->reopen &= IMAP_REOPEN_ALLOW;
1129
    idata->reopen &= IMAP_REOPEN_ALLOW;
1078
    idata->state = IMAP_AUTHENTICATED;
1130
    idata->state = IMAP_AUTHENTICATED;
1131
    if (idata->hcache)
1132
    {
1133
      imap_headercache_close(idata->hcache);
1134
      idata->hcache = NULL;
1135
    }
1079
    FREE (&(idata->mailbox));
1136
    FREE (&(idata->mailbox));
1080
    mutt_free_list (&idata->flags);
1137
    mutt_free_list (&idata->flags);
1081
  }
1138
  }
(-)mutt-1.4/imap/imap_headercache.c (+330 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2002 Tudor Bosman <tudorb-mutt@dwyn.net>
3
 * 
4
 *     This program is free software; you can redistribute it and/or modify
5
 *     it under the terms of the GNU General Public License as published by
6
 *     the Free Software Foundation; either version 2 of the License, or
7
 *     (at your option) any later version.
8
 * 
9
 *     This program is distributed in the hope that it will be useful,
10
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *     GNU General Public License for more details.
13
 * 
14
 *     You should have received a copy of the GNU General Public License
15
 *     along with this program; if not, write to the Free Software
16
 *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
 */ 
18
19
#include "mutt.h"
20
#include "imap.h"
21
#include "imap_private.h"
22
#include "imap_headercache.h"
23
#include "mx.h"
24
#include <stdio.h>
25
#include <sys/types.h>
26
#include <sys/stat.h>
27
#include <fcntl.h>
28
#include <errno.h>
29
#include <unistd.h>
30
#include <dirent.h>
31
#include <assert.h>
32
33
/* Delete all messages from headercache */
34
static int imap_headercache_purge(IMAP_HEADERCACHE *hc)
35
{
36
  int rc = -1;
37
  DIR *dir;
38
  struct dirent *ent;
39
40
  dir = opendir(hc->name);
41
  if (!dir)
42
  {
43
    mutt_error(_("IMAP headercache: can't purge directory %s: %s"), hc->name,
44
               strerror(errno));
45
    mutt_sleep(2);
46
    return -1;
47
  }
48
49
  while ((ent = readdir(dir)) != NULL)
50
  {
51
    if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
52
      continue;
53
54
    sprintf(hc->tmpname, "%s/%s", hc->name, ent->d_name);
55
    if (unlink(hc->tmpname) == -1)
56
    {
57
      mutt_error(_("IMAP headercache: can't unlink file %s: %s"), hc->tmpname,
58
                 strerror(errno));
59
      mutt_sleep(2);
60
      goto bail;
61
    }
62
  }
63
  
64
  rc = 0;
65
66
bail:
67
  closedir(dir);
68
69
  return rc;
70
}
71
72
/* Open headercache */
73
IMAP_HEADERCACHE *imap_headercache_open(IMAP_DATA *idata)
74
{
75
  IMAP_HEADERCACHE *hc;
76
  char hcdir[_POSIX_PATH_MAX + 1];
77
  FILE *f;
78
  size_t len;
79
  char *p;
80
81
  if (!ImapHeadercache || ImapHeadercache[0] == '\0')
82
    return NULL;
83
84
  strfcpy(hcdir, ImapHeadercache, _POSIX_PATH_MAX);
85
  mutt_expand_path(hcdir, _POSIX_PATH_MAX);
86
87
  hc = safe_malloc(sizeof(IMAP_HEADERCACHE));
88
89
  len = strlen(hcdir) + strlen(idata->conn->account.host) +
90
        strlen(idata->mailbox) + 5;
91
92
  hc->name = safe_malloc(len);
93
  hc->tmpname = safe_malloc(len + NAME_MAX + 2);
94
95
  sprintf(hc->name, "%s/%s", hcdir, idata->conn->account.host);
96
  
97
  if (mkdir(hcdir, 0777) == -1 && errno != EEXIST)
98
  {
99
    mutt_error(_("Can't create IMAP headercache root directory %s: %s"), 
100
                 hcdir, strerror(errno));
101
    mutt_sleep(2);
102
    goto bail;
103
  }
104
105
  if (mkdir(hc->name, 0700) == -1 && errno != EEXIST)
106
  {
107
    mutt_error(_("Can't create IMAP headercache server directory %s: %s"),
108
                 hc->name, strerror(errno));
109
    mutt_sleep(2);
110
    goto bail;
111
  }
112
113
  p = idata->mailbox;
114
  while ((p = strchr(p, '/')) != NULL)
115
  {
116
    *p = '\0';
117
    sprintf(hc->name, "%s/%s/%s", hcdir, 
118
            idata->conn->account.host, idata->mailbox);
119
120
    if (mkdir(hc->name, 0700) == -1 && errno != EEXIST)
121
    {
122
      mutt_error(_("Can't create IMAP headercache mailbox directory %s: %s"),
123
                   hc->name, strerror(errno));
124
      mutt_sleep(2);
125
      goto bail;
126
    }
127
128
    *p = '/';
129
    p++;
130
  }
131
132
  sprintf(hc->name, "%s/%s/%s", hcdir, 
133
          idata->conn->account.host, idata->mailbox);
134
135
  if (mkdir(hc->name, 0700) == -1 && errno != EEXIST)
136
  {
137
    mutt_error(_("Can't create IMAP headercache mailbox directory %s: %s"),
138
                 hc->name, strerror(errno));
139
    mutt_sleep(2);
140
    goto bail;
141
  }
142
  
143
  sprintf(hc->tmpname, "%s/uidvalidity", hc->name);
144
  f = fopen(hc->tmpname, "r");
145
146
  if (f)
147
  {
148
    fscanf(f, "%u", &hc->uidvalidity);
149
    if (idata->uidvalidity != hc->uidvalidity)
150
    {
151
      fclose(f);
152
      f = NULL;
153
    }
154
  }
155
156
  if (!f)
157
  {
158
    if (imap_headercache_purge(hc) == -1)
159
      goto bail;
160
161
    sprintf(hc->tmpname, "%s/uidvalidity", hc->name);
162
    f = fopen(hc->tmpname, "w");
163
    if (!f)
164
    {
165
      mutt_error(_("Can't create IMAP headercache uidvalidity file %s: %s"),
166
                   hc->tmpname, strerror(errno));
167
      mutt_sleep(2);
168
      goto bail;
169
    }
170
171
    hc->uidvalidity = idata->uidvalidity;
172
173
    fprintf(f, "%u\n", hc->uidvalidity);
174
    fclose(f);
175
  }
176
177
  return hc;
178
179
bail:
180
  safe_free((void **)&hc->tmpname);
181
  safe_free((void **)&hc->name);
182
  safe_free((void **)&hc);
183
184
  return NULL;
185
}
186
187
/* Close headercache */
188
void imap_headercache_close(IMAP_HEADERCACHE *hc)
189
{
190
  safe_free((void **)&hc->tmpname);
191
  safe_free((void **)&hc->name);
192
  safe_free((void **)&hc);
193
}
194
195
static void imap_headercache_writehdr(FILE *f, IMAP_HEADER *h)
196
{
197
  /* Write the stuff in the header.  This must have a fixed length, as it is
198
   * overwritten in case of imap_headercache_update
199
   */
200
  fprintf(f, "%1x %1x %1x %1x %1x %1x %8x %16lx %16lx %8x\n",
201
          h->read, h->old, h->deleted, h->flagged, h->replied, h->changed,
202
          h->sid, h->received, h->content_length, HEADER_DATA(h)->uid);
203
}
204
205
/* Add message to headercache */
206
int imap_headercache_add(IMAP_HEADERCACHE *hc, IMAP_HEADER *h, FILE *from,
207
                         size_t hdrsz)
208
{
209
  FILE *f;
210
#define BUFSIZE 4096
211
  char buf[BUFSIZE];
212
  size_t sz;
213
  int rc = -1;
214
215
  sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
216
217
  f = fopen(hc->tmpname, "w");
218
  if (!f)
219
  {
220
    mutt_error(_("Can't create IMAP headercache message file %s: %s"),
221
                 hc->tmpname, strerror(errno));
222
    mutt_sleep(2);
223
    goto bail;
224
  }
225
226
  imap_headercache_writehdr(f, h);
227
228
  while ((sz = fread(buf, 1, (hdrsz < BUFSIZE ? hdrsz : BUFSIZE), from)) != 0)
229
  {
230
    hdrsz -= sz;
231
    fwrite(buf, 1, sz, f);
232
  }
233
234
  fclose(f);
235
236
  rc = 0;
237
238
bail:
239
  return rc;
240
}
241
242
/* Update flags in headercache message */
243
int imap_headercache_update(IMAP_HEADERCACHE *hc, IMAP_HEADER *h)
244
{
245
  FILE *f;
246
  int rc = -1;
247
248
  sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
249
250
  f = fopen(hc->tmpname, "r+");
251
  if (!f)
252
    goto bail;
253
254
  imap_headercache_writehdr(f, h);
255
256
  fclose(f);
257
258
  rc = 0;
259
260
bail:
261
  return rc;
262
}
263
264
/* Delete message from headercache */
265
int imap_headercache_delete(IMAP_HEADERCACHE *hc, IMAP_HEADER *h)
266
{
267
  int rc = -1;
268
269
  sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
270
271
  if (unlink(hc->tmpname) == -1)
272
  {
273
    mutt_error(_("Can't delete IMAP headercache message %s: %s"),
274
               hc->tmpname, strerror(errno));
275
    mutt_sleep(2);
276
    goto bail;
277
  }
278
279
  rc = 0;
280
  
281
bail:
282
  return rc;
283
}
284
285
/* Find message in headercache */
286
FILE *imap_headercache_find(IMAP_HEADERCACHE *hc, IMAP_HEADER *h)
287
{
288
  FILE *f = NULL;
289
  unsigned int flag_read, flag_old, flag_deleted, flag_flagged, flag_replied;
290
  unsigned int flag_changed;
291
  unsigned int uid;
292
  unsigned long received;
293
  unsigned long content_length;
294
295
  sprintf(hc->tmpname, "%s/%u", hc->name, HEADER_DATA(h)->uid);
296
297
  f = fopen(hc->tmpname, "r");
298
  if (!f)
299
    goto bail;
300
301
  fscanf(f, "%x %x %x %x %x %x %x %lx %lx %x\n",
302
         &flag_read, &flag_old, &flag_deleted, &flag_flagged, &flag_replied,
303
         &flag_changed, &h->sid, &received, &content_length, &uid);
304
305
  if (uid != HEADER_DATA(h)->uid)
306
  {
307
    fclose(f);
308
    f = NULL;
309
    goto bail;
310
  }
311
312
  h->received = received;
313
  h->read = flag_read;
314
  h->old = flag_old;
315
  h->deleted = flag_deleted;
316
  h->flagged = flag_flagged;
317
  h->replied = flag_replied;
318
  h->changed = flag_changed;
319
  h->content_length = (long)content_length;
320
321
bail:
322
  return f;
323
}
324
325
/* Close file returned by imap_headercache_find */
326
void imap_headercache_done(IMAP_HEADERCACHE *hc, FILE *f)
327
{
328
  fclose(f);
329
}
330
(-)mutt-1.4/imap/imap_headercache.h (+47 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2002 Tudor Bosman <tudorb-mutt@dwyn.net>
3
 * 
4
 *     This program is free software; you can redistribute it and/or modify
5
 *     it under the terms of the GNU General Public License as published by
6
 *     the Free Software Foundation; either version 2 of the License, or
7
 *     (at your option) any later version.
8
 * 
9
 *     This program is distributed in the hope that it will be useful,
10
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *     GNU General Public License for more details.
13
 * 
14
 *     You should have received a copy of the GNU General Public License
15
 *     along with this program; if not, write to the Free Software
16
 *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
 */ 
18
19
#ifndef _IMAP_HEADERCACHE_H
20
#define _IMAP_HEADERCACHE_H
21
#include "imap_private.h"
22
#include "message.h"
23
24
typedef struct IMAP_HEADERCACHE
25
{
26
  char *name;
27
  char *tmpname;
28
  unsigned int uidvalidity;
29
  int exists;
30
} IMAP_HEADERCACHE;
31
32
struct IMAP_DATA;
33
34
IMAP_HEADERCACHE *imap_headercache_open(struct IMAP_DATA *idata);
35
36
void imap_headercache_close(IMAP_HEADERCACHE *hc);
37
38
int imap_headercache_add(IMAP_HEADERCACHE *hc, IMAP_HEADER *h, FILE *from,
39
                         size_t hdrsz);
40
int imap_headercache_update(IMAP_HEADERCACHE *hc, IMAP_HEADER *h);
41
int imap_headercache_delete(IMAP_HEADERCACHE *hc, IMAP_HEADER *h);
42
43
FILE *imap_headercache_find(IMAP_HEADERCACHE *hc, IMAP_HEADER *h);
44
void imap_headercache_done(IMAP_HEADERCACHE *hc, FILE *f);
45
46
#endif
47
(-)mutt-1.4/imap/imap_private.h (-1 / +4 lines)
Lines 21-26 Link Here
21
#define _IMAP_PRIVATE_H 1
21
#define _IMAP_PRIVATE_H 1
22
22
23
#include "imap.h"
23
#include "imap.h"
24
#include "imap_headercache.h"
24
#include "mutt_socket.h"
25
#include "mutt_socket.h"
25
26
26
/* -- symbols -- */
27
/* -- symbols -- */
Lines 148-154 Link Here
148
  int state;
149
  int state;
149
} IMAP_COMMAND;
150
} IMAP_COMMAND;
150
151
151
typedef struct
152
typedef struct IMAP_DATA
152
{
153
{
153
  /* This data is specific to a CONNECTION to an IMAP server */
154
  /* This data is specific to a CONNECTION to an IMAP server */
154
  CONNECTION *conn;
155
  CONNECTION *conn;
Lines 174-179 Link Here
174
  char *mailbox;
175
  char *mailbox;
175
  unsigned short check_status;
176
  unsigned short check_status;
176
  unsigned char reopen;
177
  unsigned char reopen;
178
  unsigned int uidvalidity;
177
  unsigned char rights[(RIGHTSMAX + 7)/8];
179
  unsigned char rights[(RIGHTSMAX + 7)/8];
178
  unsigned int newMailCount;
180
  unsigned int newMailCount;
179
  IMAP_CACHE cache[IMAP_CACHE_LEN];
181
  IMAP_CACHE cache[IMAP_CACHE_LEN];
Lines 181-186 Link Here
181
  
183
  
182
  /* all folder flags - system flags AND keywords */
184
  /* all folder flags - system flags AND keywords */
183
  LIST *flags;
185
  LIST *flags;
186
  IMAP_HEADERCACHE *hcache;
184
} IMAP_DATA;
187
} IMAP_DATA;
185
/* I wish that were called IMAP_CONTEXT :( */
188
/* I wish that were called IMAP_CONTEXT :( */
186
189
(-)mutt-1.4/imap/Makefile.am (-1 / +2 lines)
Lines 22-25 Link Here
22
noinst_HEADERS = auth.h imap_private.h message.h
22
noinst_HEADERS = auth.h imap_private.h message.h
23
23
24
libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \
24
libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \
25
	message.c utf7.c util.c $(AUTHENTICATORS) $(GSSSOURCES)
25
	imap_headercache.c imap_headercache.h message.c utf7.c util.c \
26
	$(AUTHENTICATORS) $(GSSSOURCES)
(-)mutt-1.4/imap/message.c (-23 / +160 lines)
Lines 25-30 Link Here
25
#include "mutt.h"
25
#include "mutt.h"
26
#include "mutt_curses.h"
26
#include "mutt_curses.h"
27
#include "imap_private.h"
27
#include "imap_private.h"
28
#include "imap_headercache.h"
28
#include "message.h"
29
#include "message.h"
29
#include "mx.h"
30
#include "mx.h"
30
31
Lines 54-62 Link Here
54
  int msgno;
55
  int msgno;
55
  IMAP_HEADER h;
56
  IMAP_HEADER h;
56
  int rc, mfhrc, oldmsgcount;
57
  int rc, mfhrc, oldmsgcount;
58
  IMAP_HEADERCACHE *hc = NULL;
59
  int msgbegin_hc;
57
  int fetchlast = 0;
60
  int fetchlast = 0;
61
58
  const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL";
62
  const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL";
59
63
64
  msgno = msgbegin;
65
60
  ctx = idata->ctx;
66
  ctx = idata->ctx;
61
67
62
  if (mutt_bit_isset (idata->capabilities,IMAP4REV1))
68
  if (mutt_bit_isset (idata->capabilities,IMAP4REV1))
Lines 87-122 Link Here
87
  }
93
  }
88
  unlink (tempfile);
94
  unlink (tempfile);
89
95
96
  oldmsgcount = ctx->msgcount;
97
98
  msgbegin_hc = msgbegin;
99
100
  hc = idata->hcache;
101
102
restart:
90
  /* make sure context has room to hold the mailbox */
103
  /* make sure context has room to hold the mailbox */
91
  while ((msgend) >= idata->ctx->hdrmax)
104
  while ((msgend) >= idata->ctx->hdrmax)
92
    mx_alloc_memory (idata->ctx);
105
    mx_alloc_memory (idata->ctx);
93
106
94
  oldmsgcount = ctx->msgcount;
95
  idata->reopen &= ~IMAP_NEWMAIL_PENDING;
107
  idata->reopen &= ~IMAP_NEWMAIL_PENDING;
96
  idata->newMailCount = 0;
108
  idata->newMailCount = 0;
97
109
110
  if (hc)
111
  {
112
    snprintf(buf, sizeof(buf), "FETCH %d:%d (UID)", msgbegin_hc + 1, 
113
             msgend + 1);
114
    imap_cmd_start(idata, buf);
115
116
    for (msgno = msgbegin_hc; msgno <= msgend; msgno++)
117
    {
118
      if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0)))
119
        mutt_message (_("Fetching message UIDs... [%d/%d]"), msgno + 1,
120
                      msgend + 1);
121
122
      /* XXX */
123
      ctx->hdrs[msgno] = NULL;
124
125
      /* XXX leaking h.data on successful exit */
126
      memset (&h, 0, sizeof (h));
127
      h.data = safe_calloc (1, sizeof (IMAP_HEADER_DATA));
128
129
      do
130
      {
131
        FILE *cache_fp;
132
133
        mfhrc = 0;
134
135
        rc = imap_cmd_step (idata);
136
        if (rc != IMAP_CMD_CONTINUE)
137
          break;
138
139
        if ((mfhrc = msg_fetch_header (idata->ctx, &h, idata->cmd.buf, NULL)) == -1)
140
          continue;
141
        else if (mfhrc < 0)
142
          break;
143
144
        cache_fp = imap_headercache_find(hc, &h);
145
        if (cache_fp)
146
        {
147
          /* update context with message header */
148
          ctx->hdrs[msgno] = mutt_new_header ();
149
150
          ctx->hdrs[msgno]->index = h.sid - 1;
151
152
          /* messages which have not been expunged are ACTIVE (borrowed from mh 
153
           * folders) */
154
          ctx->hdrs[msgno]->active = 1;
155
          ctx->hdrs[msgno]->read = h.read;
156
          ctx->hdrs[msgno]->old = h.old;
157
          ctx->hdrs[msgno]->deleted = h.deleted;
158
          ctx->hdrs[msgno]->flagged = h.flagged;
159
          ctx->hdrs[msgno]->replied = h.replied;
160
          ctx->hdrs[msgno]->changed = h.changed;
161
          ctx->hdrs[msgno]->received = h.received;
162
          ctx->hdrs[msgno]->data = (void *) (h.data);
163
164
          /* NOTE: if Date: header is missing, mutt_read_rfc822_header depends
165
           *   on h.received being set */
166
          ctx->hdrs[msgno]->env = mutt_read_rfc822_header (cache_fp, ctx->hdrs[msgno],
167
            0, 0);
168
          /* content built as a side-effect of mutt_read_rfc822_header */
169
          ctx->hdrs[msgno]->content->length = h.content_length;
170
171
          imap_headercache_done(hc, cache_fp);
172
        }
173
      }
174
      while (mfhrc == -1);
175
176
      /* in case we get new mail while fetching the headers */
177
      if (idata->reopen & IMAP_NEWMAIL_PENDING)
178
      {
179
        msgbegin_hc = msgno + 1;
180
        msgend = idata->newMailCount - 1;
181
        goto restart;
182
      }
183
      /* XXX freshen... etc */
184
    }
185
  }
186
187
  /* Remember where we left if we get new mail while fetching actual headers */
188
  msgbegin_hc = msgno;
189
190
  /* Now, either one of the following is true:
191
   * 1. We don't have a headercache (hc == 0)
192
   * 2. All messages found in the cache have ctx->hdrs[msgno] != NULL, and
193
   * filled up.
194
   */
195
196
  /*
197
   * Make one request for everything. This makes fetching headers an
198
   * order of magnitude faster if you have a large mailbox.
199
   *
200
   * If we get more messages while doing this, we make another
201
   * request for all the new messages.
202
   */
203
  if (!hc)
204
  {
205
    snprintf (buf, sizeof (buf),
206
      "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgbegin + 1,
207
      msgend + 1, hdrreq);
208
209
    imap_cmd_start (idata, buf);
210
  }
211
98
  for (msgno = msgbegin; msgno <= msgend ; msgno++)
212
  for (msgno = msgbegin; msgno <= msgend ; msgno++)
99
  {
213
  {
100
    if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0)))
214
    if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0)))
101
      mutt_message (_("Fetching message headers... [%d/%d]"), msgno + 1,
215
      mutt_message (_("Fetching message headers... [%d/%d]"), msgno + 1,
102
        msgend + 1);
216
        msgend + 1);
103
217
104
    if (msgno + 1 > fetchlast)
218
    /* If the message is in the cache, skip it */
219
    if (hc)
105
    {
220
    {
106
      /*
221
      if (ctx->hdrs[msgno])
107
       * Make one request for everything. This makes fetching headers an
222
      {
108
       * order of magnitude faster if you have a large mailbox.
223
        ctx->msgcount++;
109
       *
224
        continue;
110
       * If we get more messages while doing this, we make another
225
      }
111
       * request for all the new messages.
226
      else if (msgno >= fetchlast)
112
       */
227
      {
113
      snprintf (buf, sizeof (buf),
228
        /* Find the longest "run" of messages not in the cache and fetch it in
114
        "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1,
229
         * one go
115
        msgend + 1, hdrreq);
230
         */
116
231
        for (fetchlast = msgno + 1; 
117
      imap_cmd_start (idata, buf);
232
             fetchlast <= msgend && !ctx->hdrs[fetchlast]; fetchlast++);
233
234
        snprintf (buf, sizeof (buf),
235
          "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1,
236
          fetchlast, hdrreq);
118
237
119
      fetchlast = msgend + 1;
238
        imap_cmd_start (idata, buf);
239
      }
120
    }
240
    }
121
241
122
    /* freshen fp, h */
242
    /* freshen fp, h */
Lines 130-135 Link Here
130
     */
250
     */
131
    do
251
    do
132
    {
252
    {
253
      size_t hdrsz;
254
133
      mfhrc = 0;
255
      mfhrc = 0;
134
256
135
      rc = imap_cmd_step (idata);
257
      rc = imap_cmd_step (idata);
Lines 144-155 Link Here
144
      /* make sure we don't get remnants from older larger message headers */
266
      /* make sure we don't get remnants from older larger message headers */
145
      fputs ("\n\n", fp);
267
      fputs ("\n\n", fp);
146
268
269
      hdrsz = (size_t)ftell(fp);
270
147
      /* update context with message header */
271
      /* update context with message header */
148
      ctx->hdrs[msgno] = mutt_new_header ();
272
      ctx->hdrs[msgno] = mutt_new_header ();
149
273
150
      ctx->hdrs[msgno]->index = h.sid - 1;
274
      ctx->hdrs[msgno]->index = h.sid - 1;
275
#if 0
151
      if (h.sid != ctx->msgcount + 1)
276
      if (h.sid != ctx->msgcount + 1)
152
	dprint (1, (debugfile, "imap_read_headers: msgcount and sequence ID are inconsistent!"));
277
	dprint (1, (debugfile, "imap_read_headers: msgcount and sequence ID are inconsistent!"));
278
#endif
153
      /* messages which have not been expunged are ACTIVE (borrowed from mh 
279
      /* messages which have not been expunged are ACTIVE (borrowed from mh 
154
       * folders) */
280
       * folders) */
155
      ctx->hdrs[msgno]->active = 1;
281
      ctx->hdrs[msgno]->active = 1;
Lines 163-168 Link Here
163
      ctx->hdrs[msgno]->data = (void *) (h.data);
289
      ctx->hdrs[msgno]->data = (void *) (h.data);
164
290
165
      rewind (fp);
291
      rewind (fp);
292
293
      if (hc)
294
      {
295
        imap_headercache_add(hc, &h, fp, hdrsz);
296
        rewind(fp);
297
      }
298
166
      /* NOTE: if Date: header is missing, mutt_read_rfc822_header depends
299
      /* NOTE: if Date: header is missing, mutt_read_rfc822_header depends
167
       *   on h.received being set */
300
       *   on h.received being set */
168
      ctx->hdrs[msgno]->env = mutt_read_rfc822_header (fp, ctx->hdrs[msgno],
301
      ctx->hdrs[msgno]->env = mutt_read_rfc822_header (fp, ctx->hdrs[msgno],
Lines 172-179 Link Here
172
305
173
      ctx->msgcount++;
306
      ctx->msgcount++;
174
    }
307
    }
175
    while ((rc != IMAP_CMD_OK) && ((mfhrc == -1) ||
308
    while (mfhrc == -1);
176
      ((msgno + 1) >= fetchlast)));
177
309
178
    if ((mfhrc < -1) || ((rc != IMAP_CMD_CONTINUE) && (rc != IMAP_CMD_OK)))
310
    if ((mfhrc < -1) || ((rc != IMAP_CMD_CONTINUE) && (rc != IMAP_CMD_OK)))
179
    {
311
    {
Lines 186-196 Link Here
186
    /* in case we get new mail while fetching the headers */
318
    /* in case we get new mail while fetching the headers */
187
    if (idata->reopen & IMAP_NEWMAIL_PENDING)
319
    if (idata->reopen & IMAP_NEWMAIL_PENDING)
188
    {
320
    {
321
      msgbegin = msgno + 1;
189
      msgend = idata->newMailCount - 1;
322
      msgend = idata->newMailCount - 1;
190
      while ((msgend) >= ctx->hdrmax)
323
      goto restart;
191
	mx_alloc_memory (ctx);
192
      idata->reopen &= ~IMAP_NEWMAIL_PENDING;
193
      idata->newMailCount = 0;
194
    }
324
    }
195
  }
325
  }
196
326
Lines 731-736 Link Here
731
  IMAP_DATA* idata;
861
  IMAP_DATA* idata;
732
  long bytes;
862
  long bytes;
733
  int rc = -1; /* default now is that string isn't FETCH response*/
863
  int rc = -1; /* default now is that string isn't FETCH response*/
864
  int fetch_rc;
734
865
735
  idata = (IMAP_DATA*) ctx->data;
866
  idata = (IMAP_DATA*) ctx->data;
736
867
Lines 753-761 Link Here
753
884
754
  /* FIXME: current implementation - call msg_parse_fetch - if it returns -2,
885
  /* FIXME: current implementation - call msg_parse_fetch - if it returns -2,
755
   *   read header lines and call it again. Silly. */
886
   *   read header lines and call it again. Silly. */
756
  if (msg_parse_fetch (h, buf) != -2)
887
  fetch_rc = msg_parse_fetch(h, buf);
888
  if (fetch_rc == 0)
889
    return 0;
890
  else if (fetch_rc != -2)
757
    return rc;
891
    return rc;
758
  
892
893
  if (!fp)
894
    return -2;
895
759
  if (imap_get_literal_count (buf, &bytes) < 0)
896
  if (imap_get_literal_count (buf, &bytes) < 0)
760
    return rc;
897
    return rc;
761
  imap_read_literal (fp, idata, bytes);
898
  imap_read_literal (fp, idata, bytes);
(-)mutt-1.4/imap/util.c (+1 lines)
Lines 257-262 Link Here
257
  if (!idata)
257
  if (!idata)
258
    return;
258
    return;
259
259
260
  FREE (&(*idata)->hcache);
260
  FREE (&(*idata)->capstr);
261
  FREE (&(*idata)->capstr);
261
  mutt_free_list (&(*idata)->flags);
262
  mutt_free_list (&(*idata)->flags);
262
  FREE (&((*idata)->cmd.buf));
263
  FREE (&((*idata)->cmd.buf));
(-)mutt-1.4/init.h (+5 lines)
Lines 818-823 Link Here
818
  ** .pp
818
  ** .pp
819
  ** This variable defaults to your user name on the local machine.
819
  ** This variable defaults to your user name on the local machine.
820
  */
820
  */
821
  { "imap_headercache", DT_STR, R_NONE, UL &ImapHeadercache, UL 0 },
822
  /*
823
  ** .pp
824
  ** The location of the IMAP headercache directory.
825
  */
821
#endif
826
#endif
822
  { "implicit_autoview", DT_BOOL,R_NONE, OPTIMPLICITAUTOVIEW, 0},
827
  { "implicit_autoview", DT_BOOL,R_NONE, OPTIMPLICITAUTOVIEW, 0},
823
  /*
828
  /*

Return to bug 55240