summaryrefslogtreecommitdiffabout
path: root/libetpan/src/driver/interface/maildriver_tools.c
Unidiff
Diffstat (limited to 'libetpan/src/driver/interface/maildriver_tools.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/driver/interface/maildriver_tools.c841
1 files changed, 841 insertions, 0 deletions
diff --git a/libetpan/src/driver/interface/maildriver_tools.c b/libetpan/src/driver/interface/maildriver_tools.c
new file mode 100644
index 0000000..4501b23
--- a/dev/null
+++ b/libetpan/src/driver/interface/maildriver_tools.c
@@ -0,0 +1,841 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildriver_tools.h"
37
38#include "libetpan-config.h"
39
40#include <stdlib.h>
41#include <ctype.h>
42#include <string.h>
43#include <dirent.h>
44#include <unistd.h>
45
46#include "maildriver.h"
47#include "mailmessage.h"
48#include "mailstream.h"
49#include "mailmime.h"
50#include "mail_cache_db.h"
51
52/* ********************************************************************* */
53/* tools */
54
55
56int
57maildriver_generic_get_envelopes_list(mailsession * session,
58 struct mailmessage_list * env_list)
59{
60 int r;
61 unsigned i;
62#if 0
63 uint32_t j;
64 uint32_t last_msg;
65
66 last_msg = 0;
67#endif
68
69#if 0
70 j = 0;
71 i = 0;
72 while (i < env_list->tab->len) {
73 mailmessage * msg;
74 uint32_t index;
75
76 msg = carray_get(env_list->tab, i);
77
78 index = msg->index;
79
80 if (msg->fields == NULL) {
81 struct mailimf_fields * fields;
82
83 r = mailmessage_fetch_envelope(msg, &fields);
84 if (r != MAIL_NO_ERROR) {
85 /* do nothing */
86 }
87 else {
88 msg->fields = fields;
89
90 carray_set(env_list->tab, j, msg);
91
92 j ++;
93 last_msg = i + 1;
94 }
95 mailmessage_flush(msg);
96 }
97 else {
98 j ++;
99 last_msg = i + 1;
100 }
101
102 i ++;
103 }
104
105 for(i = last_msg ; i < env_list->tab->len ; i ++) {
106 mailmessage_free(carray_get(env_list->tab, i));
107 carray_set(env_list->tab, i, NULL);
108 }
109
110 r = carray_set_size(env_list->tab, j);
111 if (r < 0)
112 return MAIL_ERROR_MEMORY;
113#endif
114
115 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
116 mailmessage * msg;
117
118 msg = carray_get(env_list->msg_tab, i);
119
120 if (msg->msg_fields == NULL) {
121 struct mailimf_fields * fields;
122
123 r = mailmessage_fetch_envelope(msg, &fields);
124 if (r != MAIL_NO_ERROR) {
125 /* do nothing */
126 }
127 else {
128 msg->msg_fields = fields;
129 }
130 mailmessage_flush(msg);
131 }
132 }
133
134 return MAIL_NO_ERROR;
135}
136
137
138#if 0
139static int is_search_header_only(struct mail_search_key * key)
140{
141 clistiter * cur;
142 int result;
143
144 switch (key->type) {
145 case MAIL_SEARCH_KEY_ANSWERED:
146 case MAIL_SEARCH_KEY_BCC:
147 case MAIL_SEARCH_KEY_BEFORE:
148 case MAIL_SEARCH_KEY_CC:
149 case MAIL_SEARCH_KEY_DELETED:
150 case MAIL_SEARCH_KEY_FLAGGED:
151 case MAIL_SEARCH_KEY_FROM:
152 case MAIL_SEARCH_KEY_NEW:
153 case MAIL_SEARCH_KEY_OLD:
154 case MAIL_SEARCH_KEY_ON:
155 case MAIL_SEARCH_KEY_RECENT:
156 case MAIL_SEARCH_KEY_SEEN:
157 case MAIL_SEARCH_KEY_SINCE:
158 case MAIL_SEARCH_KEY_SUBJECT:
159 case MAIL_SEARCH_KEY_TO:
160 case MAIL_SEARCH_KEY_UNANSWERED:
161 case MAIL_SEARCH_KEY_UNDELETED:
162 case MAIL_SEARCH_KEY_UNFLAGGED:
163 case MAIL_SEARCH_KEY_UNSEEN:
164 case MAIL_SEARCH_KEY_HEADER:
165 case MAIL_SEARCH_KEY_LARGER:
166 case MAIL_SEARCH_KEY_NOT:
167 case MAIL_SEARCH_KEY_SMALLER:
168 case MAIL_SEARCH_KEY_ALL:
169 return TRUE;
170
171 case MAIL_SEARCH_KEY_BODY:
172 case MAIL_SEARCH_KEY_TEXT:
173 return FALSE;
174
175 case MAIL_SEARCH_KEY_OR:
176 return (is_search_header_only(key->or1) &&
177 is_search_header_only(key->or2));
178
179 case MAIL_SEARCH_KEY_MULTIPLE:
180 result = TRUE;
181 for (cur = clist_begin(key->multiple) ; cur != NULL ;
182 cur = clist_next(cur))
183 result = result && is_search_header_only(clist_content(cur));
184 return result;
185
186 default:
187 return TRUE;
188 }
189}
190
191static int match_header(struct mailimf_fields * fields,
192 char * name, char * value)
193{
194 clistiter * cur;
195
196 for(cur = clist_begin(fields->list) ; cur != NULL ;
197 cur = clist_content(cur)) {
198 struct mailimf_field * field;
199 struct mailimf_optional_field * opt_field;
200
201 field = clist_content(cur);
202 opt_field = field->optional_field;
203 if ((char) toupper((unsigned char) opt_field->name[0]) ==
204 (char) toupper((unsigned char) name[0])) {
205 if (strcasecmp(opt_field->name, name) == 0)
206 if (strstr(opt_field->value, value) != NULL)
207 return TRUE;
208 }
209 }
210 return FALSE;
211}
212
213static int comp_date(struct mailimf_fields * fields,
214 struct mailimf_date_time * ref_date)
215{
216 clistiter * cur;
217 struct mailimf_date_time * date;
218 int r;
219
220 date = NULL;
221 for(cur = clist_begin(fields->list) ; cur != NULL ;
222 cur = clist_content(cur)) {
223 struct mailimf_field * field;
224 struct mailimf_optional_field * opt_field;
225
226 field = clist_content(cur);
227 opt_field = field->optional_field;
228 if ((char) toupper((unsigned char) opt_field->name[0]) == 'D') {
229 if (strcasecmp(opt_field->name, "Date") == 0) {
230 size_t cur_token;
231
232 cur_token = 0;
233 r = mailimf_date_time_parse(opt_field->value, strlen(opt_field->value),
234 &cur_token, &date);
235 if (r == MAILIMF_NO_ERROR)
236 break;
237 else if (r == MAILIMF_ERROR_PARSE) {
238 /* do nothing */
239 }
240 else
241 break;
242 }
243 }
244 }
245
246 if (date == NULL)
247 return 0;
248
249 return mailimf_date_time_comp(date, ref_date);
250}
251
252static int match_messages(char * message,
253 size_t size,
254 struct mailimf_fields * fields,
255 int32_t flags,
256 char * charset,
257 struct mail_search_key * key)
258{
259 clistiter * cur;
260 size_t length;
261 size_t cur_token;
262 int r;
263
264 switch (key->type) {
265
266 /* flags */
267 case MAIL_SEARCH_KEY_ANSWERED:
268 return ((flags & MAIL_FLAG_ANSWERED) != 0);
269
270 case MAIL_SEARCH_KEY_FLAGGED:
271 return ((flags & MAIL_FLAG_FLAGGED) != 0);
272
273 case MAIL_SEARCH_KEY_DELETED:
274 return ((flags & MAIL_FLAG_DELETED) != 0);
275
276 case MAIL_SEARCH_KEY_RECENT:
277 return ((flags & MAIL_FLAG_NEW) != 0) &&
278 ((flags & MAIL_FLAG_SEEN) == 0);
279
280 case MAIL_SEARCH_KEY_SEEN:
281 return ((flags & MAIL_FLAG_SEEN) != 0);
282
283 case MAIL_SEARCH_KEY_NEW:
284 return ((flags & MAIL_FLAG_NEW) != 0);
285
286 case MAIL_SEARCH_KEY_OLD:
287 return ((flags & MAIL_FLAG_NEW) == 0);
288
289 case MAIL_SEARCH_KEY_UNANSWERED:
290 return ((flags & MAIL_FLAG_ANSWERED) == 0);
291
292 case MAIL_SEARCH_KEY_UNDELETED:
293 return ((flags & MAIL_FLAG_DELETED) == 0);
294
295 case MAIL_SEARCH_KEY_UNFLAGGED:
296 return ((flags & MAIL_FLAG_FLAGGED) == 0);
297
298 case MAIL_SEARCH_KEY_UNSEEN:
299 return ((flags & MAIL_FLAG_SEEN) == 0);
300
301 /* headers */
302 case MAIL_SEARCH_KEY_BCC:
303 return match_header(fields, "Bcc", key->bcc);
304
305 case MAIL_SEARCH_KEY_CC:
306 return match_header(fields, "Cc", key->cc);
307
308 case MAIL_SEARCH_KEY_FROM:
309 return match_header(fields, "From", key->from);
310
311 case MAIL_SEARCH_KEY_SUBJECT:
312 return match_header(fields, "Subject", key->subject);
313
314 case MAIL_SEARCH_KEY_TO:
315 return match_header(fields, "To", key->to);
316
317 case MAIL_SEARCH_KEY_HEADER:
318 return match_header(fields, key->header_name, key->header_value);
319
320 /* date */
321 case MAIL_SEARCH_KEY_BEFORE:
322 return (comp_date(fields, key->before) <= 0);
323
324 case MAIL_SEARCH_KEY_ON:
325 return (comp_date(fields, key->before) == 0);
326
327 case MAIL_SEARCH_KEY_SINCE:
328 return (comp_date(fields, key->before) >= 0);
329
330 /* boolean */
331 case MAIL_SEARCH_KEY_NOT:
332 return (!match_messages(message, size, fields, flags, charset, key->not));
333 case MAIL_SEARCH_KEY_OR:
334 return (match_messages(message, size, fields, flags, charset, key->or1) ||
335 match_messages(message, size, fields, flags, charset, key->or2));
336
337 case MAIL_SEARCH_KEY_MULTIPLE:
338 for(cur = clist_begin(key->multiple) ; cur != NULL ;
339 cur = clist_next(cur)) {
340 if (!match_messages(message, size, fields, flags, charset,
341 clist_content(cur)))
342 return FALSE;
343 }
344
345 return TRUE;
346
347 /* size */
348 case MAIL_SEARCH_KEY_SMALLER:
349 return (size <= key->smaller);
350
351 case MAIL_SEARCH_KEY_LARGER:
352 return (size >= key->larger);
353
354 case MAIL_SEARCH_KEY_BODY:
355 length = strlen(message);
356
357 cur_token = 0;
358 while (1) {
359 r = mailimf_ignore_field_parse(message, length, &cur_token);
360 if (r == MAILIMF_NO_ERROR) {
361 /* do nothing */
362 }
363 else
364 break;
365 }
366
367 return (strstr(message + cur_token, key->body) != NULL);
368
369 case MAIL_SEARCH_KEY_TEXT:
370 return (strstr(message, key->body) != NULL);
371
372 case MAIL_SEARCH_KEY_ALL:
373 default:
374 return TRUE;
375 }
376}
377
378int maildriver_generic_search_messages(mailsession * session, char * charset,
379 struct mail_search_key * key,
380 struct mail_search_result ** result)
381{
382 int header;
383 clist * list;
384 struct mail_search_result * search_result;
385 int r;
386 struct mailmessage_list * env_list;
387 int res;
388 unsigned int i;
389
390 header = is_search_header_only(key);
391
392 r = mailsession_get_messages_list(session, &env_list);
393 if (r != MAIL_NO_ERROR)
394 return r;
395
396 list = NULL;
397 for(i = 0 ; i < carray_count(env_list->tab) ; i ++) {
398 char * message;
399 size_t length;
400 struct mail_info * info;
401 uint32_t flags;
402 struct mailimf_fields * fields;
403 size_t cur_token;
404
405 info = carray_get(env_list->tab, i);
406
407 if (!header) {
408 r = mailsession_fetch_message(session, info->index, &message, &length);
409 if (r != MAIL_NO_ERROR) {
410 res = r;
411 goto free_list;
412 }
413
414 cur_token = 0;
415 r = mailimf_optional_fields_parse(message, length,
416 &cur_token, &fields);
417 if (r != MAILIMF_NO_ERROR) {
418 res = MAIL_ERROR_PARSE;
419 goto free_list;
420 }
421 }
422 else {
423 char * msg_header;
424 int r;
425 size_t cur_token;
426 size_t header_len;
427
428 r = mailsession_fetch_message_header(session, info->index, &msg_header,
429 &header_len);
430 if (r != MAIL_NO_ERROR) {
431 res = r;
432 goto free_list;
433 }
434
435 message = NULL;
436 cur_token = 0;
437 r = mailimf_optional_fields_parse(msg_header, header_len,
438 &cur_token, &fields);
439 if (r != MAILIMF_NO_ERROR) {
440 res = MAIL_ERROR_PARSE;
441 goto free_list;
442 }
443
444 mailsession_fetch_result_free(session, msg_header);
445 }
446
447 r = mailsession_get_message_flags(session, info->index, &flags);
448 if (r != MAIL_NO_ERROR) {
449 res = r;
450 goto free_list;
451 }
452
453 if (match_messages(message, info->size, fields, flags,
454 charset, key)) {
455 uint32_t * pnum;
456
457 pnum = malloc(sizeof(* pnum));
458 if (pnum == NULL) {
459 if (message != NULL)
460 mailsession_fetch_result_free(session, message);
461 res = MAIL_ERROR_MEMORY;
462 goto free_list;
463 }
464
465 * pnum = info->index;
466
467 r = clist_append(list, pnum);
468 if (r < 0) {
469 free(pnum);
470 if (message != NULL)
471 mailsession_fetch_result_free(session, message);
472 res = MAIL_ERROR_MEMORY;
473 goto free_list;
474 }
475 }
476
477 if (message != NULL)
478 mailsession_fetch_result_free(session, message);
479 }
480
481 search_result = mail_search_result_new(list);
482 if (search_result == NULL) {
483 res = MAIL_ERROR_MEMORY;
484 goto free_list;
485 }
486
487 * result = search_result;
488
489 return MAIL_NO_ERROR;
490
491 free_list:
492 clist_foreach(list, (clist_func) free, NULL);
493 clist_free(list);
494 mailmessage_list_free(env_list);
495 return res;
496}
497#endif
498
499#if 0
500int maildriver_generic_search_messages(mailsession * session, char * charset,
501 struct mail_search_key * key,
502 struct mail_search_result ** result)
503{
504 return MAIL_ERROR_NOT_IMPLEMENTED;
505}
506#endif
507
508int
509maildriver_env_list_to_msg_list(struct mailmessage_list * env_list,
510 clist ** result)
511{
512 clist * msg_list;
513 int r;
514 int res;
515 unsigned int i;
516
517 msg_list = clist_new();
518 if (msg_list == NULL) {
519 res = MAIL_ERROR_MEMORY;
520 goto err;
521 }
522
523 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
524 mailmessage * msg;
525
526 msg = carray_get(env_list->msg_tab, i);
527
528 if (msg->msg_fields == NULL) {
529 uint32_t * pindex;
530
531 pindex = malloc(sizeof(* pindex));
532 if (pindex == NULL) {
533 res = MAIL_ERROR_MEMORY;
534 goto free_msg_list;
535 }
536
537 * pindex = msg->msg_index;
538
539 r = clist_append(msg_list, pindex);
540 if (r < 0) {
541 free(pindex);
542 res = MAIL_ERROR_MEMORY;
543 goto free_msg_list;
544 }
545
546 }
547 }
548
549 * result = msg_list;
550
551 return MAIL_NO_ERROR;
552
553 free_msg_list:
554 clist_foreach(msg_list, (clist_func) free, NULL);
555 clist_free(msg_list);
556 err:
557 return res;
558}
559
560
561int
562maildriver_env_list_to_msg_list_no_flags(struct mailmessage_list * env_list,
563 clist ** result)
564{
565 clist * msg_list;
566 int r;
567 int res;
568 unsigned int i;
569
570 msg_list = clist_new();
571 if (msg_list == NULL) {
572 res = MAIL_ERROR_MEMORY;
573 goto err;
574 }
575
576 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
577 mailmessage * msg;
578
579 msg = carray_get(env_list->msg_tab, i);
580
581 if (msg->msg_flags == NULL) {
582 uint32_t * pindex;
583
584 pindex = malloc(sizeof(* pindex));
585 if (pindex == NULL) {
586 res = MAIL_ERROR_MEMORY;
587 goto free_msg_list;
588 }
589
590 * pindex = msg->msg_index;
591
592 r = clist_append(msg_list, pindex);
593 if (r < 0) {
594 free(pindex);
595 res = MAIL_ERROR_MEMORY;
596 goto free_msg_list;
597 }
598
599 }
600 }
601
602 * result = msg_list;
603
604 return MAIL_NO_ERROR;
605
606 free_msg_list:
607 clist_foreach(msg_list, (clist_func) free, NULL);
608 clist_free(msg_list);
609 err:
610 return res;
611}
612
613
614
615int maildriver_imf_error_to_mail_error(int error)
616{
617 switch (error) {
618 case MAILIMF_NO_ERROR:
619 return MAIL_NO_ERROR;
620
621 case MAILIMF_ERROR_PARSE:
622 return MAIL_ERROR_PARSE;
623
624 case MAILIMF_ERROR_MEMORY:
625 return MAIL_ERROR_MEMORY;
626
627 case MAILIMF_ERROR_INVAL:
628 return MAIL_ERROR_INVAL;
629
630 case MAILIMF_ERROR_FILE:
631 return MAIL_ERROR_FILE;
632
633 default:
634 return MAIL_ERROR_INVAL;
635 }
636}
637
638char * maildriver_quote_mailbox(char * mb)
639{
640 MMAPString * gstr;
641 char * str;
642
643 gstr = mmap_string_new("");
644 if (gstr == NULL)
645 return NULL;
646
647 while (* mb != 0) {
648 char hex[3];
649
650 if (((* mb >= 'a') && (* mb <= 'z')) ||
651 ((* mb >= 'A') && (* mb <= 'Z')) ||
652 ((* mb >= '0') && (* mb <= '9')))
653 mmap_string_append_c(gstr, * mb);
654 else {
655 if (mmap_string_append_c(gstr, '%') == NULL)
656 goto free;
657 snprintf(hex, 3, "%02x", (unsigned char) (* mb));
658 if (mmap_string_append(gstr, hex) == NULL)
659 goto free;
660 }
661 mb ++;
662 }
663
664 str = strdup(gstr->str);
665 if (str == NULL)
666 goto free;
667
668 mmap_string_free(gstr);
669
670 return str;
671
672 free:
673 mmap_string_free(gstr);
674 return NULL;
675}
676
677
678
679int maildriver_cache_clean_up(struct mail_cache_db * cache_db_env,
680 struct mail_cache_db * cache_db_flags,
681 struct mailmessage_list * env_list)
682{
683 chash * hash_exist;
684 int res;
685 int r;
686 char keyname[PATH_MAX];
687 unsigned int i;
688
689 /* flush cache */
690
691 hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
692 if (hash_exist == NULL) {
693 res = MAIL_ERROR_MEMORY;
694 goto err;
695 }
696
697 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
698 mailmessage * msg;
699 chashdatum key;
700 chashdatum value;
701
702 msg = carray_get(env_list->msg_tab, i);
703
704 value.data = NULL;
705 value.len = 0;
706
707 if (cache_db_env != NULL) {
708 snprintf(keyname, PATH_MAX, "%s-envelope", msg->msg_uid);
709
710 key.data = keyname;
711 key.len = strlen(keyname);
712 r = chash_set(hash_exist, &key, &value, NULL);
713 if (r < 0) {
714 res = MAIL_ERROR_MEMORY;
715 goto free;
716 }
717 }
718
719 if (cache_db_flags != NULL) {
720 snprintf(keyname, PATH_MAX, "%s-flags", msg->msg_uid);
721
722 key.data = keyname;
723 key.len = strlen(keyname);
724 r = chash_set(hash_exist, &key, &value, NULL);
725 if (r < 0) {
726 res = MAIL_ERROR_MEMORY;
727 goto free;
728 }
729 }
730 }
731
732 /* clean up */
733 if (cache_db_env != NULL)
734 mail_cache_db_clean_up(cache_db_env, hash_exist);
735 if (cache_db_flags != NULL)
736 mail_cache_db_clean_up(cache_db_flags, hash_exist);
737
738 chash_free(hash_exist);
739
740 return MAIL_NO_ERROR;
741
742 free:
743 chash_free(hash_exist);
744 err:
745 return res;
746}
747
748
749/*
750 maildriver_message_cache_clean_up()
751
752 remove files in cache_dir that does not correspond to a message.
753
754 get_uid_from_filename() modifies the given filename so that it
755 is a uid when returning from the function. If get_uid_from_filename()
756 clears the content of file (set to empty string), this means that
757 this file should not be deleted.
758*/
759
760int maildriver_message_cache_clean_up(char * cache_dir,
761 struct mailmessage_list * env_list,
762 void (* get_uid_from_filename)(char *))
763{
764 chash * hash_exist;
765 DIR * d;
766 char cached_filename[PATH_MAX];
767 struct dirent * ent;
768 char keyname[PATH_MAX];
769 unsigned int i;
770 int res;
771 int r;
772
773 /* remove files */
774
775 hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
776 if (hash_exist == NULL) {
777 res = MAIL_ERROR_MEMORY;
778 goto err;
779 }
780
781 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
782 mailmessage * msg;
783 chashdatum key;
784 chashdatum value;
785
786 msg = carray_get(env_list->msg_tab, i);
787
788 key.data = msg->msg_uid;
789 key.len = strlen(msg->msg_uid);
790 value.data = NULL;
791 value.len = 0;
792 r = chash_set(hash_exist, &key, &value, NULL);
793 if (r < 0) {
794 res = MAIL_ERROR_MEMORY;
795 goto free;
796 }
797 }
798
799 d = opendir(cache_dir);
800 while ((ent = readdir(d)) != NULL) {
801 chashdatum key;
802 chashdatum value;
803
804 if (strcmp(ent->d_name, ".") == 0)
805 continue;
806
807 if (strcmp(ent->d_name, "..") == 0)
808 continue;
809
810 if (strstr(ent->d_name, ".db") != NULL)
811 continue;
812
813 strncpy(keyname, ent->d_name, sizeof(keyname));
814 keyname[sizeof(keyname) - 1] = '\0';
815
816 get_uid_from_filename(keyname);
817
818 if (* keyname == '\0')
819 continue;
820
821 key.data = keyname;
822 key.len = strlen(keyname);
823
824 r = chash_get(hash_exist, &key, &value);
825 if (r < 0) {
826 snprintf(cached_filename, sizeof(cached_filename),
827 "%s/%s", cache_dir, ent->d_name);
828 unlink(cached_filename);
829 }
830 }
831 closedir(d);
832
833 chash_free(hash_exist);
834
835 return MAIL_NO_ERROR;
836
837 free:
838 chash_free(hash_exist);
839 err:
840 return res;
841}