summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic/pop3driver_cached.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/generic/pop3driver_cached.c') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached.c857
1 files changed, 857 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/pop3driver_cached.c b/kmicromail/libetpan/generic/pop3driver_cached.c
new file mode 100644
index 0000000..6f97303
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached.c
@@ -0,0 +1,857 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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 "pop3driver_cached.h"
37
38#include "libetpan-config.h"
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <fcntl.h>
43#include <string.h>
44#include <unistd.h>
45#include <stdlib.h>
46
47#include "mail.h"
48#include "mail_cache_db.h"
49
50#include "maildriver.h"
51#include "mailmessage.h"
52#include "pop3driver.h"
53#include "mailpop3.h"
54#include "generic_cache.h"
55#include "imfcache.h"
56#include "pop3driver_cached_message.h"
57#include "pop3driver_tools.h"
58#include "maildriver_tools.h"
59
60static int pop3driver_cached_initialize(mailsession * session);
61
62static void pop3driver_cached_uninitialize(mailsession * session);
63
64static int pop3driver_cached_parameters(mailsession * session,
65 int id, void * value);
66
67static int pop3driver_cached_connect_stream(mailsession * session,
68 mailstream * s);
69
70static int pop3driver_cached_starttls(mailsession * session);
71
72static int pop3driver_cached_login(mailsession * session,
73 char * userid, char * password);
74
75static int pop3driver_cached_logout(mailsession * session);
76
77static int pop3driver_cached_check_folder(mailsession * session);
78
79static int pop3driver_cached_noop(mailsession * session);
80
81static int pop3driver_cached_expunge_folder(mailsession * session);
82
83static int pop3driver_cached_status_folder(mailsession * session,
84 char * mb, uint32_t * result_messages, uint32_t * result_recent,
85 uint32_t * result_unseen);
86
87static int pop3driver_cached_messages_number(mailsession * session,
88 char * mb,
89 uint32_t * result);
90
91static int pop3driver_cached_recent_number(mailsession * session,
92 char * mb,
93 uint32_t * result);
94
95static int pop3driver_cached_unseen_number(mailsession * session,
96 char * mb,
97 uint32_t * result);
98
99static int pop3driver_cached_remove_message(mailsession * session,
100 uint32_t num);
101
102static int
103pop3driver_cached_get_messages_list(mailsession * session,
104 struct mailmessage_list ** result);
105
106static int
107pop3driver_cached_get_envelopes_list(mailsession * session,
108 struct mailmessage_list * env_list);
109
110static int pop3driver_cached_get_message(mailsession * session,
111 uint32_t num, mailmessage ** result);
112
113static mailsession_driver local_pop3_cached_session_driver = {
114 .sess_name = "pop3-cached",
115
116 .sess_initialize = pop3driver_cached_initialize,
117 .sess_uninitialize = pop3driver_cached_uninitialize,
118
119 .sess_parameters = pop3driver_cached_parameters,
120
121 .sess_connect_stream = pop3driver_cached_connect_stream,
122 .sess_connect_path = NULL,
123 .sess_starttls = pop3driver_cached_starttls,
124 .sess_login = pop3driver_cached_login,
125 .sess_logout = pop3driver_cached_logout,
126 .sess_noop = pop3driver_cached_noop,
127
128 .sess_build_folder_name = NULL,
129 .sess_create_folder = NULL,
130 .sess_delete_folder = NULL,
131 .sess_rename_folder = NULL,
132 .sess_check_folder = pop3driver_cached_check_folder,
133 .sess_examine_folder = NULL,
134 .sess_select_folder = NULL,
135 .sess_expunge_folder = pop3driver_cached_expunge_folder,
136 .sess_status_folder = pop3driver_cached_status_folder,
137 .sess_messages_number = pop3driver_cached_messages_number,
138 .sess_recent_number = pop3driver_cached_recent_number,
139 .sess_unseen_number = pop3driver_cached_unseen_number,
140 .sess_list_folders = NULL,
141 .sess_lsub_folders = NULL,
142 .sess_subscribe_folder = NULL,
143 .sess_unsubscribe_folder = NULL,
144
145 .sess_append_message = NULL,
146 .sess_copy_message = NULL,
147 .sess_move_message = NULL,
148
149 .sess_get_messages_list = pop3driver_cached_get_messages_list,
150 .sess_get_envelopes_list = pop3driver_cached_get_envelopes_list,
151 .sess_remove_message = pop3driver_cached_remove_message,
152#if 0
153 .sess_search_messages = maildriver_generic_search_messages,
154#endif
155
156 .sess_get_message = pop3driver_cached_get_message,
157 .sess_get_message_by_uid = NULL,
158};
159
160mailsession_driver * pop3_cached_session_driver =
161&local_pop3_cached_session_driver;
162
163#define ENV_NAME "env.db"
164#define FLAGS_NAME "flags.db"
165
166
167static inline struct pop3_cached_session_state_data *
168get_cached_data(mailsession * session)
169{
170 return session->sess_data;
171}
172
173static inline mailsession * get_ancestor(mailsession * session)
174{
175 return get_cached_data(session)->pop3_ancestor;
176}
177
178static inline struct pop3_session_state_data *
179get_ancestor_data(mailsession * session)
180{
181 return get_ancestor(session)->sess_data;
182}
183
184static inline mailpop3 * get_pop3_session(mailsession * session)
185{
186 return get_ancestor_data(session)->pop3_session;
187}
188
189static int pop3driver_cached_initialize(mailsession * session)
190{
191 struct pop3_cached_session_state_data * data;
192
193 data = malloc(sizeof(* data));
194 if (data == NULL)
195 goto err;
196
197 data->pop3_flags_store = mail_flags_store_new();
198 if (data->pop3_flags_store == NULL)
199 goto free_data;
200
201 data->pop3_ancestor = mailsession_new(pop3_session_driver);
202 if (data->pop3_ancestor == NULL)
203 goto free_store;
204
205 data->pop3_flags_hash = chash_new(128, CHASH_COPYNONE);
206 if (data->pop3_flags_hash == NULL)
207 goto free_session;
208
209 session->sess_data = data;
210
211 return MAIL_NO_ERROR;
212
213 free_session:
214 mailsession_free(data->pop3_ancestor);
215 free_store:
216 mail_flags_store_free(data->pop3_flags_store);
217 free_data:
218 free(data);
219 err:
220 return MAIL_ERROR_MEMORY;
221}
222
223static int pop3_flags_store_process(char * flags_directory,
224 struct mail_flags_store * flags_store)
225{
226 char filename_flags[PATH_MAX];
227 struct mail_cache_db * cache_db_flags;
228 MMAPString * mmapstr;
229 unsigned int i;
230 int r;
231 int res;
232
233 if (carray_count(flags_store->fls_tab) == 0)
234 return MAIL_NO_ERROR;
235
236 snprintf(filename_flags, PATH_MAX, "%s/%s",
237 flags_directory, FLAGS_NAME);
238
239 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
240 if (r < 0) {
241 res = MAIL_ERROR_FILE;
242 goto err;
243 }
244
245 mmapstr = mmap_string_new("");
246 if (mmapstr == NULL) {
247 res = MAIL_ERROR_MEMORY;
248 goto close_db_flags;
249 }
250
251 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
252 mailmessage * msg;
253
254 msg = carray_get(flags_store->fls_tab, i);
255
256 r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
257 msg->msg_uid, msg->msg_flags);
258 }
259
260 mmap_string_free(mmapstr);
261 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
262
263 mail_flags_store_clear(flags_store);
264
265 return MAIL_NO_ERROR;
266
267 close_db_flags:
268 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
269 err:
270 return res;
271}
272
273static void pop3driver_cached_uninitialize(mailsession * session)
274{
275 struct pop3_cached_session_state_data * data;
276
277 data = get_cached_data(session);
278
279 pop3_flags_store_process(data->pop3_flags_directory,
280 data->pop3_flags_store);
281
282 mail_flags_store_free(data->pop3_flags_store);
283
284 chash_free(data->pop3_flags_hash);
285 mailsession_free(data->pop3_ancestor);
286 free(data);
287
288 session->sess_data = data;
289}
290
291static int pop3driver_cached_check_folder(mailsession * session)
292{
293 struct pop3_cached_session_state_data * pop3_data;
294
295 pop3_data = get_cached_data(session);
296
297 pop3_flags_store_process(pop3_data->pop3_flags_directory,
298 pop3_data->pop3_flags_store);
299
300 return MAIL_NO_ERROR;
301}
302
303static int pop3driver_cached_parameters(mailsession * session,
304 int id, void * value)
305{
306 struct pop3_cached_session_state_data * data;
307 int r;
308
309 data = get_cached_data(session);
310
311 switch (id) {
312 case POP3DRIVER_CACHED_SET_CACHE_DIRECTORY:
313 strncpy(data->pop3_cache_directory, value, PATH_MAX);
314 data->pop3_cache_directory[PATH_MAX - 1] = '\0';
315
316 r = generic_cache_create_dir(data->pop3_cache_directory);
317 if (r != MAIL_NO_ERROR)
318 return r;
319
320 return MAIL_NO_ERROR;
321
322 case POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY:
323 strncpy(data->pop3_flags_directory, value, PATH_MAX);
324 data->pop3_flags_directory[PATH_MAX - 1] = '\0';
325
326 r = generic_cache_create_dir(data->pop3_flags_directory);
327 if (r != MAIL_NO_ERROR)
328 return r;
329
330 return MAIL_NO_ERROR;
331
332 default:
333 return mailsession_parameters(data->pop3_ancestor, id, value);
334 }
335}
336
337static int pop3driver_cached_connect_stream(mailsession * session,
338 mailstream * s)
339{
340 int r;
341
342 r = mailsession_connect_stream(get_ancestor(session), s);
343 if (r != MAIL_NO_ERROR)
344 return r;
345
346 return MAIL_NO_ERROR;
347}
348
349static int pop3driver_cached_starttls(mailsession * session)
350{
351 return mailsession_starttls(get_ancestor(session));
352}
353
354
355static int pop3driver_cached_login(mailsession * session,
356 char * userid, char * password)
357{
358 return mailsession_login(get_ancestor(session), userid, password);
359}
360
361static int pop3driver_cached_logout(mailsession * session)
362{
363 struct pop3_cached_session_state_data * cached_data;
364
365 cached_data = get_cached_data(session);
366
367 pop3_flags_store_process(cached_data->pop3_flags_directory,
368 cached_data->pop3_flags_store);
369
370 return mailsession_logout(get_ancestor(session));
371}
372
373static int pop3driver_cached_noop(mailsession * session)
374{
375 return mailsession_noop(get_ancestor(session));
376}
377
378static int pop3driver_cached_expunge_folder(mailsession * session)
379{
380 int res;
381 struct pop3_cached_session_state_data * cached_data;
382 char filename_flags[PATH_MAX];
383 struct mail_cache_db * cache_db_flags;
384 MMAPString * mmapstr;
385 unsigned int i;
386 int r;
387 carray * msg_tab;
388 mailpop3 * pop3;
389
390 pop3 = get_pop3_session(session);
391
392 cached_data = get_cached_data(session);
393
394 pop3_flags_store_process(cached_data->pop3_flags_directory,
395 cached_data->pop3_flags_store);
396
397 snprintf(filename_flags, PATH_MAX, "%s/%s",
398 cached_data->pop3_flags_directory, FLAGS_NAME);
399
400 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
401 if (r < 0) {
402 res = MAIL_ERROR_MEMORY;
403 goto err;
404 }
405
406 mmapstr = mmap_string_new("");
407 if (mmapstr == NULL) {
408 res = MAIL_ERROR_MEMORY;
409 goto close_db_flags;
410 }
411
412 mailpop3_list(pop3, &msg_tab);
413
414 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
415 struct mailpop3_msg_info * pop3_info;
416 struct mail_flags * flags;
417
418 pop3_info = carray_get(msg_tab, i);
419 if (pop3_info == NULL)
420 continue;
421
422 if (pop3_info->msg_deleted)
423 continue;
424
425 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
426 session, pop3_info->msg_index, &flags);
427 if (r != MAIL_NO_ERROR)
428 continue;
429
430 if (flags->fl_flags & MAIL_FLAG_DELETED) {
431 r = mailpop3_dele(pop3, pop3_info->msg_index);
432 }
433
434 mail_flags_free(flags);
435 }
436
437 mmap_string_free(mmapstr);
438 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
439
440 return MAIL_NO_ERROR;
441
442 close_db_flags:
443 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
444 err:
445 return res;
446}
447
448static int pop3driver_cached_status_folder(mailsession * session,
449 char * mb, uint32_t * result_messages, uint32_t * result_recent,
450 uint32_t * result_unseen)
451{
452 int res;
453 struct pop3_cached_session_state_data * cached_data;
454 char filename_flags[PATH_MAX];
455 struct mail_cache_db * cache_db_flags;
456 MMAPString * mmapstr;
457 unsigned int i;
458 int r;
459 carray * msg_tab;
460 mailpop3 * pop3;
461 uint32_t recent;
462 uint32_t unseen;
463
464 recent = 0;
465 unseen = 0;
466
467 pop3 = get_pop3_session(session);
468
469 cached_data = get_cached_data(session);
470
471 pop3_flags_store_process(cached_data->pop3_flags_directory,
472 cached_data->pop3_flags_store);
473
474 snprintf(filename_flags, PATH_MAX, "%s/%s",
475 cached_data->pop3_flags_directory, FLAGS_NAME);
476
477 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
478 if (r < 0) {
479 res = MAIL_ERROR_MEMORY;
480 goto err;
481 }
482
483 mmapstr = mmap_string_new("");
484 if (mmapstr == NULL) {
485 res = MAIL_ERROR_MEMORY;
486 goto close_db_flags;
487 }
488
489 mailpop3_list(pop3, &msg_tab);
490
491 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
492 struct mailpop3_msg_info * pop3_info;
493 struct mail_flags * flags;
494
495 pop3_info = carray_get(msg_tab, i);
496 if (pop3_info == NULL)
497 continue;
498
499 if (pop3_info->msg_deleted)
500 continue;
501
502 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
503 session, pop3_info->msg_index, &flags);
504 if (r != MAIL_NO_ERROR) {
505 recent ++;
506 unseen ++;
507 continue;
508 }
509
510 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
511 recent ++;
512 }
513 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
514 unseen ++;
515 }
516 mail_flags_free(flags);
517
518 }
519
520 mmap_string_free(mmapstr);
521 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
522
523 * result_messages = carray_count(msg_tab) - pop3->pop3_deleted_count;
524 * result_recent = recent;
525 * result_unseen = unseen;
526
527 return MAIL_NO_ERROR;
528
529 close_db_flags:
530 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
531 err:
532 return res;
533}
534
535static int pop3driver_cached_messages_number(mailsession * session,
536 char * mb,
537 uint32_t * result)
538{
539 return mailsession_messages_number(get_ancestor(session), mb, result);
540}
541
542static int pop3driver_cached_recent_number(mailsession * session,
543 char * mb,
544 uint32_t * result)
545{
546 uint32_t messages;
547 uint32_t recent;
548 uint32_t unseen;
549 int r;
550
551 r = pop3driver_cached_status_folder(session, mb,
552 &messages, &recent, &unseen);
553 if (r != MAIL_NO_ERROR)
554 return r;
555
556 * result = recent;
557
558 return MAIL_NO_ERROR;
559}
560
561static int pop3driver_cached_unseen_number(mailsession * session,
562 char * mb,
563 uint32_t * result)
564{
565 uint32_t messages;
566 uint32_t recent;
567 uint32_t unseen;
568 int r;
569
570 r = pop3driver_cached_status_folder(session, mb,
571 &messages, &recent, &unseen);
572 if (r != MAIL_NO_ERROR)
573 return r;
574
575 * result = unseen;
576
577 return MAIL_NO_ERROR;
578}
579
580/* messages operations */
581
582static int pop3driver_cached_remove_message(mailsession * session,
583 uint32_t num)
584{
585 return mailsession_remove_message(get_ancestor(session), num);
586}
587
588static int
589pop3driver_cached_get_messages_list(mailsession * session,
590 struct mailmessage_list ** result)
591{
592 mailpop3 * pop3;
593
594 pop3 = get_pop3_session(session);
595
596 return pop3_get_messages_list(pop3, session,
597 pop3_cached_message_driver, result);
598}
599
600
601static int
602get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
603 mailsession * session, uint32_t num,
604 struct mailimf_fields ** result)
605{
606 int r;
607 char keyname[PATH_MAX];
608 struct mailpop3_msg_info * info;
609 struct mailimf_fields * fields;
610 int res;
611 mailpop3 * pop3;
612
613 pop3 = get_pop3_session(session);
614
615 r = mailpop3_get_msg_info(pop3, num, &info);
616 switch (r) {
617 case MAILPOP3_ERROR_BAD_STATE:
618 return MAIL_ERROR_BAD_STATE;
619 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
620 return MAIL_ERROR_MSG_NOT_FOUND;
621 case MAILPOP3_NO_ERROR:
622 break;
623 default:
624 return MAIL_ERROR_FETCH;
625 }
626
627 snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
628
629 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
630 if (r != MAIL_NO_ERROR) {
631 res = r;
632 goto err;
633 }
634
635 * result = fields;
636
637 return MAIL_NO_ERROR;
638
639 err:
640 return res;
641}
642
643static int
644write_cached_envelope(struct mail_cache_db * cache_db,
645 MMAPString * mmapstr,
646 mailsession * session, uint32_t num,
647 struct mailimf_fields * fields)
648{
649 int r;
650 char keyname[PATH_MAX];
651 int res;
652 struct mailpop3_msg_info * info;
653 mailpop3 * pop3;
654
655 pop3 = get_pop3_session(session);
656
657 r = mailpop3_get_msg_info(pop3, num, &info);
658 switch (r) {
659 case MAILPOP3_ERROR_BAD_STATE:
660 return MAIL_ERROR_BAD_STATE;
661 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
662 return MAIL_ERROR_MSG_NOT_FOUND;
663 case MAILPOP3_NO_ERROR:
664 break;
665 default:
666 return MAIL_ERROR_FETCH;
667 }
668
669 snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
670
671 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
672 if (r != MAIL_NO_ERROR) {
673 res = r;
674 goto err;
675 }
676
677 return MAIL_NO_ERROR;
678
679 err:
680 return res;
681}
682
683static void get_uid_from_filename(char * filename)
684{
685 char * p;
686
687 p = strstr(filename, "-header");
688 if (p != NULL)
689 * p = 0;
690}
691
692static int
693pop3driver_cached_get_envelopes_list(mailsession * session,
694 struct mailmessage_list * env_list)
695{
696 int r;
697 unsigned int i;
698 struct pop3_cached_session_state_data * cached_data;
699 char filename_env[PATH_MAX];
700 char filename_flags[PATH_MAX];
701 struct mail_cache_db * cache_db_env;
702 struct mail_cache_db * cache_db_flags;
703 MMAPString * mmapstr;
704 int res;
705
706 cached_data = get_cached_data(session);
707
708 pop3_flags_store_process(cached_data->pop3_flags_directory,
709 cached_data->pop3_flags_store);
710
711 snprintf(filename_env, PATH_MAX, "%s/%s",
712 cached_data->pop3_cache_directory, ENV_NAME);
713
714 mmapstr = mmap_string_new("");
715 if (mmapstr == NULL) {
716 res = MAIL_ERROR_MEMORY;
717 goto err;
718 }
719
720 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
721 if (r < 0) {
722 res = MAIL_ERROR_MEMORY;
723 goto free_mmapstr;
724 }
725
726 snprintf(filename_flags, PATH_MAX, "%s/%s",
727 cached_data->pop3_flags_directory, FLAGS_NAME);
728
729 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
730 if (r < 0) {
731 res = MAIL_ERROR_MEMORY;
732 goto close_db_env;
733 }
734
735 /* fill with cached */
736
737 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
738 mailmessage * msg;
739 struct mailimf_fields * fields;
740 struct mail_flags * flags;
741
742 msg = carray_get(env_list->msg_tab, i);
743
744 if (msg->msg_fields == NULL) {
745 r = get_cached_envelope(cache_db_env, mmapstr,
746 session, msg->msg_index, &fields);
747 if (r == MAIL_NO_ERROR) {
748 msg->msg_cached = TRUE;
749 msg->msg_fields = fields;
750 }
751 }
752
753 if (msg->msg_flags == NULL) {
754 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
755 session, msg->msg_index, &flags);
756 if (r == MAIL_NO_ERROR) {
757 msg->msg_flags = flags;
758 }
759 }
760 }
761
762 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
763 mail_cache_db_close_unlock(filename_env, cache_db_env);
764
765 r = maildriver_generic_get_envelopes_list(session, env_list);
766
767 if (r != MAIL_NO_ERROR) {
768 res = r;
769 goto free_mmapstr;
770 }
771
772 /* add flags */
773
774 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
775 mailmessage * msg;
776
777 msg = carray_get(env_list->msg_tab, i);
778
779 if (msg->msg_flags == NULL)
780 msg->msg_flags = mail_flags_new_empty();
781 }
782
783 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
784 if (r < 0) {
785 res = MAIL_ERROR_MEMORY;
786 goto free_mmapstr;
787 }
788
789 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
790 if (r < 0) {
791 res = MAIL_ERROR_MEMORY;
792 goto close_db_env;
793 }
794
795 /* must write cache */
796
797 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
798 mailmessage * msg;
799
800 msg = carray_get(env_list->msg_tab, i);
801
802 if (msg->msg_fields != NULL) {
803 if (!msg->msg_cached) {
804 r = write_cached_envelope(cache_db_env, mmapstr,
805 session, msg->msg_index, msg->msg_fields);
806 }
807 }
808
809 if (msg->msg_flags != NULL) {
810 r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
811 msg->msg_uid, msg->msg_flags);
812 }
813 }
814
815 /* flush cache */
816
817 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
818
819 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
820 mail_cache_db_close_unlock(filename_env, cache_db_env);
821 mmap_string_free(mmapstr);
822
823 /* remove cache files */
824
825 maildriver_message_cache_clean_up(cached_data->pop3_cache_directory,
826 env_list, get_uid_from_filename);
827
828 return MAIL_NO_ERROR;
829
830 close_db_env:
831 mail_cache_db_close_unlock(filename_env, cache_db_env);
832 free_mmapstr:
833 mmap_string_free(mmapstr);
834 err:
835 return res;
836}
837
838static int pop3driver_cached_get_message(mailsession * session,
839 uint32_t num, mailmessage ** result)
840{
841 mailmessage * msg_info;
842 int r;
843
844 msg_info = mailmessage_new();
845 if (msg_info == NULL)
846 return MAIL_ERROR_MEMORY;
847
848 r = mailmessage_init(msg_info, session, pop3_cached_message_driver, num, 0);
849 if (r != MAIL_NO_ERROR) {
850 mailmessage_free(msg_info);
851 return r;
852 }
853
854 * result = msg_info;
855
856 return MAIL_NO_ERROR;
857}