View | Details | Raw Unified | Return to bug 63806
Collapse All | Expand All

(-)./Makefile (+14 lines)
Lines 44-49 Link Here
44
# If you want to have the IMAP header cache define:
44
# If you want to have the IMAP header cache define:
45
#  WITH_MUTT_IMAP_HEADER_CACHE
45
#  WITH_MUTT_IMAP_HEADER_CACHE
46
#
46
#
47
# If you want to have the Maildir header cache define:
48
#  WITH_MUTT_MAILDIR_HEADER_CACHE
49
#
47
# If you want to make SMIME outlook compatible define:
50
# If you want to make SMIME outlook compatible define:
48
#  WITH_MUTT_SMIME_OUTLOOK_COMPAT
51
#  WITH_MUTT_SMIME_OUTLOOK_COMPAT
49
#  This is a default knob and can be disabled by
52
#  This is a default knob and can be disabled by
Lines 195-200 Link Here
195
BROKEN=		"mutt-devel's SASL code appears to be broken"
198
BROKEN=		"mutt-devel's SASL code appears to be broken"
196
LIB_DEPENDS+=	sasl.8:${PORTSDIR}/security/cyrus-sasl
199
LIB_DEPENDS+=	sasl.8:${PORTSDIR}/security/cyrus-sasl
197
.endif
200
.endif
201
.if defined(WITH_MUTT_MAILDIR_HEADER_CACHE)
202
LIB_DEPENDS+=	gdbm.3:${PORTSDIR}/databases/gdbm
203
.endif
198
.if ! defined(WITHOUT_MUTT_SMIME_OUTLOOK_COMPAT)
204
.if ! defined(WITHOUT_MUTT_SMIME_OUTLOOK_COMPAT)
199
pre-configure::
205
pre-configure::
200
	@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-smime-outlook
206
	@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-smime-outlook
Lines 203-208 Link Here
203
pre-configure::
209
pre-configure::
204
	@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-imap-header-cache
210
	@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-imap-header-cache
205
.endif
211
.endif
212
.if defined(WITH_MUTT_MAILDIR_HEADER_CACHE)
213
pre-configure::
214
	@${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/extra-patch-maildir-header-cache
215
.endif
206
216
207
.if ! defined(WITHOUT_MUTT_PGP_PATCH)
217
.if ! defined(WITHOUT_MUTT_PGP_PATCH)
208
SGML_NEEDED=	yes
218
SGML_NEEDED=	yes
Lines 288-293 Link Here
288
.endif
298
.endif
289
.if defined(WITH_MUTT_IMAP_HEADER_CACHE)
299
.if defined(WITH_MUTT_IMAP_HEADER_CACHE)
290
SCRIPTS_ENV+=	MUTT_IMAP_HEADER_CACHE="yes"
300
SCRIPTS_ENV+=	MUTT_IMAP_HEADER_CACHE="yes"
301
.endif
302
.if defined(WITH_MUTT_MAILDIR_HEADER_CACHE)
303
SCRIPTS_ENV+=	MUTT_MAILDIR_HEADER_CACHE="yes"
304
CONFIGURE_ARGS+=	--enable-hcache
291
.endif
305
.endif
292
.if defined(WITH_MUTT_EDIT_THREADS)
306
.if defined(WITH_MUTT_EDIT_THREADS)
293
SCRIPTS_ENV+=	MUTT_EDIT_THREADS="yes"
307
SCRIPTS_ENV+=	MUTT_EDIT_THREADS="yes"
(-)./files/extra-patch-maildir-header-cache (+629 lines)
Line 0 Link Here
1
--- Makefile.am.orig	Fri Mar  5 15:34:57 2004
2
+++ Makefile.am	Fri Mar  5 15:35:55 2004
3
@@ -20,2 +20,3 @@
4
 mutt_SOURCES = $(BUILT_SOURCES) \
5
+	hcache.c \
6
 	addrbook.c alias.c attach.c base64.c browser.c buffy.c color.c \
7
diff -Nru a/configure.in b/configure.in
8
--- configure.in	Sat Feb 28 11:16:57 2004
9
+++ configure.in	Sat Feb 28 11:16:57 2004
10
@@ -768,6 +767,21 @@
11
 
12
         fi])
13
 
14
+dnl -- start cache --
15
+AC_ARG_ENABLE(hcache, [  --enable-hcache            Enable header caching for Maildir folders],
16
+[if test x$enableval = xyes; then
17
+       AC_DEFINE(USE_HCACHE, 1, [Enable header caching for Maildir style mailboxes])
18
+       LIBS="$LIBS -lgdbm"
19
+       AC_CACHE_CHECK(for gdbm_open, ac_cv_gdbmopen,
20
+               [ac_cv_gdbmopen=no
21
+               AC_TRY_LINK([#include <gdbm.h>],[gdbm_open(0,0,0,0,0);],[ac_cv_gdbmopen=yes])])
22
+
23
+       if test $ac_cv_gdbmopen = no; then
24
+               AC_MSG_ERROR(You must install libgdbm with --enable-hcache)
25
+       fi
26
+fi])
27
+dnl -- end cache --
28
+
29
 AC_SUBST(MUTTLIBS)
30
 AC_SUBST(MUTT_LIB_OBJECTS)
31
 AC_SUBST(LIBIMAP)
32
diff -Nru a/globals.h b/globals.h
33
--- globals.h	Sat Feb 28 11:16:57 2004
34
+++ globals.h	Sat Feb 28 11:16:57 2004
35
@@ -63,6 +63,9 @@
36
 WHERE char *Locale;
37
 WHERE char *MailcapPath;
38
 WHERE char *Maildir;
39
+#if USE_HCACHE
40
+WHERE char *MaildirCache;
41
+#endif
42
 WHERE char *MhFlagged;
43
 WHERE char *MhReplied;
44
 WHERE char *MhUnseen;
45
diff -Nru a/hcache.c b/hcache.c
46
--- /dev/null	Wed Dec 31 16:00:00 1969
47
+++ hcache.c	Sat Feb 28 11:16:57 2004
48
@@ -0,0 +1,420 @@
49
+/*
50
+ * Copyright (C) 2004 Thomas Glanzmann <sithglan@stud.uni-erlangen.de>
51
+ *
52
+ *     This program is free software; you can redistribute it and/or modify
53
+ *     it under the terms of the GNU General Public License as published by
54
+ *     the Free Software Foundation; either version 2 of the License, or
55
+ *     (at your option) any later version.
56
+ *
57
+ *     This program is distributed in the hope that it will be useful,
58
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
59
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
60
+ *     GNU General Public License for more details.
61
+ *
62
+ *     You should have received a copy of the GNU General Public License
63
+ *     along with this program; if not, write to the Free Software
64
+ *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
65
+ */
66
+
67
+#if HAVE_CONFIG_H
68
+#include "config.h"
69
+#endif /* HAVE_CONFIG_H */
70
+
71
+#include <gdbm.h>
72
+#include <fcntl.h>
73
+#include "mutt.h"
74
+#include "mime.h"
75
+#include "mx.h"
76
+#include "lib.h"
77
+
78
+static unsigned char *
79
+dump_int(unsigned int i, unsigned char *d, unsigned int *off)
80
+{
81
+	safe_realloc(&d, *off + sizeof(int));
82
+	memcpy(d + *off, &i, sizeof(int));
83
+	(*off) += sizeof(int);
84
+
85
+	return d;
86
+}
87
+
88
+static void
89
+restore_int(unsigned int *i, unsigned char *d, unsigned int *off)
90
+{
91
+	memcpy(i, d + *off, sizeof(int));
92
+	(*off) += sizeof(int);
93
+}
94
+
95
+static unsigned char *
96
+dump_char(char *c, unsigned char *d, unsigned int *off)
97
+{
98
+	unsigned int size;
99
+
100
+	if (c == NULL) {
101
+		size = 0;
102
+		d = dump_int(size, d, off);
103
+		return d;
104
+	}
105
+
106
+	size = strlen(c) + 1;
107
+	d = dump_int(size, d, off);
108
+	safe_realloc(&d, *off + size);
109
+	memcpy(d + *off, c, size);
110
+	*off += size;
111
+
112
+	return d;
113
+}
114
+
115
+static void
116
+restore_char(char **c, unsigned char *d, unsigned int *off)
117
+{
118
+	unsigned int size;
119
+	restore_int(&size, d, off);
120
+
121
+	if (size == 0) {
122
+		*c = NULL;
123
+		return;
124
+	}
125
+
126
+	*c = safe_malloc(size);
127
+	memcpy(*c, d + *off, size);
128
+	*off += size;
129
+}
130
+
131
+static void
132
+skip_char(unsigned char *d, unsigned int *off)
133
+{
134
+	unsigned int size;
135
+	restore_int(&size, d, off);
136
+	*off += size;
137
+}
138
+
139
+static unsigned char *
140
+dump_address(ADDRESS *a, unsigned char *d, unsigned int *off)
141
+{
142
+	unsigned int counter = 0;
143
+	unsigned int start_off = *off;
144
+
145
+	d = dump_int(0xdeadbeaf, d, off);
146
+
147
+	while (a) {
148
+#ifdef EXACT_ADDRESS
149
+		d = dump_char(a->val, d, off);
150
+#endif
151
+		d = dump_char(a->personal, d, off);
152
+		d = dump_char(a->mailbox, d, off);
153
+		d = dump_int(a->group, d, off);
154
+		a = a->next;
155
+		counter++;
156
+	}
157
+
158
+	memcpy(d + start_off, &counter, sizeof(int));
159
+
160
+	return d;
161
+}
162
+
163
+static void
164
+restore_address(ADDRESS **a, unsigned char *d, unsigned int *off)
165
+{
166
+	unsigned int counter;
167
+
168
+	restore_int(&counter, d, off);
169
+
170
+	while (counter) {
171
+		*a = safe_malloc(sizeof(ADDRESS));
172
+#ifdef EXACT_ADDRESS
173
+		restore_char(&(*a)->val, d, off);
174
+#endif
175
+		restore_char(&(*a)->personal, d, off);
176
+		restore_char(&(*a)->mailbox, d, off);
177
+		restore_int((unsigned int *)&(*a)->group, d, off);
178
+		a = &(*a)->next;
179
+		counter--;
180
+	}
181
+
182
+	*a = NULL;
183
+	return;
184
+}
185
+
186
+static unsigned char *
187
+dump_list(LIST *l, unsigned char *d, unsigned int *off)
188
+{
189
+	unsigned int counter = 0;
190
+	unsigned int start_off = *off;
191
+
192
+	d = dump_int(0xdeadbeaf, d, off);
193
+
194
+	while (l) {
195
+		d = dump_char(l->data, d, off);
196
+		l = l->next;
197
+		counter++;
198
+	}
199
+
200
+	memcpy(d + start_off, &counter, sizeof(int));
201
+
202
+	return d;
203
+}
204
+
205
+static void
206
+restore_list(LIST **l, unsigned char *d, unsigned int *off)
207
+{
208
+	unsigned int counter;
209
+
210
+	restore_int(&counter, d, off);
211
+
212
+	while (counter) {
213
+		*l = safe_malloc(sizeof(LIST));
214
+		restore_char(&(*l)->data, d, off);
215
+		l = &(*l)->next;
216
+		counter--;
217
+	}
218
+
219
+	*l = NULL;
220
+	return;
221
+}
222
+
223
+static unsigned char *
224
+dump_parameter(PARAMETER *p, unsigned char *d, unsigned int *off)
225
+{
226
+	unsigned int counter = 0;
227
+	unsigned int start_off = *off;
228
+
229
+	d = dump_int(0xdeadbeaf, d, off);
230
+
231
+	while (p) {
232
+		d = dump_char(p->attribute, d, off);
233
+		d = dump_char(p->value, d, off);
234
+		p = p->next;
235
+		counter++;
236
+	}
237
+
238
+	memcpy(d + start_off, &counter, sizeof(int));
239
+
240
+	return d;
241
+}
242
+
243
+static void
244
+restore_parameter(PARAMETER **p, unsigned char *d, unsigned int *off)
245
+{
246
+	unsigned int counter;
247
+
248
+	restore_int(&counter, d, off);
249
+
250
+	while (counter) {
251
+		*p = safe_malloc(sizeof(PARAMETER));
252
+		restore_char(&(*p)->attribute, d, off);
253
+		restore_char(&(*p)->value, d, off);
254
+		p = &(*p)->next;
255
+		counter--;
256
+	}
257
+
258
+	*p = NULL;
259
+	return;
260
+}
261
+
262
+static unsigned char *
263
+dump_body(BODY *c, unsigned char *d, unsigned int *off)
264
+{
265
+	safe_realloc(&d, *off + sizeof(BODY));
266
+	memcpy(d + *off, c, sizeof(BODY));
267
+	*off += sizeof(BODY);
268
+
269
+	d = dump_char(c->xtype, d, off);
270
+	d = dump_char(c->subtype, d, off);
271
+
272
+	d = dump_parameter(c->parameter, d, off);
273
+
274
+	d = dump_char(c->description, d, off);
275
+	d = dump_char(c->form_name, d, off);
276
+	d = dump_char(c->filename, d, off);
277
+	d = dump_char(c->d_filename, d, off);
278
+
279
+	return d;
280
+}
281
+
282
+static void
283
+restore_body(BODY *c, unsigned char *d, unsigned int *off)
284
+{
285
+	memcpy(c, d + *off, sizeof(BODY));
286
+	*off += sizeof(BODY);
287
+
288
+	restore_char(& c->xtype, d, off);
289
+	restore_char(& c->subtype, d, off);
290
+
291
+	restore_parameter(& c->parameter, d, off);
292
+
293
+	restore_char(& c->description, d, off);
294
+	restore_char(& c->form_name, d, off);
295
+	restore_char(& c->filename, d, off);
296
+	restore_char(& c->d_filename, d, off);
297
+}
298
+
299
+static unsigned char *
300
+dump_envelope(ENVELOPE *e, unsigned char *d, unsigned int *off)
301
+{
302
+	d = dump_address(e->return_path, d, off);
303
+	d = dump_address(e->from, d, off);
304
+	d = dump_address(e->to, d, off);
305
+	d = dump_address(e->cc, d, off);
306
+	d = dump_address(e->bcc, d, off);
307
+	d = dump_address(e->sender, d, off);
308
+	d = dump_address(e->reply_to, d, off);
309
+	d = dump_address(e->mail_followup_to, d, off);
310
+
311
+	d = dump_char(e->subject, d, off);
312
+	d = dump_char(e->real_subj, d, off);
313
+	d = dump_char(e->message_id, d, off);
314
+	d = dump_char(e->supersedes, d, off);
315
+	d = dump_char(e->date, d, off);
316
+	d = dump_char(e->x_label, d, off);
317
+
318
+	d = dump_list(e->references, d, off);
319
+	d = dump_list(e->in_reply_to, d, off);
320
+	d = dump_list(e->userhdrs, d, off);
321
+
322
+	return d;
323
+}
324
+
325
+static void
326
+restore_envelope(ENVELOPE *e, unsigned char *d, unsigned int *off)
327
+{
328
+	restore_address(& e->return_path, d, off);
329
+	restore_address(& e->from, d, off);
330
+	restore_address(& e->to, d, off);
331
+	restore_address(& e->cc, d, off);
332
+	restore_address(& e->bcc, d, off);
333
+	restore_address(& e->sender, d, off);
334
+	restore_address(& e->reply_to, d, off);
335
+	restore_address(& e->mail_followup_to, d, off);
336
+
337
+	restore_char(& e->subject, d, off);
338
+	restore_char(& e->real_subj, d, off);
339
+	restore_char(& e->message_id, d, off);
340
+	restore_char(& e->supersedes, d, off);
341
+	restore_char(& e->date, d, off);
342
+	restore_char(& e->x_label, d, off);
343
+
344
+	restore_list(& e->references, d, off);
345
+	restore_list(& e->in_reply_to, d, off);
346
+	restore_list(& e->userhdrs, d, off);
347
+}
348
+
349
+
350
+/* This function transforms a header into a char so that it is useable by
351
+ * gdbm_store */
352
+
353
+#if HAVE_LANGINFO_CODESET
354
+int
355
+mutt_hcache_charset_matches(char *d)
356
+{
357
+	unsigned int off = sizeof(struct timeval);
358
+	char *charset = NULL;
359
+
360
+	restore_char(&charset, (unsigned char *) d, &off);
361
+
362
+	return (0 == mutt_strcmp(charset, Charset));
363
+}
364
+#endif /* HAVE_LANGINFO_CODESET */
365
+
366
+void *
367
+mutt_hcache_dump(HEADER *h, unsigned int *off)
368
+{
369
+	unsigned char *d = NULL;
370
+	struct timeval now;
371
+	*off             = 0;
372
+
373
+	d = safe_malloc(sizeof(struct timeval));
374
+	gettimeofday(&now, NULL);
375
+	memcpy(d, &now, sizeof(struct timeval));
376
+	*off += sizeof(struct timeval);
377
+
378
+#if HAVE_LANGINFO_CODESET
379
+	d = dump_char(Charset, d, off);
380
+#endif /* HAVE_LANGINFO_CODESET */
381
+
382
+
383
+	safe_realloc(&d, *off + sizeof(HEADER));
384
+	memcpy(d + *off, h, sizeof(HEADER));
385
+	*off += sizeof(HEADER);
386
+
387
+	d = dump_envelope(h->env, d, off);
388
+	d = dump_body(h->content, d, off);
389
+	d = dump_char(h->maildir_flags, d, off);
390
+
391
+	return d;
392
+}
393
+
394
+HEADER *
395
+mutt_hcache_restore(unsigned char *d, HEADER **oh)
396
+{
397
+	unsigned int off = 0;
398
+	HEADER *h        = mutt_new_header();
399
+
400
+	/* skip timeval */
401
+	off += sizeof(struct timeval);
402
+
403
+#if HAVE_LANGINFO_CODESET
404
+	skip_char(d, &off);
405
+#endif /* HAVE_LANGINFO_CODESET */
406
+
407
+	memcpy(h, d + off, sizeof(HEADER));
408
+	off += sizeof(HEADER);
409
+
410
+	h->env = mutt_new_envelope();
411
+	restore_envelope(h->env, d, &off);
412
+
413
+	h->content = mutt_new_body();
414
+	restore_body(h->content, d, &off);
415
+
416
+	restore_char(&h->maildir_flags, d, &off);
417
+
418
+	h->old  = (*oh)->old;
419
+	h->path = safe_strdup((*oh)->path);
420
+	mutt_free_header (oh);
421
+
422
+	return h;
423
+}
424
+
425
+GDBM_FILE
426
+mutt_hcache_open(char *path)
427
+{
428
+	GDBM_FILE db = NULL;
429
+
430
+	if (! path || path[0] == '\0') {
431
+		return NULL;
432
+	}
433
+
434
+	db = gdbm_open(path, 0, GDBM_WRCREAT, 00600, NULL);
435
+	if (db) {
436
+		return db;
437
+	}
438
+
439
+	/* if rw failed try ro */
440
+	return gdbm_open(path, 0, GDBM_READER, 00600, NULL);
441
+}
442
+
443
+void
444
+mutt_hcache_close(GDBM_FILE db)
445
+{
446
+	if (db) {
447
+		gdbm_close(db);
448
+	}
449
+}
450
+
451
+datum
452
+mutt_hcache_fetch(GDBM_FILE db, datum key)
453
+{
454
+	if (! db) {
455
+		datum ret = {NULL, 0};
456
+		return ret;
457
+	}
458
+	return gdbm_fetch(db, key);
459
+}
460
+
461
+int
462
+mutt_hcache_store(GDBM_FILE db, datum key, datum data)
463
+{
464
+	if (! db) {
465
+		return -1;
466
+	}
467
+	return gdbm_store(db, key, data, GDBM_REPLACE);
468
+}
469
diff -Nru a/init.h b/init.h
470
--- init.h	Sat Feb 28 11:16:57 2004
471
+++ init.h	Sat Feb 28 11:16:57 2004
472
@@ -981,6 +981,13 @@
473
   ** \fBDON'T CHANGE THIS SETTING UNLESS YOU ARE REALLY SURE WHAT YOU ARE
474
   ** DOING!\fP
475
   */
476
+#if USE_HCACHE
477
+  { "maildir_cache", DT_PATH, R_NONE, UL &MaildirCache, 0 },
478
+  /*
479
+  ** .pp
480
+  ** Path to the maildir cache file. If unset no cache will be used.
481
+  */
482
+#endif /* USE_HCACHE */
483
   { "maildir_trash", DT_BOOL, R_NONE, OPTMAILDIRTRASH, 0 },
484
   /*
485
   ** .pp
486
diff -Nru a/main.c b/main.c
487
--- main.c	Sat Feb 28 11:16:57 2004
488
+++ main.c	Sat Feb 28 11:16:57 2004
489
@@ -411,6 +411,12 @@
490
 	"-HAVE_GETADDRINFO  "
491
 #endif
492
 
493
+#if USE_HCACHE
494
+	"+USE_HCACHE  "
495
+#else
496
+	"-USE_HCACHE  "
497
+#endif
498
+
499
 	);
500
 
501
 #ifdef ISPELL
502
diff -Nru a/mh.c b/mh.c
503
--- mh.c	Sat Feb 28 11:16:57 2004
504
+++ mh.c	Sat Feb 28 11:16:57 2004
505
@@ -42,6 +42,10 @@
506
 #include <string.h>
507
 #include <utime.h>
508
 
509
+#if USE_HCACHE
510
+#include <gdbm.h>
511
+#endif /* USE_HCACHE */
512
+
513
 struct maildir
514
 {
515
   HEADER *h;
516
@@ -779,11 +783,82 @@
517
   return r;
518
 }
519
 
520
+#if USE_HCACHE
521
+
522
+static ssize_t
523
+maildir_cache_keylen(const char *fn)
524
+{
525
+	char *lastcolon = strrchr(fn, ':');
526
+
527
+	if (lastcolon) {
528
+		*lastcolon = '\0';
529
+	}
530
+
531
+	return strlen(fn) + 1;
532
+}
533
 
534
 /* 
535
  * This function does the second parsing pass for a maildir-style
536
  * folder.
537
  */
538
+void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md)
539
+{
540
+	struct maildir *p;
541
+	GDBM_FILE db = NULL;
542
+	char fn[_POSIX_PATH_MAX];
543
+	char key_fn[_POSIX_PATH_MAX];
544
+	datum key;
545
+	datum data;
546
+	unsigned int size;
547
+	struct timeval *when = NULL;
548
+	struct stat lastchanged;
549
+	int ret;
550
+
551
+	db = mutt_hcache_open(MaildirCache);
552
+
553
+	for (p = md; p; p = p->next) {
554
+		if (! (p && p->h && !p->header_parsed)) {
555
+			continue;
556
+		}
557
+
558
+		snprintf(key_fn, sizeof(key_fn), "%s/%s", ctx->path, p->h->path + 4);
559
+		key.dptr  = key_fn;
560
+		key.dsize = maildir_cache_keylen(key_fn);
561
+		data      = mutt_hcache_fetch(db, key);
562
+		when      = (struct timeval *) data.dptr;
563
+
564
+		snprintf(fn, sizeof (fn), "%s/%s", ctx->path, p->h->path);
565
+		ret = stat(fn, &lastchanged);
566
+
567
+		if (data.dptr != NULL
568
+		 && ret == 0
569
+		 && lastchanged.st_mtime <= when->tv_sec
570
+#if HAVE_LANGINFO_CODESET
571
+		 && mutt_hcache_charset_matches(data.dptr)
572
+#endif /* HAVE_LANGINFO_CODESET */
573
+		 ) {
574
+			p->h = mutt_hcache_restore((unsigned char *)data.dptr, &p->h);
575
+			FREE(& data.dptr);
576
+			maildir_parse_flags(p->h, fn);
577
+
578
+		} else if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h)) {
579
+			maildir_parse_flags(p->h, fn);
580
+			p->header_parsed = 1;
581
+			if (db) {
582
+				/* only try this if db connection is available */
583
+				data.dptr = mutt_hcache_dump(p->h, &size); 
584
+				data.dsize = size;
585
+				mutt_hcache_store(db, key, data);
586
+				FREE(& data.dptr);
587
+			}
588
+		} else {
589
+			mutt_free_header (&p->h);
590
+		}
591
+	}
592
+	mutt_hcache_close(db);
593
+}
594
+
595
+#else /* USE_HCACHE */
596
 
597
 void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md)
598
 {
599
@@ -801,7 +876,7 @@
600
     }
601
 }
602
 
603
-
604
+#endif /* USE_HCACHE */
605
 
606
 /* Read a MH/maildir style mailbox.
607
  *
608
diff -Nru a/protos.h b/protos.h
609
--- protos.h	Sat Feb 28 11:16:57 2004
610
+++ protos.h	Sat Feb 28 11:16:57 2004
611
@@ -99,6 +99,18 @@
612
 ENVELOPE *mutt_read_rfc822_header (FILE *, HEADER *, short, short);
613
 HEADER *mutt_dup_header (HEADER *);
614
 
615
+#if USE_HCACHE
616
+#include <gdbm.h>
617
+GDBM_FILE mutt_hcache_open(char *path);
618
+void mutt_hcache_close(GDBM_FILE db);
619
+void * mutt_hcache_dump(HEADER *h, unsigned int *off);
620
+HEADER * mutt_hcache_restore(unsigned char *d, HEADER **oh);
621
+datum mutt_hcache_fetch(GDBM_FILE db, datum key);
622
+int mutt_hcache_store(GDBM_FILE db, datum key, datum data);
623
+int mutt_hcache_charset_matches(char *d);
624
+#endif /* USE_HCACHE */
625
+
626
+
627
 ATTACHPTR **mutt_gen_attach_list (BODY *, int, ATTACHPTR **, short *, short *, int, int);
628
 
629
 time_t mutt_decrease_mtime (const char *, struct stat *);
(-)./scripts/generate-plist (+3 lines)
Lines 147-152 Link Here
147
    if [ "$MUTT_IMAP_HEADER_CACHE" = "yes" ]; then
147
    if [ "$MUTT_IMAP_HEADER_CACHE" = "yes" ]; then
148
      html=$(($html + 1))
148
      html=$(($html + 1))
149
    fi
149
    fi
150
    if [ "$MUTT_MAILDIR_HEADER_CACHE" = "yes" ]; then
151
      html=$(($html + 1))
152
    fi
150
    if [ "$MUTT_SIGNATURE_MENU" = "yes" ]; then
153
    if [ "$MUTT_SIGNATURE_MENU" = "yes" ]; then
151
      html=$(($html + 1))
154
      html=$(($html + 1))
152
    fi
155
    fi

Return to bug 63806