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 *); |