summaryrefslogtreecommitdiffabout
path: root/libetpan/src/driver/implementation/db
Unidiff
Diffstat (limited to 'libetpan/src/driver/implementation/db') (more/less context) (show whitespace changes)
-rw-r--r--libetpan/src/driver/implementation/db/dbdriver.c1134
-rw-r--r--libetpan/src/driver/implementation/db/dbdriver.h53
-rw-r--r--libetpan/src/driver/implementation/db/dbdriver_message.c308
-rw-r--r--libetpan/src/driver/implementation/db/dbdriver_message.h52
-rw-r--r--libetpan/src/driver/implementation/db/dbdriver_types.h71
-rw-r--r--libetpan/src/driver/implementation/db/dbstorage.c144
-rw-r--r--libetpan/src/driver/implementation/db/dbstorage.h61
7 files changed, 1823 insertions, 0 deletions
diff --git a/libetpan/src/driver/implementation/db/dbdriver.c b/libetpan/src/driver/implementation/db/dbdriver.c
new file mode 100644
index 0000000..e374e64
--- a/dev/null
+++ b/libetpan/src/driver/implementation/db/dbdriver.c
@@ -0,0 +1,1134 @@
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 "dbdriver.h"
37#include "imfcache.h"
38#include "generic_cache.h"
39#include "libetpan-config.h"
40#include "dbdriver_message.h"
41#include "mail_cache_db.h"
42#include <string.h>
43#include <stdlib.h>
44#include "mailmessage.h"
45
46static int initialize(mailsession * session);
47
48static void uninitialize(mailsession * session);
49
50static int connect_path(mailsession * session, char * path);
51
52static int logout(mailsession * session);
53
54static int expunge_folder(mailsession * session);
55
56static int status_folder(mailsession * session, char * mb,
57 uint32_t * result_messages, uint32_t * result_recent,
58 uint32_t * result_unseen);
59
60static int recent_number(mailsession * session, char * mb,
61 uint32_t * result);
62
63static int unseen_number(mailsession * session, char * mb,
64 uint32_t * result);
65
66static int messages_number(mailsession * session, char * mb,
67 uint32_t * result);
68
69static int append_message(mailsession * session,
70 char * message, size_t size);
71
72static int append_message_flags(mailsession * session,
73 char * message, size_t size, struct mail_flags * flags);
74
75static int get_messages_list(mailsession * session,
76 struct mailmessage_list ** result);
77
78static int get_envelopes_list(mailsession * session,
79 struct mailmessage_list * env_list);
80
81static int check_folder(mailsession * session);
82
83static int get_message(mailsession * session,
84 uint32_t num, mailmessage ** result);
85
86static int get_message_by_uid(mailsession * session,
87 const char * uid, mailmessage ** result);
88
89static mailsession_driver local_db_session_driver = {
90 .sess_name = "db",
91
92 .sess_initialize = initialize,
93 .sess_uninitialize = uninitialize,
94
95 .sess_parameters = NULL,
96
97 .sess_connect_stream = NULL,
98 .sess_connect_path = connect_path,
99 .sess_starttls = NULL,
100 .sess_login = NULL,
101 .sess_logout = logout,
102 .sess_noop = NULL,
103
104 .sess_build_folder_name = NULL,
105 .sess_create_folder = NULL,
106 .sess_delete_folder = NULL,
107 .sess_rename_folder = NULL,
108 .sess_check_folder = check_folder,
109 .sess_examine_folder = NULL,
110 .sess_select_folder = NULL,
111 .sess_expunge_folder = expunge_folder,
112 .sess_status_folder = status_folder,
113 .sess_messages_number = messages_number,
114 .sess_recent_number = recent_number,
115 .sess_unseen_number = unseen_number,
116 .sess_list_folders = NULL,
117 .sess_lsub_folders = NULL,
118 .sess_subscribe_folder = NULL,
119 .sess_unsubscribe_folder = NULL,
120
121 .sess_append_message = append_message,
122 .sess_append_message_flags = append_message_flags,
123 .sess_copy_message = NULL,
124 .sess_move_message = NULL,
125
126 .sess_get_messages_list = get_messages_list,
127 .sess_get_envelopes_list = get_envelopes_list,
128 .sess_remove_message = NULL,
129
130 .sess_get_message = get_message,
131 .sess_get_message_by_uid = get_message_by_uid,
132};
133
134mailsession_driver * db_session_driver = &local_db_session_driver;
135
136static inline struct db_session_state_data * get_data(mailsession * session)
137{
138 return session->sess_data;
139}
140
141static int flags_store_process(mailsession * session)
142{
143 unsigned int i;
144 MMAPString * mmapstr;
145 int r;
146 int res;
147 struct mail_cache_db * maildb;
148 struct db_session_state_data * data;
149 struct mail_flags_store * flags_store;
150
151 data = get_data(session);
152
153 flags_store = data->db_flags_store;
154
155 if (carray_count(flags_store->fls_tab) == 0)
156 return MAIL_NO_ERROR;
157
158 mmapstr = mmap_string_new("");
159 if (mmapstr == NULL) {
160 res = MAIL_ERROR_MEMORY;
161 goto err;
162 }
163
164 r = mail_cache_db_open_lock(data->db_filename, &maildb);
165 if (r < 0) {
166 res = MAIL_ERROR_FILE;
167 goto free_mmapstr;
168 }
169
170 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
171 mailmessage * msg;
172 char key[PATH_MAX];
173
174 msg = carray_get(flags_store->fls_tab, i);
175
176 snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg->msg_index);
177
178 r = generic_cache_flags_write(maildb, mmapstr,
179 key, msg->msg_flags);
180 }
181
182 mail_flags_store_clear(flags_store);
183
184 mail_cache_db_close_unlock(data->db_filename, maildb);
185 mmap_string_free(mmapstr);
186
187 return MAIL_NO_ERROR;
188
189 free_mmapstr:
190 mmap_string_free(mmapstr);
191 err:
192 return res;
193}
194
195static int db_get_next_validity(struct mail_cache_db * maildb,
196 uint32_t * p_validity)
197{
198 int r;
199 char key_value[PATH_MAX];
200 uint32_t validity;
201 void * serialized;
202 size_t serialized_len;
203 int res;
204 MMAPString * mmapstr;
205 size_t cur_token;
206
207 mmapstr = mmap_string_new_len(serialized, serialized_len);
208 if (mmapstr == NULL) {
209 res = MAIL_ERROR_MEMORY;
210 goto err;
211 }
212
213 snprintf(key_value, sizeof(key_value), "next-validity");
214
215 r = mail_cache_db_get(maildb, key_value, strlen(key_value),
216 &serialized, &serialized_len);
217
218 if (r >= 0) {
219 size_t cur_token;
220
221 cur_token = 0;
222 r = mailimf_cache_int_read(mmapstr, &cur_token, &validity);
223 if (r < 0)
224 validity = 0;
225 }
226 else {
227 validity = 0;
228 }
229
230 mmap_string_set_size(mmapstr, 0);
231 cur_token = 0;
232 r = mailimf_cache_int_write(mmapstr, &cur_token, validity + 1);
233 if (r < 0) {
234 res = MAIL_ERROR_MEMORY;
235 goto free_mmapstr;
236 }
237
238 r = mail_cache_db_put(maildb, key_value, strlen(key_value),
239 mmapstr->str, mmapstr->len);
240 if (r < 0) {
241 res = MAIL_ERROR_FILE;
242 goto free_mmapstr;
243 }
244
245 mmap_string_free(mmapstr);
246
247 * p_validity = validity;
248
249 return MAIL_NO_ERROR;
250
251 free_mmapstr:
252 mmap_string_free(mmapstr);
253 err:
254 return res;
255}
256
257static int db_get_next_msg_number(struct mail_cache_db * maildb,
258 uint32_t * p_num)
259{
260 int r;
261 char key_value[PATH_MAX];
262 uint32_t num;
263 void * serialized;
264 size_t serialized_len;
265 int res;
266 MMAPString * mmapstr;
267 size_t cur_token;
268
269 mmapstr = mmap_string_new("");
270 if (mmapstr == NULL) {
271 res = MAIL_ERROR_MEMORY;
272 goto err;
273 }
274
275 snprintf(key_value, sizeof(key_value), "next-msg");
276
277 r = mail_cache_db_get(maildb, key_value, strlen(key_value),
278 &serialized, &serialized_len);
279
280 if (r >= 0) {
281 size_t cur_token;
282
283 if (mmap_string_append_len(mmapstr, serialized, serialized_len) == NULL) {
284 res = MAIL_ERROR_MEMORY;
285 goto err;
286 }
287
288 cur_token = 0;
289 r = mailimf_cache_int_read(mmapstr, &cur_token, &num);
290 if (r < 0)
291 num = 1;
292 }
293 else {
294 num = 1;
295 }
296
297 mmap_string_set_size(mmapstr, 0);
298 cur_token = 0;
299 r = mailimf_cache_int_write(mmapstr, &cur_token, num + 1);
300 if (r < 0) {
301 res = MAIL_ERROR_MEMORY;
302 goto free_mmapstr;
303 }
304
305 r = mail_cache_db_put(maildb, key_value, strlen(key_value),
306 mmapstr->str, mmapstr->len);
307 if (r < 0) {
308 res = MAIL_ERROR_FILE;
309 goto free_mmapstr;
310 }
311
312 mmap_string_free(mmapstr);
313
314 * p_num = num;
315
316 return MAIL_NO_ERROR;
317
318 free_mmapstr:
319 mmap_string_free(mmapstr);
320 err:
321 return res;
322}
323
324static int db_set_message_list(struct mail_cache_db * maildb,
325 carray * msglist)
326{
327 MMAPString * mmapstr;
328 char key_value[PATH_MAX];
329 int r;
330 unsigned int i;
331 size_t cur_token;
332 int res;
333
334 mmapstr = mmap_string_new("");
335 if (mmapstr == NULL) {
336 res = MAIL_ERROR_MEMORY;
337 goto err;
338 }
339
340 cur_token = 0;
341 for(i = 0 ; i < carray_count(msglist) ; i ++) {
342 uint32_t * msg;
343
344 msg = carray_get(msglist, i);
345 r = mailimf_cache_int_write(mmapstr, &cur_token, * msg);
346 if (r != MAIL_NO_ERROR) {
347 res = r;
348 goto free_mmapstr;
349 }
350 }
351
352 snprintf(key_value, sizeof(key_value), "message-list");
353 r = mail_cache_db_put(maildb, key_value, strlen(key_value),
354 mmapstr->str, mmapstr->len);
355 if (r < 0) {
356 res = MAIL_ERROR_FILE;
357 goto err;
358 }
359
360 mmap_string_free(mmapstr);
361
362 return MAIL_NO_ERROR;
363
364 free_mmapstr:
365 mmap_string_free(mmapstr);
366 err:
367 return res;
368}
369
370static int db_get_message_list(struct mail_cache_db * maildb,
371 carray ** p_msglist)
372{
373 carray * msglist;
374 void * serialized;
375 size_t serialized_len;
376 int r;
377 char key_value[PATH_MAX];
378 int res;
379 unsigned int i;
380
381 msglist = carray_new(16);
382 if (msglist == NULL) {
383 res = MAIL_ERROR_MEMORY;
384 goto err;
385 }
386
387 snprintf(key_value, sizeof(key_value), "message-list");
388 r = mail_cache_db_get(maildb, key_value, strlen(key_value),
389 &serialized, &serialized_len);
390 if (r >= 0) {
391 MMAPString * mmapstr;
392 size_t cur_token;
393
394 /* collect message list */
395
396 mmapstr = mmap_string_new_len(serialized, serialized_len);
397 if (mmapstr == NULL) {
398 res = MAIL_ERROR_MEMORY;
399 goto free_msglist;
400 }
401
402 cur_token = 0;
403 do {
404 uint32_t num;
405 uint32_t * msg;
406
407 r = mailimf_cache_int_read(mmapstr, &cur_token, &num);
408 if (r != MAIL_NO_ERROR)
409 break;
410
411 msg = malloc(sizeof(* msg));
412 if (msg == NULL) {
413 res = MAIL_ERROR_MEMORY;
414 mmap_string_free(mmapstr);
415 goto free_msglist;
416 }
417 * msg = num;
418
419 r = carray_add(msglist, msg, NULL);
420 if (r < 0) {
421 res = MAIL_ERROR_MEMORY;
422 free(msg);
423 mmap_string_free(mmapstr);
424 goto free_msglist;
425 }
426 } while (1);
427
428 mmap_string_free(mmapstr);
429 }
430
431 * p_msglist = msglist;
432
433 return MAIL_NO_ERROR;
434
435 free_msglist:
436 for(i = 0 ; i < carray_count(msglist) ; i ++) {
437 uint32_t * msg;
438
439 msg = carray_get(msglist, i);
440 free(msg);
441 }
442 carray_free(msglist);
443 err:
444 return res;
445}
446
447static int initialize(mailsession * session)
448{
449 struct db_session_state_data * data;
450
451 data = malloc(sizeof(* data));
452 if (data == NULL)
453 goto err;
454
455 data->db_filename[0] = '\0';
456
457 data->db_flags_store = mail_flags_store_new();
458 if (data->db_flags_store == NULL)
459 goto free;
460
461 session->sess_data = data;
462
463 return MAIL_NO_ERROR;
464
465 free:
466 free(data);
467 err:
468 return MAIL_ERROR_MEMORY;
469}
470
471static void uninitialize(mailsession * session)
472{
473 struct db_session_state_data * data;
474
475 data = get_data(session);
476
477 flags_store_process(session);
478
479 mail_flags_store_free(data->db_flags_store);
480
481 free(data);
482
483 session->sess_data = NULL;
484}
485
486static int connect_path(mailsession * session, char * path)
487{
488 struct db_session_state_data * data;
489
490 data = get_data(session);
491
492 strncpy(data->db_filename, path, sizeof(data->db_filename));
493
494 return MAIL_NO_ERROR;
495}
496
497static int logout(mailsession * session)
498{
499 return MAIL_NO_ERROR;
500}
501
502static int expunge_folder(mailsession * session)
503{
504 int r;
505 char key_value[PATH_MAX];
506 struct mail_cache_db * maildb;
507 carray * msglist;
508 unsigned int i;
509 struct db_session_state_data * data;
510 int res;
511 chash * msg_table;
512 MMAPString * mmapstr;
513
514 data = get_data(session);
515
516 flags_store_process(session);
517
518 r = mail_cache_db_open_lock(data->db_filename, &maildb);
519 if (r < 0) {
520 res = MAIL_ERROR_FILE;
521 goto err;
522 }
523
524 r = db_get_message_list(maildb, &msglist);
525 if (r != MAIL_NO_ERROR) {
526 res = r;
527 goto close_db;
528 }
529
530 msg_table = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
531 if (msg_table == NULL) {
532 res = MAIL_ERROR_MEMORY;
533 goto free_msglist;
534 }
535
536 mmapstr = mmap_string_new("");
537 if (mmapstr == NULL) {
538 res = MAIL_ERROR_MEMORY;
539 goto free_msgtable;
540 }
541
542 i = 0;
543 while (i < carray_count(msglist)) {
544 uint32_t num;
545 uint32_t * msg;
546 chashdatum key;
547 chashdatum value;
548 struct mail_flags * flags;
549 int deleted;
550
551 msg = carray_get(msglist, i);
552 num = * msg;
553
554 deleted = 0;
555 snprintf(key_value, sizeof(key_value), "%lu-flags",
556 (unsigned long) num);
557 r = generic_cache_flags_read(maildb, mmapstr, key_value, &flags);
558 if (r == MAIL_NO_ERROR) {
559 if ((flags->fl_flags & MAIL_FLAG_DELETED) != 0)
560 deleted = 1;
561 }
562
563 if (!deleted) {
564 snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num);
565 key.data = key_value;
566 key.len = strlen(key_value);
567 chash_set(msg_table, &key, &value, NULL);
568
569 snprintf(key_value, sizeof(key_value), "%lu-envelope",
570 (unsigned long) num);
571 key.data = key_value;
572 key.len = strlen(key_value);
573 chash_set(msg_table, &key, &value, NULL);
574
575 snprintf(key_value, sizeof(key_value), "%lu-flags",
576 (unsigned long) num);
577 key.data = key_value;
578 key.len = strlen(key_value);
579 chash_set(msg_table, &key, &value, NULL);
580
581 i ++;
582 }
583 else {
584 free(msg);
585 carray_delete(msglist, i);
586 }
587 }
588
589 mmap_string_free(mmapstr);
590
591 r = mail_cache_db_clean_up(maildb, msg_table);
592
593 chash_free(msg_table);
594
595 r = db_set_message_list(maildb, msglist);
596
597 for(i = 0 ; i < carray_count(msglist) ; i ++) {
598 uint32_t * msg;
599
600 msg = carray_get(msglist, i);
601 free(msg);
602 }
603 carray_free(msglist);
604
605 mail_cache_db_close_unlock(data->db_filename, maildb);
606
607 return MAIL_NO_ERROR;
608
609 free_msgtable:
610 chash_free(msg_table);
611 free_msglist:
612 for(i = 0 ; i < carray_count(msglist) ; i ++) {
613 uint32_t * msg;
614
615 msg = carray_get(msglist, i);
616 free(msg);
617 }
618 close_db:
619 mail_cache_db_close_unlock(data->db_filename, maildb);
620 err:
621 return res;
622}
623
624static int status_folder(mailsession * session, char * mb,
625 uint32_t * result_messages, uint32_t * result_recent,
626 uint32_t * result_unseen)
627{
628 struct mail_cache_db * maildb;
629 char key_value[PATH_MAX];
630 MMAPString * mmapstr;
631 uint32_t messages;
632 uint32_t recent;
633 uint32_t unseen;
634 struct db_session_state_data * data;
635 int r;
636 int res;
637 carray * msglist;
638 unsigned int i;
639
640 data = get_data(session);
641
642 flags_store_process(session);
643
644 r = mail_cache_db_open_lock(data->db_filename, &maildb);
645 if (r < 0) {
646 res = MAIL_ERROR_FILE;
647 goto err;
648 }
649
650 r = db_get_message_list(maildb, &msglist);
651 if (r != MAIL_NO_ERROR) {
652 res = r;
653 goto close_db;
654 }
655
656 mmapstr = mmap_string_new("");
657 if (mmapstr == NULL) {
658 res = MAIL_ERROR_MEMORY;
659 goto free_list;
660 }
661
662 messages = 0;
663 recent = 0;
664 unseen = 0;
665 for(i = 0 ; i < carray_count(msglist) ; i ++) {
666 uint32_t num;
667 uint32_t * msg;
668 int r;
669 struct mail_flags * flags;
670
671 msg = carray_get(msglist, i);
672 num = * msg;
673 free(msg);
674 carray_set(msglist, i, NULL);
675
676 messages ++;
677
678 snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num);
679
680 r = generic_cache_flags_read(maildb, mmapstr, key_value, &flags);
681 if (r == MAIL_NO_ERROR) {
682 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
683 recent ++;
684 }
685 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
686 unseen ++;
687 }
688 mail_flags_free(flags);
689 }
690 }
691
692 mmap_string_free(mmapstr);
693
694 carray_free(msglist);
695
696 mail_cache_db_close_unlock(data->db_filename, maildb);
697
698 * result_messages = messages;
699 * result_unseen = unseen;
700 * result_recent = recent;
701
702 return MAIL_NO_ERROR;
703
704 free_list:
705 for(i = 0 ; i < carray_count(msglist) ; i ++) {
706 uint32_t * msg;
707
708 msg = carray_get(msglist, i);
709 if (msg != NULL)
710 free(msg);
711 }
712 carray_free(msglist);
713 close_db:
714 mail_cache_db_close_unlock(data->db_filename, maildb);
715 err:
716 return res;
717}
718
719static int recent_number(mailsession * session, char * mb,
720 uint32_t * result)
721{
722 uint32_t dummy_messages;
723 uint32_t dummy_unseen;
724
725 return status_folder(session, mb,
726 &dummy_messages, result, &dummy_unseen);
727}
728
729static int unseen_number(mailsession * session, char * mb,
730 uint32_t * result)
731{
732 uint32_t dummy_messages;
733 uint32_t dummy_recent;
734
735 return status_folder(session, mb,
736 &dummy_messages, &dummy_recent, result);
737}
738
739static int messages_number(mailsession * session, char * mb,
740 uint32_t * result)
741{
742 uint32_t dummy_unseen;
743 uint32_t dummy_recent;
744
745 return status_folder(session, mb,
746 result, &dummy_recent, &dummy_unseen);
747}
748
749static int append_message(mailsession * session,
750 char * message, size_t size)
751{
752 return append_message_flags(session, message, size, NULL);
753}
754
755static int append_message_flags(mailsession * session,
756 char * message, size_t size, struct mail_flags * flags)
757{
758 carray * msglist;
759 unsigned int i;
760 uint32_t * msg;
761 uint32_t num;
762 char key_value[PATH_MAX];
763 MMAPString * mmapstr;
764 struct mail_cache_db * maildb;
765 struct db_session_state_data * data;
766 size_t cur_token;
767 struct mailimf_fields * fields;
768 int r;
769 int res;
770
771 data = get_data(session);
772
773 r = mail_cache_db_open_lock(data->db_filename, &maildb);
774 if (r < 0) {
775 res = MAIL_ERROR_FILE;
776 goto err;
777 }
778
779 r = db_get_next_msg_number(maildb, &num);
780 if (r != MAIL_NO_ERROR) {
781 res = r;
782 goto err;
783 }
784
785 r = db_get_message_list(maildb, &msglist);
786 if (r != MAIL_NO_ERROR) {
787 res = r;
788 goto close_db;
789 }
790
791 msg = malloc(sizeof(* msg));
792 if (msg == NULL) {
793 res = MAIL_ERROR_MEMORY;
794 goto free_msglist;
795 }
796
797 * msg = num;
798
799 r = carray_add(msglist, msg, NULL);
800 if (r < 0) {
801 res = MAIL_ERROR_MEMORY;
802 free(msg);
803 goto free_msglist;
804 }
805
806 r = db_set_message_list(maildb, msglist);
807 if (r != MAIL_NO_ERROR) {
808 res = r;
809 goto free_msglist;
810 }
811
812 /* free msglist */
813
814 for(i = 0 ; i < carray_count(msglist) ; i ++) {
815 uint32_t * msg;
816
817 msg = carray_get(msglist, i);
818 free(msg);
819 }
820 carray_free(msglist);
821
822 snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num);
823
824 r = mail_cache_db_put(maildb, key_value, strlen(key_value),
825 message, size);
826 if (r < 0) {
827 res = MAIL_ERROR_FILE;
828 goto close_db;
829 }
830
831 /* write envelope */
832
833 cur_token = 0;
834 r = mailimf_envelope_fields_parse(message, size, &cur_token, &fields);
835 if (r != MAILIMF_NO_ERROR) {
836 res = MAIL_ERROR_PARSE;
837 goto close_db;
838 }
839
840 mmapstr = mmap_string_new("");
841 if (mmapstr == NULL) {
842 res = MAIL_ERROR_MEMORY;
843 goto close_db;
844 }
845
846 cur_token = 0;
847 r = mailimf_cache_fields_write(mmapstr, &cur_token, fields);
848 if (r != MAIL_NO_ERROR) {
849 res = r;
850 mmap_string_free(mmapstr);
851 goto close_db;
852 }
853
854 snprintf(key_value, sizeof(key_value), "%lu-envelope", (unsigned long) num);
855
856 r = mail_cache_db_put(maildb, key_value, strlen(key_value),
857 mmapstr->str, mmapstr->len);
858
859 mmap_string_free(mmapstr);
860
861 mailimf_fields_free(fields);
862
863 /* write flags */
864
865 if (flags != NULL) {
866 snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num);
867
868 mmapstr = mmap_string_new("");
869 if (mmapstr == NULL) {
870 res = MAIL_ERROR_MEMORY;
871 goto close_db;
872 }
873
874 r = generic_cache_flags_write(maildb, mmapstr,
875 key_value, flags);
876
877 mmap_string_free(mmapstr);
878
879 if (r != MAIL_NO_ERROR) {
880 res = MAIL_ERROR_FILE;
881 goto close_db;
882 }
883 }
884
885 mail_cache_db_close_unlock(data->db_filename, maildb);
886
887 return MAIL_NO_ERROR;
888
889 free_msglist:
890 for(i = 0 ; i < carray_count(msglist) ; i ++) {
891 uint32_t * msg;
892
893 msg = carray_get(msglist, i);
894 free(msg);
895 }
896 carray_free(msglist);
897 close_db:
898 mail_cache_db_close_unlock(data->db_filename, maildb);
899 err:
900 return res;
901}
902
903static int get_messages_list(mailsession * session,
904 struct mailmessage_list ** result)
905{
906 int r;
907 char key[PATH_MAX];
908 struct mail_cache_db * maildb;
909 struct db_session_state_data * data;
910 int res;
911 carray * msglist;
912 unsigned int i;
913 carray * msgtab;
914 struct mailmessage_list * driver_msglist;
915
916 data = get_data(session);
917
918 r = mail_cache_db_open_lock(data->db_filename, &maildb);
919 if (r < 0) {
920 res = MAIL_ERROR_FILE;
921 goto err;
922 }
923
924 r = db_get_message_list(maildb, &msglist);
925 if (r != MAIL_NO_ERROR) {
926 res = r;
927 goto close_db;
928 }
929
930 msgtab = carray_new(16);
931 if (msgtab == NULL) {
932 res = MAIL_ERROR_MEMORY;
933 goto close_db;
934 }
935
936 for(i = 0 ; i < carray_count(msglist) ; i ++) {
937 uint32_t msg_num;
938 uint32_t * pmsg_num;
939 mailmessage * msg;
940 size_t size;
941
942 pmsg_num = carray_get(msglist, i);
943 msg_num = * pmsg_num;
944 free(pmsg_num);
945 carray_set(msglist, i, NULL);
946
947 snprintf(key, sizeof(key), "%lu", (unsigned long) msg_num);
948 r = mail_cache_db_get_size(maildb, key, strlen(key), &size);
949 if (r < 0) {
950 continue;
951 }
952
953 msg = mailmessage_new();
954 if (msg == NULL) {
955 res = MAIL_ERROR_MEMORY;
956 goto free_list;
957 }
958
959 r = mailmessage_init(msg, session, db_message_driver,
960 msg_num, size);
961 if (r != MAIL_NO_ERROR) {
962 mailmessage_free(msg);
963 res = r;
964 goto free_list;
965 }
966
967 r = carray_add(msgtab, msg, NULL);
968 if (r < 0) {
969 mailmessage_free(msg);
970 res = MAIL_ERROR_MEMORY;
971 goto free_list;
972 }
973 }
974 carray_free(msglist);
975
976 driver_msglist = mailmessage_list_new(msgtab);
977 if (driver_msglist == NULL) {
978 res = MAIL_ERROR_MEMORY;
979 goto free_list;
980 }
981
982 mail_cache_db_close_unlock(data->db_filename, maildb);
983
984 * result = driver_msglist;
985
986 return MAIL_NO_ERROR;
987
988 free_list:
989 for(i = 0 ; i < carray_count(msgtab) ; i ++) {
990 mailmessage * msg;
991
992 msg = carray_get(msgtab, i);
993 mailmessage_free(msg);
994 }
995 carray_free(msgtab);
996
997 for(i = 0 ; i < carray_count(msglist) ; i ++) {
998 uint32_t * msg;
999
1000 msg = carray_get(msglist, i);
1001 if (msg != NULL)
1002 free(msg);
1003 }
1004 carray_free(msglist);
1005 close_db:
1006 mail_cache_db_close_unlock(data->db_filename, maildb);
1007 err:
1008 return res;
1009}
1010
1011static int get_envelopes_list(mailsession * session,
1012 struct mailmessage_list * env_list)
1013{
1014 unsigned int i;
1015 char key[PATH_MAX];
1016 int r;
1017 struct mail_cache_db * maildb;
1018 int res;
1019 struct db_session_state_data * data;
1020 MMAPString * mmapstr;
1021
1022 data = get_data(session);
1023
1024 flags_store_process(session);
1025
1026 r = mail_cache_db_open_lock(data->db_filename, &maildb);
1027 if (r < 0) {
1028 res = MAIL_ERROR_FILE;
1029 goto err;
1030 }
1031
1032 mmapstr = mmap_string_new("");
1033 if (mmapstr == NULL) {
1034 res = MAIL_ERROR_MEMORY;
1035 goto close_db;
1036 }
1037
1038 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1039 mailmessage * msg;
1040
1041 msg = carray_get(env_list->msg_tab, i);
1042 if (msg->msg_fields == NULL) {
1043 snprintf(key, sizeof(key), "%lu-envelope",
1044 (unsigned long) msg->msg_index);
1045
1046 r = generic_cache_fields_read(maildb, mmapstr,
1047 key, &msg->msg_fields);
1048 }
1049
1050 if (msg->msg_flags == NULL) {
1051 snprintf(key, sizeof(key), "%lu-flags",
1052 (unsigned long) msg->msg_index);
1053
1054 r = generic_cache_flags_read(maildb, mmapstr,
1055 key, &msg->msg_flags);
1056 }
1057 }
1058
1059 mmap_string_free(mmapstr);
1060
1061 mail_cache_db_close_unlock(data->db_filename, maildb);
1062
1063 return MAIL_NO_ERROR;
1064
1065 close_db:
1066 mail_cache_db_close_unlock(data->db_filename, maildb);
1067 err:
1068 return res;
1069}
1070
1071static int check_folder(mailsession * session)
1072{
1073 flags_store_process(session);
1074
1075 return MAIL_NO_ERROR;
1076}
1077
1078static int get_message(mailsession * session,
1079 uint32_t num, mailmessage ** result)
1080{
1081 mailmessage * msg;
1082 int r;
1083 size_t size;
1084 char key[PATH_MAX];
1085 struct db_session_state_data * data;
1086 struct mail_cache_db * maildb;
1087 int res;
1088
1089 data = get_data(session);
1090
1091 r = mail_cache_db_open_lock(data->db_filename, &maildb);
1092 if (r < 0) {
1093 res = MAIL_ERROR_FILE;
1094 goto err;
1095 }
1096
1097 msg = mailmessage_new();
1098 if (msg == NULL) {
1099 res = MAIL_ERROR_MEMORY;
1100 goto close_db;
1101 }
1102
1103 size = 0;
1104 snprintf(key, sizeof(key), "%lu", (unsigned long) num);
1105 r = mail_cache_db_get_size(maildb, key, strlen(key), &size);
1106 /* ignore error */
1107
1108 r = mailmessage_init(msg, session, db_message_driver,
1109 num, size);
1110 if (r != MAIL_NO_ERROR) {
1111 mailmessage_free(msg);
1112 res = r;
1113 goto close_db;
1114 }
1115
1116 mail_cache_db_close_unlock(data->db_filename, maildb);
1117
1118 return MAIL_NO_ERROR;
1119
1120 close_db:
1121 mail_cache_db_close_unlock(data->db_filename, maildb);
1122 err:
1123 return res;
1124}
1125
1126static int get_message_by_uid(mailsession * session,
1127 const char * uid, mailmessage ** result)
1128{
1129 uint32_t msg_num;
1130
1131 msg_num = strtoul(uid, NULL, 10);
1132
1133 return get_message(session, msg_num, result);
1134}
diff --git a/libetpan/src/driver/implementation/db/dbdriver.h b/libetpan/src/driver/implementation/db/dbdriver.h
new file mode 100644
index 0000000..1c2a96d
--- a/dev/null
+++ b/libetpan/src/driver/implementation/db/dbdriver.h
@@ -0,0 +1,53 @@
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#ifndef DBDRIVER_H
37
38#define DBDRIVER_H
39
40#include <libetpan/dbdriver_message.h>
41#include <libetpan/dbdriver_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47extern mailsession_driver * db_session_driver;
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/libetpan/src/driver/implementation/db/dbdriver_message.c b/libetpan/src/driver/implementation/db/dbdriver_message.c
new file mode 100644
index 0000000..70e9dca
--- a/dev/null
+++ b/libetpan/src/driver/implementation/db/dbdriver_message.c
@@ -0,0 +1,308 @@
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 "dbdriver_message.h"
37#include "dbdriver.h"
38#include "mail_cache_db.h"
39
40#include "mailmessage_tools.h"
41#include "generic_cache.h"
42
43#include <unistd.h>
44#include <sys/mman.h>
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <fcntl.h>
48#include <string.h>
49#include <stdlib.h>
50
51static int fetch_envelope(mailmessage * msg_info,
52 struct mailimf_fields ** result);
53
54static int get_flags(mailmessage * msg_info,
55 struct mail_flags ** result);
56
57static int prefetch(mailmessage * msg_info);
58
59static void prefetch_free(struct generic_message_t * msg);
60
61static int initialize(mailmessage * msg_info);
62
63static void check(mailmessage * msg_info);
64
65static mailmessage_driver local_db_message_driver = {
66 .msg_name = "db",
67
68 .msg_initialize = initialize,
69 .msg_uninitialize = mailmessage_generic_uninitialize,
70
71 .msg_flush = mailmessage_generic_flush,
72 .msg_check = check,
73
74 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
75
76 .msg_fetch = mailmessage_generic_fetch,
77 .msg_fetch_header = mailmessage_generic_fetch_header,
78 .msg_fetch_body = mailmessage_generic_fetch_header,
79 .msg_fetch_size = NULL,
80 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
81 .msg_fetch_section = mailmessage_generic_fetch_section,
82 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
83 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
84 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
85 .msg_fetch_envelope = fetch_envelope,
86
87 .msg_get_flags = get_flags,
88};
89
90mailmessage_driver * db_message_driver = &local_db_message_driver;
91
92struct db_msg_data {
93 MMAPString * msg_content;
94};
95
96static inline struct db_session_state_data *
97get_session_data(mailmessage * msg)
98{
99 return msg->msg_session->sess_data;
100}
101
102static int prefetch(mailmessage * msg_info)
103{
104 struct generic_message_t * msg;
105 int res;
106 struct db_msg_data * data;
107 struct db_session_state_data * sess_data;
108 MMAPString * msg_content;
109 struct mail_cache_db * maildb;
110 int r;
111 char key[PATH_MAX];
112 void * msg_data;
113 size_t msg_data_len;
114
115 sess_data = get_session_data(msg_info);
116
117 r = mail_cache_db_open_lock(sess_data->db_filename, &maildb);
118 if (r < 0) {
119 res = MAIL_ERROR_FILE;
120 goto err;
121 }
122
123 snprintf(key, sizeof(key), "%lu", (unsigned long) msg_info->msg_index);
124 r = mail_cache_db_get(maildb, key, strlen(key), &msg_data, &msg_data_len);
125 if (r < 0) {
126 res = MAIL_ERROR_MSG_NOT_FOUND;
127 goto close_db;
128 }
129
130 msg_content = mmap_string_new_len(msg_data, msg_data_len);
131 if (msg_content == NULL) {
132 res = MAIL_ERROR_MEMORY;
133 goto close_db;
134 }
135
136 data = malloc(sizeof(* data));
137 if (data == NULL) {
138 res = MAIL_ERROR_MEMORY;
139 goto free_mmapstr;
140 }
141
142 data->msg_content = msg_content;
143
144 msg = msg_info->msg_data;
145
146 msg->msg_data = data;
147 msg->msg_message = msg_content->str;
148 msg->msg_length = msg_content->len;
149
150 mail_cache_db_close_unlock(sess_data->db_filename, maildb);
151
152 return MAIL_NO_ERROR;
153
154 free_mmapstr:
155 mmap_string_free(msg_content);
156 close_db:
157 mail_cache_db_close_unlock(sess_data->db_filename, maildb);
158 err:
159 return res;
160}
161
162static void prefetch_free(struct generic_message_t * msg)
163{
164 if (msg->msg_message != NULL) {
165 struct db_msg_data * data;
166
167 data = msg->msg_data;
168 mmap_string_free(data->msg_content);
169 data->msg_content = NULL;
170 free(data);
171 msg->msg_message = NULL;
172 }
173}
174
175static int initialize(mailmessage * msg_info)
176{
177 struct generic_message_t * msg;
178 int r;
179 char key[PATH_MAX];
180
181 snprintf(key, sizeof(key), "%lu", (unsigned long) msg_info->msg_index);
182 msg_info->msg_uid = strdup(key);
183 if (msg_info->msg_uid == NULL)
184 return MAIL_ERROR_MEMORY;
185
186 r = mailmessage_generic_initialize(msg_info);
187 if (r != MAIL_NO_ERROR)
188 return r;
189
190 msg = msg_info->msg_data;
191 msg->msg_prefetch = prefetch;
192 msg->msg_prefetch_free = prefetch_free;
193
194 return MAIL_NO_ERROR;
195}
196
197static void check(mailmessage * msg_info)
198{
199 int r;
200
201 if (msg_info->msg_flags != NULL) {
202 r = mail_flags_store_set(get_session_data(msg_info)->db_flags_store,
203 msg_info);
204 /* ignore errors */
205 }
206}
207
208static int fetch_envelope(mailmessage * msg_info,
209 struct mailimf_fields ** result)
210{
211 char key[PATH_MAX];
212 int r;
213 struct db_session_state_data * sess_data;
214 struct mail_cache_db * maildb;
215 int res;
216 struct mailimf_fields * fields;
217 MMAPString * mmapstr;
218
219 sess_data = get_session_data(msg_info);
220
221 r = mail_cache_db_open_lock(sess_data->db_filename, &maildb);
222 if (r < 0) {
223 res = MAIL_ERROR_FILE;
224 goto err;
225 }
226
227 snprintf(key, sizeof(key), "%lu-envelope",
228 (unsigned long) msg_info->msg_index);
229
230 mmapstr = mmap_string_new("");
231 if (mmapstr == NULL) {
232 res = MAIL_ERROR_MEMORY;
233 goto close_db;
234 }
235
236 r = generic_cache_fields_read(maildb, mmapstr,
237 key, &fields);
238
239 mmap_string_free(mmapstr);
240
241 if (r != MAIL_NO_ERROR) {
242 res = MAIL_ERROR_MSG_NOT_FOUND;
243 goto close_db;
244 }
245
246 mail_cache_db_close_unlock(sess_data->db_filename, maildb);
247
248 * result = fields;
249
250 return MAIL_NO_ERROR;
251
252 close_db:
253 mail_cache_db_close_unlock(sess_data->db_filename, maildb);
254 err:
255 return res;
256}
257
258static int get_flags(mailmessage * msg_info,
259 struct mail_flags ** result)
260{
261 char key[PATH_MAX];
262 int r;
263 struct db_session_state_data * sess_data;
264 struct mail_cache_db * maildb;
265 int res;
266 MMAPString * mmapstr;
267
268 sess_data = get_session_data(msg_info);
269
270 r = mail_cache_db_open_lock(sess_data->db_filename, &maildb);
271 if (r < 0) {
272 res = MAIL_ERROR_FILE;
273 goto err;
274 }
275
276 snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg_info->msg_index);
277
278 mmapstr = mmap_string_new("");
279 if (mmapstr == NULL) {
280 res = MAIL_ERROR_MEMORY;
281 goto close_db;
282 }
283
284 r = generic_cache_flags_read(maildb, mmapstr,
285 key, &msg_info->msg_flags);
286
287 mmap_string_free(mmapstr);
288
289 if (r != MAIL_NO_ERROR) {
290 msg_info->msg_flags = mail_flags_new_empty();
291 if (msg_info->msg_flags == NULL) {
292 res = MAIL_ERROR_MEMORY;
293 goto close_db;
294 }
295 }
296
297 mail_cache_db_close_unlock(sess_data->db_filename, maildb);
298
299 * result = msg_info->msg_flags;
300
301 return MAIL_NO_ERROR;
302
303 close_db:
304 mail_cache_db_close_unlock(sess_data->db_filename, maildb);
305 err:
306 return res;
307}
308
diff --git a/libetpan/src/driver/implementation/db/dbdriver_message.h b/libetpan/src/driver/implementation/db/dbdriver_message.h
new file mode 100644
index 0000000..f634775
--- a/dev/null
+++ b/libetpan/src/driver/implementation/db/dbdriver_message.h
@@ -0,0 +1,52 @@
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#ifndef DBDRIVER_MESSAGE_H
37
38#define DBDRIVER_MESSAGE_H
39
40#include <libetpan/dbdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * db_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/libetpan/src/driver/implementation/db/dbdriver_types.h b/libetpan/src/driver/implementation/db/dbdriver_types.h
new file mode 100644
index 0000000..052e3db
--- a/dev/null
+++ b/libetpan/src/driver/implementation/db/dbdriver_types.h
@@ -0,0 +1,71 @@
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#ifndef DBDRIVER_TYPES_H
37
38#define DBDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/generic_cache_types.h>
44#include <libetpan/mailstorage_types.h>
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50struct db_session_state_data {
51 char db_filename[PATH_MAX];
52 struct mail_flags_store * db_flags_store;
53};
54
55/* db storage */
56
57/*
58 db_mailstorage is the state data specific to the db storage.
59
60 - pathname is the path of the db storage.
61*/
62
63struct db_mailstorage {
64 char * db_pathname;
65};
66
67#ifdef __cplusplus
68}
69#endif
70
71#endif
diff --git a/libetpan/src/driver/implementation/db/dbstorage.c b/libetpan/src/driver/implementation/db/dbstorage.c
new file mode 100644
index 0000000..c4be63c
--- a/dev/null
+++ b/libetpan/src/driver/implementation/db/dbstorage.c
@@ -0,0 +1,144 @@
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 "dbstorage.h"
37#include "mailstorage.h"
38
39#include "mail.h"
40#include "mailmessage.h"
41#include "dbdriver.h"
42#include "maildriver.h"
43
44#include <stdlib.h>
45#include <string.h>
46
47/* db storage */
48
49static int db_mailstorage_connect(struct mailstorage * storage);
50static int
51db_mailstorage_get_folder_session(struct mailstorage * storage,
52 char * pathname, mailsession ** result);
53static void db_mailstorage_uninitialize(struct mailstorage * storage);
54
55static mailstorage_driver db_mailstorage_driver = {
56 .sto_name = "db",
57 .sto_connect = db_mailstorage_connect,
58 .sto_get_folder_session = db_mailstorage_get_folder_session,
59 .sto_uninitialize = db_mailstorage_uninitialize,
60};
61
62int db_mailstorage_init(struct mailstorage * storage,
63 char * db_pathname)
64{
65 struct db_mailstorage * db_storage;
66
67 db_storage = malloc(sizeof(* db_storage));
68 if (db_storage == NULL)
69 goto err;
70
71 db_storage->db_pathname = strdup(db_pathname);
72 if (db_storage->db_pathname == NULL)
73 goto free;
74
75 storage->sto_data = db_storage;
76 storage->sto_driver = &db_mailstorage_driver;
77
78 return MAIL_NO_ERROR;
79
80 free:
81 free(db_storage);
82 err:
83 return MAIL_ERROR_MEMORY;
84}
85
86static void db_mailstorage_uninitialize(struct mailstorage * storage)
87{
88 struct db_mailstorage * db_storage;
89
90 db_storage = storage->sto_data;
91 free(db_storage->db_pathname);
92 free(db_storage);
93
94 storage->sto_data = NULL;
95}
96
97static int db_mailstorage_connect(struct mailstorage * storage)
98{
99 struct db_mailstorage * db_storage;
100 mailsession_driver * driver;
101 int r;
102 int res;
103 mailsession * session;
104
105 db_storage = storage->sto_data;
106
107 driver = db_session_driver;
108
109 session = mailsession_new(driver);
110 if (session == NULL) {
111 res = MAIL_ERROR_MEMORY;
112 goto err;
113 }
114
115 r = mailsession_connect_path(session, db_storage->db_pathname);
116 switch (r) {
117 case MAIL_NO_ERROR_NON_AUTHENTICATED:
118 case MAIL_NO_ERROR_AUTHENTICATED:
119 case MAIL_NO_ERROR:
120 break;
121 default:
122 res = r;
123 goto free;
124 }
125
126 storage->sto_session = session;
127
128 return MAIL_NO_ERROR;
129
130 free:
131 mailsession_free(session);
132 err:
133 return res;
134}
135
136static int
137db_mailstorage_get_folder_session(struct mailstorage * storage,
138 char * pathname, mailsession ** result)
139{
140 * result = storage->sto_session;
141
142 return MAIL_NO_ERROR;
143}
144
diff --git a/libetpan/src/driver/implementation/db/dbstorage.h b/libetpan/src/driver/implementation/db/dbstorage.h
new file mode 100644
index 0000000..5fa9659
--- a/dev/null
+++ b/libetpan/src/driver/implementation/db/dbstorage.h
@@ -0,0 +1,61 @@
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#ifndef DBSTORAGE_H
37
38#define DBSTORAGE_H
39
40#include <libetpan/dbdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 db_mailstorage_init is the constructor for a DB storage.
48
49 @param storage this is the storage to initialize.
50
51 @param pathname is the directory that contains the mailbox.
52*/
53
54int db_mailstorage_init(struct mailstorage * storage,
55 char * db_pathname);
56
57#ifdef __cplusplus
58}
59#endif
60
61#endif