summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic
authorzautrix <zautrix>2004-07-03 16:33:12 (UTC)
committer zautrix <zautrix>2004-07-03 16:33:12 (UTC)
commite3b89230f065c48c84b48c88edb6eb088374c487 (patch) (unidiff)
tree162ea2ef909a6f82ccfcedf45d80d6c821174912 /kmicromail/libetpan/generic
parent2dd6ac0b2d24c91d35ce674a6c26351352df2b15 (diff)
downloadkdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.zip
kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.gz
kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.bz2
Initial revision
Diffstat (limited to 'kmicromail/libetpan/generic') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/.libs/libmaildriver.abin0 -> 1412946 bytes
-rw-r--r--kmicromail/libetpan/generic/TODO9
-rw-r--r--kmicromail/libetpan/generic/data_message_driver.c119
-rw-r--r--kmicromail/libetpan/generic/data_message_driver.h50
-rw-r--r--kmicromail/libetpan/generic/generic_cache.c729
-rw-r--r--kmicromail/libetpan/generic/generic_cache.h109
-rw-r--r--kmicromail/libetpan/generic/generic_cache_types.h56
-rw-r--r--kmicromail/libetpan/generic/imapdriver.c1130
-rw-r--r--kmicromail/libetpan/generic/imapdriver.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached.c1274
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached_message.c664
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_message.c1239
-rw-r--r--kmicromail/libetpan/generic/imapdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_tools.c3599
-rw-r--r--kmicromail/libetpan/generic/imapdriver_tools.h113
-rw-r--r--kmicromail/libetpan/generic/imapdriver_types.h144
-rw-r--r--kmicromail/libetpan/generic/imapstorage.c297
-rw-r--r--kmicromail/libetpan/generic/imapstorage.h90
-rw-r--r--kmicromail/libetpan/generic/imfcache.c1429
-rw-r--r--kmicromail/libetpan/generic/imfcache.h75
-rw-r--r--kmicromail/libetpan/generic/libetpan.h104
-rw-r--r--kmicromail/libetpan/generic/libetpan_version.c18
-rw-r--r--kmicromail/libetpan/generic/libetpan_version.h51
-rw-r--r--kmicromail/libetpan/generic/libetpan_version.h.in51
-rw-r--r--kmicromail/libetpan/generic/maildirdriver.c625
-rw-r--r--kmicromail/libetpan/generic/maildirdriver.h53
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached.c1080
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached.h53
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached_message.c248
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_message.c199
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_tools.c195
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_tools.h53
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_types.h96
-rw-r--r--kmicromail/libetpan/generic/maildirstorage.c192
-rw-r--r--kmicromail/libetpan/generic/maildirstorage.h69
-rw-r--r--kmicromail/libetpan/generic/maildriver.c373
-rw-r--r--kmicromail/libetpan/generic/maildriver.h543
-rw-r--r--kmicromail/libetpan/generic/maildriver_errors.h99
-rw-r--r--kmicromail/libetpan/generic/maildriver_tools.c841
-rw-r--r--kmicromail/libetpan/generic/maildriver_tools.h81
-rw-r--r--kmicromail/libetpan/generic/maildriver_types.c340
-rw-r--r--kmicromail/libetpan/generic/maildriver_types.h793
-rw-r--r--kmicromail/libetpan/generic/maildriver_types_helper.c104
-rw-r--r--kmicromail/libetpan/generic/maildriver_types_helper.h99
-rw-r--r--kmicromail/libetpan/generic/mailfolder.c96
-rw-r--r--kmicromail/libetpan/generic/mailfolder.h32
-rw-r--r--kmicromail/libetpan/generic/mailmessage.c240
-rw-r--r--kmicromail/libetpan/generic/mailmessage.h379
-rw-r--r--kmicromail/libetpan/generic/mailmessage_tools.c600
-rw-r--r--kmicromail/libetpan/generic/mailmessage_tools.h103
-rw-r--r--kmicromail/libetpan/generic/mailmessage_types.c92
-rw-r--r--kmicromail/libetpan/generic/mailmessage_types.h50
-rw-r--r--kmicromail/libetpan/generic/mailstorage.c334
-rw-r--r--kmicromail/libetpan/generic/mailstorage.h98
-rw-r--r--kmicromail/libetpan/generic/mailstorage_tools.c372
-rw-r--r--kmicromail/libetpan/generic/mailstorage_tools.h67
-rw-r--r--kmicromail/libetpan/generic/mailstorage_types.h203
-rw-r--r--kmicromail/libetpan/generic/mailthread.c1631
-rw-r--r--kmicromail/libetpan/generic/mailthread.h108
-rw-r--r--kmicromail/libetpan/generic/mailthread_types.c90
-rw-r--r--kmicromail/libetpan/generic/mailthread_types.h63
-rw-r--r--kmicromail/libetpan/generic/mboxdriver.c505
-rw-r--r--kmicromail/libetpan/generic/mboxdriver.h52
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached.c1253
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached.h54
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached_message.c360
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_message.c225
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_tools.c434
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_tools.h85
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_types.h107
-rw-r--r--kmicromail/libetpan/generic/mboxstorage.c192
-rw-r--r--kmicromail/libetpan/generic/mboxstorage.h69
-rw-r--r--kmicromail/libetpan/generic/mhdriver.c866
-rw-r--r--kmicromail/libetpan/generic/mhdriver.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached.c1232
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached_message.c338
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_message.c212
-rw-r--r--kmicromail/libetpan/generic/mhdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_tools.c475
-rw-r--r--kmicromail/libetpan/generic/mhdriver_tools.h80
-rw-r--r--kmicromail/libetpan/generic/mhdriver_types.h100
-rw-r--r--kmicromail/libetpan/generic/mhstorage.c192
-rw-r--r--kmicromail/libetpan/generic/mhstorage.h67
-rw-r--r--kmicromail/libetpan/generic/mime_message_driver.c689
-rw-r--r--kmicromail/libetpan/generic/mime_message_driver.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver.c1170
-rw-r--r--kmicromail/libetpan/generic/nntpdriver.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached.c1048
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached_message.c365
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_message.c169
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_tools.c563
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_tools.h88
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_types.h146
-rw-r--r--kmicromail/libetpan/generic/nntpstorage.c267
-rw-r--r--kmicromail/libetpan/generic/nntpstorage.h93
-rw-r--r--kmicromail/libetpan/generic/pop3driver.c387
-rw-r--r--kmicromail/libetpan/generic/pop3driver.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached.c857
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached_message.c355
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_message.c159
-rw-r--r--kmicromail/libetpan/generic/pop3driver_message.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_tools.c344
-rw-r--r--kmicromail/libetpan/generic/pop3driver_tools.h82
-rw-r--r--kmicromail/libetpan/generic/pop3driver_types.h153
-rw-r--r--kmicromail/libetpan/generic/pop3storage.c284
-rw-r--r--kmicromail/libetpan/generic/pop3storage.h95
119 files changed, 37348 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/.libs/libmaildriver.a b/kmicromail/libetpan/generic/.libs/libmaildriver.a
new file mode 100644
index 0000000..9cbc924
--- a/dev/null
+++ b/kmicromail/libetpan/generic/.libs/libmaildriver.a
Binary files differ
diff --git a/kmicromail/libetpan/generic/TODO b/kmicromail/libetpan/generic/TODO
new file mode 100644
index 0000000..fb992cd
--- a/dev/null
+++ b/kmicromail/libetpan/generic/TODO
@@ -0,0 +1,9 @@
1- add UID to non-cached drivers, help clients to recognize messages
2- move IMAP UID cache to non-cached driver
3- fix message size (put it in cache)
4- XXX : fetch body in nntp do not use generic_fetch_body
5- add flags prototype to add or remove flags
6- change prototype of append_message (add flags)
7- cache bodystructures
8- search is not implemented
9- list of folder new implementation
diff --git a/kmicromail/libetpan/generic/data_message_driver.c b/kmicromail/libetpan/generic/data_message_driver.c
new file mode 100644
index 0000000..26cb808
--- a/dev/null
+++ b/kmicromail/libetpan/generic/data_message_driver.c
@@ -0,0 +1,119 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - 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 "data_message_driver.h"
37
38#include "mailmessage.h"
39#include "mailmessage_tools.h"
40
41#include <unistd.h>
42#include <sys/mman.h>
43#include <sys/types.h>
44#include <sys/stat.h>
45#include <fcntl.h>
46#include <string.h>
47#include <stdlib.h>
48
49static int fetch_size(mailmessage * msg, size_t * result)
50{
51 struct generic_message_t * msg_data;
52
53 msg_data = msg->msg_data;
54 * result = msg_data->msg_length;
55
56 return MAIL_NO_ERROR;
57}
58
59
60static mailmessage_driver local_data_message_driver = {
61 .msg_name = "data",
62
63 .msg_initialize = mailmessage_generic_initialize,
64 .msg_uninitialize = mailmessage_generic_uninitialize,
65
66 .msg_flush = mailmessage_generic_flush,
67 .msg_check = NULL,
68
69 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
70
71 .msg_fetch = mailmessage_generic_fetch,
72 .msg_fetch_header = mailmessage_generic_fetch_header,
73 .msg_fetch_body = mailmessage_generic_fetch_body,
74 .msg_fetch_size = fetch_size,
75 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
76 .msg_fetch_section = mailmessage_generic_fetch_section,
77 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
78 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
79 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
80 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
81
82 .msg_get_flags = NULL,
83};
84
85mailmessage_driver * data_message_driver = &local_data_message_driver;
86
87
88
89mailmessage * data_message_init(char * data, size_t len)
90{
91 struct generic_message_t * msg_data;
92 mailmessage * msg;
93 int r;
94
95 msg = mailmessage_new();
96 if (msg == NULL)
97 goto err;
98
99 r = mailmessage_init(msg, NULL, data_message_driver, 0, len);
100 if (r < 0)
101 goto free;
102
103 msg_data = msg->msg_data;
104 msg_data->msg_fetched = 1;
105 msg_data->msg_message = data;
106 msg_data->msg_length = len;
107
108 return msg;
109
110 free:
111 mailmessage_free(msg);
112 err:
113 return NULL;
114}
115
116void data_message_detach_mime(mailmessage * msg)
117{
118 msg->msg_mime = NULL;
119}
diff --git a/kmicromail/libetpan/generic/data_message_driver.h b/kmicromail/libetpan/generic/data_message_driver.h
new file mode 100644
index 0000000..e0ee752
--- a/dev/null
+++ b/kmicromail/libetpan/generic/data_message_driver.h
@@ -0,0 +1,50 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - 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#ifndef DATA_MESSAGE_DRIVER_H
37
38#define DATA_MESSAGE_DRIVER_H
39
40#include <libetpan/mailmessage.h>
41
42#define LIBETPAN_DATA_MESSAGE
43
44extern mailmessage_driver * data_message_driver;
45
46mailmessage * data_message_init(char * data, size_t len);
47
48void data_message_detach_mime(mailmessage * msg);
49
50#endif
diff --git a/kmicromail/libetpan/generic/generic_cache.c b/kmicromail/libetpan/generic/generic_cache.c
new file mode 100644
index 0000000..d23f9cb
--- a/dev/null
+++ b/kmicromail/libetpan/generic/generic_cache.c
@@ -0,0 +1,729 @@
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 "generic_cache.h"
37
38#include "libetpan-config.h"
39
40#include <unistd.h>
41#include <string.h>
42#include <sys/mman.h>
43#include <stdio.h>
44#include <sys/types.h>
45#include <sys/stat.h>
46#include <fcntl.h>
47#include <unistd.h>
48#include <stdlib.h>
49
50#include "maildriver_types.h"
51#include "imfcache.h"
52#include "chash.h"
53#include "mailmessage.h"
54#include "mail_cache_db.h"
55
56int generic_cache_create_dir(char * dirname)
57{
58 struct stat buf;
59 int r;
60
61 r = stat(dirname, &buf);
62 if (r != 0) {
63 r = mkdir(dirname, 0700);
64
65 if (r < 0)
66 return MAIL_ERROR_FILE;
67 }
68 else {
69 if (!S_ISDIR(buf.st_mode))
70 return MAIL_ERROR_FILE;
71 }
72
73 return MAIL_NO_ERROR;
74}
75
76int generic_cache_store(char * filename, char * content, size_t length)
77{
78 int fd;
79 char * str;
80
81 fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
82 if (fd == -1)
83 return MAIL_ERROR_FILE;
84
85 if (ftruncate(fd, length) < 0)
86 return MAIL_ERROR_FILE;
87
88 str = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
89 if (str == MAP_FAILED)
90 return MAIL_ERROR_FILE;
91
92 memcpy(str, content, length);
93 msync(str, length, MS_SYNC);
94 munmap(str, length);
95
96 close(fd);
97
98 return MAIL_NO_ERROR;
99}
100
101int generic_cache_read(char * filename, char ** result, size_t * result_len)
102{
103 int fd;
104 char * str;
105 struct stat buf;
106 MMAPString * mmapstr;
107 char * content;
108 int res;
109
110 if (stat(filename, &buf) < 0) {
111 res = MAIL_ERROR_CACHE_MISS;
112 goto err;
113 }
114
115 fd = open(filename, O_RDONLY);
116 if (fd == -1) {
117 res = MAIL_ERROR_CACHE_MISS;
118 goto err;
119 }
120
121 str = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
122 if (str == MAP_FAILED) {
123 res = MAIL_ERROR_FILE;
124 goto close;
125 }
126
127 mmapstr = mmap_string_new_len(str, buf.st_size);
128 if (mmapstr == NULL) {
129 res = MAIL_ERROR_MEMORY;
130 goto unmap;
131 }
132
133 if (mmap_string_ref(mmapstr) < 0) {
134 res = MAIL_ERROR_MEMORY;
135 goto free;
136 }
137
138 content = mmapstr->str;
139
140 munmap(str, buf.st_size);
141 close(fd);
142
143 * result = content;
144 * result_len = buf.st_size;
145
146 return MAIL_NO_ERROR;
147
148 free:
149 mmap_string_free(mmapstr);
150 unmap:
151 munmap(str, buf.st_size);
152 close:
153 close(fd);
154 err:
155 return res;
156}
157
158static int flags_extension_read(MMAPString * mmapstr, size_t * index,
159 clist ** result)
160{
161 clist * list;
162 int r;
163 uint32_t count;
164 uint32_t i;
165 int res;
166
167 r = mailimf_cache_int_read(mmapstr, index, &count);
168 if (r != MAIL_NO_ERROR) {
169 res = r;
170 goto err;
171 }
172
173 list = clist_new();
174 if (list == NULL) {
175 res = MAIL_ERROR_MEMORY;
176 goto err;
177 }
178
179 for(i = 0 ; i < count ; i++) {
180 char * str;
181
182 r = mailimf_cache_string_read(mmapstr, index, &str);
183 if (r != MAIL_NO_ERROR) {
184 res = r;
185 goto free_list;
186 }
187
188 r = clist_append(list, str);
189 if (r < 0) {
190 free(str);
191 res = MAIL_ERROR_MEMORY;
192 goto free_list;
193 }
194 }
195
196 * result = list;
197
198 return MAIL_NO_ERROR;
199
200 free_list:
201 clist_foreach(list, (clist_func) free, NULL);
202 clist_free(list);
203 err:
204 return res;
205}
206
207static int generic_flags_read(MMAPString * mmapstr, size_t * index,
208 struct mail_flags ** result)
209{
210 clist * ext;
211 int r;
212 struct mail_flags * flags;
213 uint32_t value;
214 int res;
215
216 r = mailimf_cache_int_read(mmapstr, index, &value);
217 if (r != MAIL_NO_ERROR) {
218 res = r;
219 goto err;
220 }
221
222 r = flags_extension_read(mmapstr, index, &ext);
223 if (r != MAIL_NO_ERROR) {
224 res = r;
225 goto err;
226 }
227
228 flags = mail_flags_new(value, ext);
229 if (flags == NULL) {
230 res = r;
231 goto free;
232 }
233
234 * result = flags;
235
236 return MAIL_NO_ERROR;
237
238 free:
239 clist_foreach(ext, (clist_func) free, NULL);
240 clist_free(ext);
241 err:
242 return res;
243}
244
245static int flags_extension_write(MMAPString * mmapstr, size_t * index,
246 clist * ext)
247{
248 int r;
249 clistiter * cur;
250
251 r = mailimf_cache_int_write(mmapstr, index, clist_count(ext));
252 if (r != MAIL_NO_ERROR)
253 return r;
254
255 for(cur = clist_begin(ext) ; cur != NULL ; cur = clist_next(cur)) {
256 r = mailimf_cache_string_write(mmapstr, index,
257 clist_content(cur), strlen(clist_content(cur)));
258 if (r != MAIL_NO_ERROR)
259 return r;
260 }
261
262 return MAIL_NO_ERROR;
263}
264
265static int generic_flags_write(MMAPString * mmapstr, size_t * index,
266 struct mail_flags * flags)
267{
268 int r;
269
270 r = mailimf_cache_int_write(mmapstr, index,
271 flags->fl_flags & ~MAIL_FLAG_NEW);
272 if (r != MAIL_NO_ERROR)
273 return r;
274
275 r = flags_extension_write(mmapstr, index,
276 flags->fl_extension);
277 if (r != MAIL_NO_ERROR)
278 return r;
279
280 return MAIL_NO_ERROR;
281}
282
283
284
285
286static struct mail_flags * mail_flags_dup(struct mail_flags * flags)
287{
288 clist * list;
289 struct mail_flags * new_flags;
290 int r;
291 clistiter * cur;
292
293 list = clist_new();
294 if (list == NULL) {
295 goto err;
296 }
297
298 for(cur = clist_begin(flags->fl_extension) ; cur != NULL ;
299 cur = clist_next(cur)) {
300 char * ext;
301
302 ext = strdup(clist_content(cur));
303 if (ext == NULL) {
304 goto free;
305 }
306
307 r = clist_append(list, ext);
308 if (r < 0) {
309 free(ext);
310 goto free;
311 }
312 }
313
314 new_flags = mail_flags_new(flags->fl_flags, list);
315 if (new_flags == NULL) {
316 goto free;
317 }
318
319 return new_flags;
320
321 free:
322 clist_foreach(list, (clist_func) free, NULL);
323 clist_free(list);
324 err:
325 return NULL;
326}
327
328static mailmessage * mailmessage_build(mailmessage * msg)
329{
330 mailmessage * new_msg;
331
332 new_msg = malloc(sizeof(* new_msg));
333 if (new_msg == NULL)
334 goto err;
335
336 new_msg->msg_session = msg->msg_session;
337 new_msg->msg_driver = msg->msg_driver;
338 new_msg->msg_index = msg->msg_index;
339 if (msg->msg_uid == NULL)
340 new_msg->msg_uid = NULL;
341 else {
342 new_msg->msg_uid = strdup(msg->msg_uid);
343 if (new_msg->msg_uid == NULL)
344 goto free;
345 }
346
347 new_msg->msg_cached = msg->msg_cached;
348 new_msg->msg_size = msg->msg_size;
349 new_msg->msg_fields = NULL;
350 new_msg->msg_flags = mail_flags_dup(msg->msg_flags);
351 if (new_msg->msg_flags == NULL) {
352 free(new_msg->msg_uid);
353 goto free;
354 }
355
356 new_msg->msg_mime = NULL;
357 new_msg->msg_data = NULL;
358
359 return new_msg;
360
361 free:
362 free(new_msg);
363 err:
364 return NULL;
365}
366
367struct mail_flags_store * mail_flags_store_new(void)
368{
369 struct mail_flags_store * flags_store;
370
371 flags_store = malloc(sizeof(struct mail_flags_store));
372 if (flags_store == NULL)
373 goto err;
374
375 flags_store->fls_tab = carray_new(128);
376 if (flags_store->fls_tab == NULL)
377 goto free;
378
379 flags_store->fls_hash = chash_new(128, CHASH_COPYALL);
380 if (flags_store->fls_hash == NULL)
381 goto free_tab;
382
383 return flags_store;
384
385 free_tab:
386 carray_free(flags_store->fls_tab);
387 free:
388 free(flags_store);
389 err:
390 return NULL;
391}
392
393void mail_flags_store_clear(struct mail_flags_store * flags_store)
394{
395 unsigned int i;
396
397 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
398 chashdatum key;
399 mailmessage * msg;
400
401 msg = carray_get(flags_store->fls_tab, i);
402
403 key.data = &msg->msg_index;
404 key.len = sizeof(msg->msg_index);
405 chash_delete(flags_store->fls_hash, &key, NULL);
406
407 mailmessage_free(msg);
408 }
409 carray_set_size(flags_store->fls_tab, 0);
410}
411
412void mail_flags_store_free(struct mail_flags_store * flags_store)
413{
414 mail_flags_store_clear(flags_store);
415 chash_free(flags_store->fls_hash);
416 carray_free(flags_store->fls_tab);
417 free(flags_store);
418}
419
420int mail_flags_store_set(struct mail_flags_store * flags_store,
421 mailmessage * msg)
422{
423 chashdatum key;
424 chashdatum value;
425 unsigned int index;
426 int res;
427 int r;
428 mailmessage * new_msg;
429
430 if (msg->msg_flags == NULL) {
431 res = MAIL_NO_ERROR;
432 goto err;
433 }
434
435 /* duplicate needed message info */
436 new_msg = mailmessage_build(msg);
437 if (new_msg == NULL) {
438 res = MAIL_ERROR_MEMORY;
439 goto err;
440 }
441
442 key.data = &new_msg->msg_index;
443 key.len = sizeof(new_msg->msg_index);
444
445 r = chash_get(flags_store->fls_hash, &key, &value);
446 if (r == 0) {
447 mailmessage * old_msg;
448
449 index = * (unsigned int *) value.data;
450 old_msg = carray_get(flags_store->fls_tab, index);
451 mailmessage_free(old_msg);
452 }
453 else {
454 r = carray_set_size(flags_store->fls_tab,
455 carray_count(flags_store->fls_tab) + 1);
456 if (r != 0) {
457 res = MAIL_ERROR_MEMORY;
458 goto err;
459 }
460 index = carray_count(flags_store->fls_tab) - 1;
461 }
462
463 carray_set(flags_store->fls_tab, index, new_msg);
464
465 value.data = &index;
466 value.len = sizeof(index);
467
468 r = chash_set(flags_store->fls_hash, &key, &value, NULL);
469 if (r < 0) {
470 carray_delete(flags_store->fls_tab, index);
471 res = MAIL_ERROR_MEMORY;
472 goto free;
473 }
474
475 return MAIL_NO_ERROR;
476
477 free:
478 mailmessage_free(new_msg);
479 err:
480 return res;
481}
482
483static int msg_index_compare(mailmessage ** msg1, mailmessage ** msg2)
484{
485 return (* msg1)->msg_index - (* msg2)->msg_index;
486}
487
488void mail_flags_store_sort(struct mail_flags_store * flags_store)
489{
490 qsort(carray_data(flags_store->fls_tab),
491 carray_count(flags_store->fls_tab), sizeof(mailmessage *),
492 (int (*)(const void *, const void *)) msg_index_compare);
493}
494
495struct mail_flags *
496mail_flags_store_get(struct mail_flags_store * flags_store, uint32_t index)
497{
498 struct mail_flags * flags;
499 chashdatum key;
500 chashdatum value;
501 int r;
502 unsigned int tab_index;
503 mailmessage * msg;
504
505 key.data = &index;
506 key.len = sizeof(index);
507
508 r = chash_get(flags_store->fls_hash, &key, &value);
509
510 if (r < 0)
511 return NULL;
512
513#if 0
514 flags = mail_flags_dup((struct mail_flags *) value.data);
515#endif
516 tab_index = * (unsigned int *) value.data;
517 msg = carray_get(flags_store->fls_tab, tab_index);
518 if (msg->msg_flags == NULL)
519 return NULL;
520
521 flags = mail_flags_dup(msg->msg_flags);
522
523 return flags;
524}
525
526int mail_flags_compare(struct mail_flags * flags1, struct mail_flags * flags2)
527{
528 clistiter * cur1;
529
530 if (clist_count(flags1->fl_extension) != clist_count(flags2->fl_extension))
531 return -1;
532
533 for(cur1 = clist_begin(flags1->fl_extension) ; cur1 != NULL ;
534 cur1 = clist_next(cur1)) {
535 char * flag1;
536 clistiter * cur2;
537 int found;
538
539 flag1 = clist_content(cur1);
540
541 found = 0;
542 for(cur2 = clist_begin(flags2->fl_extension) ; cur2 != NULL ;
543 cur2 = clist_next(cur2)) {
544 char * flag2;
545
546 flag2 = clist_content(cur2);
547
548 if (strcasecmp(flag1, flag2) == 0) {
549 found = 1;
550 break;
551 }
552 }
553
554 if (!found)
555 return -1;
556 }
557
558 return flags1->fl_flags - flags2->fl_flags;
559}
560
561
562int generic_cache_fields_read(struct mail_cache_db * cache_db,
563 MMAPString * mmapstr,
564 char * keyname, struct mailimf_fields ** result)
565{
566 int r;
567 int res;
568 size_t cur_token;
569 struct mailimf_fields * fields;
570 void * data;
571 size_t data_len;
572
573 r = mail_cache_db_get(cache_db, keyname, strlen(keyname), &data, &data_len);
574 if (r != 0) {
575 res = MAIL_ERROR_CACHE_MISS;
576 goto err;
577 }
578
579 r = mail_serialize_clear(mmapstr, &cur_token);
580 if (r != MAIL_NO_ERROR) {
581 res = r;
582 goto err;
583 }
584
585 if (mmap_string_append_len(mmapstr, data, data_len) == NULL) {
586 res = MAIL_ERROR_MEMORY;
587 goto err;
588 }
589
590 r = mailimf_cache_fields_read(mmapstr, &cur_token, &fields);
591 if (r != MAIL_NO_ERROR) {
592 res = r;
593 goto err;
594 }
595
596 * result = fields;
597
598 return MAIL_NO_ERROR;
599
600 err:
601 return res;
602}
603
604int generic_cache_fields_write(struct mail_cache_db * cache_db,
605 MMAPString * mmapstr,
606 char * keyname, struct mailimf_fields * fields)
607{
608 int r;
609 int res;
610 size_t cur_token;
611
612 r = mail_serialize_clear(mmapstr, &cur_token);
613 if (r != MAIL_NO_ERROR) {
614 res = r;
615 goto err;
616 }
617
618 r = mailimf_cache_fields_write(mmapstr, &cur_token, fields);
619 if (r != MAIL_NO_ERROR) {
620 res = r;
621 goto err;
622 }
623
624 r = mail_cache_db_put(cache_db, keyname, strlen(keyname),
625 mmapstr->str, mmapstr->len);
626 if (r != 0) {
627 res = MAIL_ERROR_FILE;
628 goto err;
629 }
630
631 return MAIL_NO_ERROR;
632
633 err:
634 return res;
635}
636
637int generic_cache_flags_read(struct mail_cache_db * cache_db,
638 MMAPString * mmapstr,
639 char * keyname, struct mail_flags ** result)
640{
641 int r;
642 int res;
643 size_t cur_token;
644 struct mail_flags * flags;
645 void * data;
646 size_t data_len;
647
648 r = mail_cache_db_get(cache_db, keyname, strlen(keyname), &data, &data_len);
649 if (r != 0) {
650 res = MAIL_ERROR_CACHE_MISS;
651 goto err;
652 }
653
654 r = mail_serialize_clear(mmapstr, &cur_token);
655 if (r != MAIL_NO_ERROR) {
656 res = r;
657 goto err;
658 }
659
660 if (mmap_string_append_len(mmapstr, data, data_len) == NULL) {
661 res = MAIL_ERROR_MEMORY;
662 goto err;
663 }
664
665 r = generic_flags_read(mmapstr, &cur_token, &flags);
666 if (r != MAIL_NO_ERROR) {
667 res = r;
668 goto err;
669 }
670
671 * result = flags;
672
673 return MAIL_NO_ERROR;
674
675 err:
676 return res;
677}
678
679int generic_cache_flags_write(struct mail_cache_db * cache_db,
680 MMAPString * mmapstr,
681 char * keyname, struct mail_flags * flags)
682{
683 int r;
684 int res;
685 size_t cur_token;
686
687 r = mail_serialize_clear(mmapstr, &cur_token);
688 if (r != MAIL_NO_ERROR) {
689 res = r;
690 goto err;
691 }
692
693 r = generic_flags_write(mmapstr, &cur_token, flags);
694 if (r != MAIL_NO_ERROR) {
695 res = r;
696 goto err;
697 }
698
699 r = mail_cache_db_put(cache_db, keyname, strlen(keyname),
700 mmapstr->str, mmapstr->len);
701 if (r != 0) {
702 res = MAIL_ERROR_FILE;
703 goto err;
704 }
705
706 return MAIL_NO_ERROR;
707
708 err:
709 return res;
710}
711
712
713int generic_cache_delete(struct mail_cache_db * cache_db,
714 char * keyname)
715{
716 int r;
717 int res;
718
719 r = mail_cache_db_del(cache_db, keyname, strlen(keyname));
720 if (r != 0) {
721 res = MAIL_ERROR_FILE;
722 goto err;
723 }
724
725 return MAIL_NO_ERROR;
726
727 err:
728 return res;
729}
diff --git a/kmicromail/libetpan/generic/generic_cache.h b/kmicromail/libetpan/generic/generic_cache.h
new file mode 100644
index 0000000..7815831
--- a/dev/null
+++ b/kmicromail/libetpan/generic/generic_cache.h
@@ -0,0 +1,109 @@
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#ifndef GENERIC_CACHE_H
37
38#define GENERIC_CACHE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "generic_cache_types.h"
45#include "mailmessage_types.h"
46#include "chash.h"
47#include "carray.h"
48#include "mail_cache_db_types.h"
49
50int generic_cache_create_dir(char * dirname);
51
52int generic_cache_store(char * filename, char * content, size_t length);
53int generic_cache_read(char * filename, char ** result, size_t * result_len);
54
55int generic_cache_fields_read(struct mail_cache_db * cache_db,
56 MMAPString * mmapstr,
57 char * keyname, struct mailimf_fields ** result);
58
59int generic_cache_fields_write(struct mail_cache_db * cache_db,
60 MMAPString * mmapstr,
61 char * keyname, struct mailimf_fields * fields);
62
63int generic_cache_flags_read(struct mail_cache_db * cache_db,
64 MMAPString * mmapstr,
65 char * keyname, struct mail_flags ** result);
66
67int generic_cache_flags_write(struct mail_cache_db * cache_db,
68 MMAPString * mmapstr,
69 char * keyname, struct mail_flags * flags);
70
71int generic_cache_delete(struct mail_cache_db * cache_db, char * keyname);
72
73#if 0
74int generic_cache_fields_read(DB * dbp, MMAPString * mmapstr,
75 char * keyname, struct mailimf_fields ** result);
76
77int generic_cache_fields_write(DB * dbp, MMAPString * mmapstr,
78 char * keyname, struct mailimf_fields * fields);
79
80int generic_cache_flags_read(DB * dbp, MMAPString * mmapstr,
81 char * keyname, struct mail_flags ** result);
82
83int generic_cache_flags_write(DB * dbp, MMAPString * mmapstr,
84 char * keyname, struct mail_flags * flags);
85
86int generic_cache_delete(DB * dbp, char * keyname);
87#endif
88
89struct mail_flags_store * mail_flags_store_new(void);
90
91void mail_flags_store_clear(struct mail_flags_store * flags_store);
92
93void mail_flags_store_free(struct mail_flags_store * flags_store);
94
95int mail_flags_store_set(struct mail_flags_store * flags_store,
96 mailmessage * msg);
97
98void mail_flags_store_sort(struct mail_flags_store * flags_store);
99
100struct mail_flags *
101mail_flags_store_get(struct mail_flags_store * flags_store, uint32_t index);
102
103int mail_flags_compare(struct mail_flags * flags1, struct mail_flags * flags2);
104
105#ifdef __cplusplus
106}
107#endif
108
109#endif
diff --git a/kmicromail/libetpan/generic/generic_cache_types.h b/kmicromail/libetpan/generic/generic_cache_types.h
new file mode 100644
index 0000000..8803a42
--- a/dev/null
+++ b/kmicromail/libetpan/generic/generic_cache_types.h
@@ -0,0 +1,56 @@
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#ifndef GENERIC_CACHE_TYPE_H
37
38#define GENERIC_CACHE_TYPE_H
39
40#include <libetpan/carray.h>
41#include <libetpan/chash.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47struct mail_flags_store {
48 carray * fls_tab;
49 chash * fls_hash;
50};
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/generic/imapdriver.c b/kmicromail/libetpan/generic/imapdriver.c
new file mode 100644
index 0000000..0d63319
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver.c
@@ -0,0 +1,1130 @@
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 "imapdriver.h"
37
38#include "mail.h"
39#include "imapdriver_tools.h"
40#include "mailmessage.h"
41#include "imapdriver_message.h"
42#include "imapdriver_types.h"
43#include "maildriver.h"
44#include "maildriver_tools.h"
45#include "generic_cache.h"
46
47#include <stdlib.h>
48#include <string.h>
49
50static int imapdriver_initialize(mailsession * session);
51
52static void imapdriver_uninitialize(mailsession * session);
53
54static int imapdriver_connect_stream(mailsession * session, mailstream * s);
55
56static int imapdriver_starttls(mailsession * session);
57
58static int imapdriver_login(mailsession * session,
59 char * userid, char * password);
60
61static int imapdriver_logout(mailsession * session);
62
63static int imapdriver_noop(mailsession * session);
64
65static int imapdriver_build_folder_name(mailsession * session, char * mb,
66 char * name, char ** result);
67
68static int imapdriver_create_folder(mailsession * session, char * mb);
69
70static int imapdriver_delete_folder(mailsession * session, char * mb);
71
72static int imapdriver_rename_folder(mailsession * session, char * mb,
73 char * new_name);
74
75static int imapdriver_check_folder(mailsession * session);
76
77static int imapdriver_examine_folder(mailsession * session, char * mb);
78
79static int imapdriver_select_folder(mailsession * session, char * mb);
80static int imapdriver_expunge_folder(mailsession * session);
81
82static int imapdriver_status_folder(mailsession * session, char * mb,
83 uint32_t * result_messages, uint32_t * result_recent,
84 uint32_t * result_unseen);
85
86static int imapdriver_messages_number(mailsession * session, char * mb,
87 uint32_t * result);
88
89static int imapdriver_recent_number(mailsession * session, char * mb,
90 uint32_t * result);
91
92static int imapdriver_unseen_number(mailsession * session, char * mb,
93 uint32_t * result);
94
95static int imapdriver_list_folders(mailsession * session, char * mb,
96 struct mail_list ** result);
97static int imapdriver_lsub_folders(mailsession * session, char * mb,
98 struct mail_list ** result);
99static int imapdriver_subscribe_folder(mailsession * session, char * mb);
100static int imapdriver_unsubscribe_folder(mailsession * session, char * mb);
101static int imapdriver_append_message(mailsession * session,
102 char * message, size_t size);
103static int imapdriver_copy_message(mailsession * session,
104 uint32_t num, char * mb);
105
106static int imapdriver_get_messages_list(mailsession * session,
107 struct mailmessage_list ** result);
108
109static int
110imapdriver_get_envelopes_list(mailsession * session,
111 struct mailmessage_list * env_list);
112
113
114#if 0
115static int imapdriver_search_messages(mailsession * session, char * charset,
116 struct mail_search_key * key,
117 struct mail_search_result ** result);
118#endif
119
120static int imapdriver_get_message(mailsession * session,
121 uint32_t num, mailmessage ** result);
122
123static int imapdriver_get_message_by_uid(mailsession * session,
124 const char * uid,
125 mailmessage ** result);
126
127static mailsession_driver local_imap_session_driver = {
128 .sess_name = "imap",
129
130 .sess_initialize = imapdriver_initialize,
131 .sess_uninitialize = imapdriver_uninitialize,
132
133 .sess_parameters = NULL,
134
135 .sess_connect_stream = imapdriver_connect_stream,
136 .sess_connect_path = NULL,
137 .sess_starttls = imapdriver_starttls,
138 .sess_login = imapdriver_login,
139 .sess_logout = imapdriver_logout,
140 .sess_noop = imapdriver_noop,
141
142 .sess_build_folder_name = imapdriver_build_folder_name,
143 .sess_create_folder = imapdriver_create_folder,
144 .sess_delete_folder = imapdriver_delete_folder,
145 .sess_rename_folder = imapdriver_rename_folder,
146 .sess_check_folder = imapdriver_check_folder,
147 .sess_examine_folder = imapdriver_examine_folder,
148 .sess_select_folder = imapdriver_select_folder,
149 .sess_expunge_folder = imapdriver_expunge_folder,
150 .sess_status_folder = imapdriver_status_folder,
151 .sess_messages_number = imapdriver_messages_number,
152 .sess_recent_number = imapdriver_recent_number,
153 .sess_unseen_number = imapdriver_unseen_number,
154 .sess_list_folders = imapdriver_list_folders,
155 .sess_lsub_folders = imapdriver_lsub_folders,
156 .sess_subscribe_folder = imapdriver_subscribe_folder,
157 .sess_unsubscribe_folder = imapdriver_unsubscribe_folder,
158
159 .sess_append_message = imapdriver_append_message,
160 .sess_copy_message = imapdriver_copy_message,
161 .sess_move_message = NULL,
162
163 .sess_get_messages_list = imapdriver_get_messages_list,
164 .sess_get_envelopes_list = imapdriver_get_envelopes_list,
165 .sess_remove_message = NULL,
166#if 0
167 .sess_search_messages = imapdriver_search_messages,
168#endif
169
170 .sess_get_message = imapdriver_get_message,
171 .sess_get_message_by_uid = imapdriver_get_message_by_uid,
172};
173
174mailsession_driver * imap_session_driver = &local_imap_session_driver;
175
176static inline struct imap_session_state_data * get_data(mailsession * session)
177{
178 return session->sess_data;
179}
180
181static mailimap * get_imap_session(mailsession * session)
182{
183 return get_data(session)->imap_session;
184}
185
186static int imapdriver_initialize(mailsession * session)
187{
188 struct imap_session_state_data * data;
189 mailimap * imap;
190 struct mail_flags_store * flags_store;
191
192 imap = mailimap_new(0, NULL);
193 if (imap == NULL)
194 goto err;
195
196 flags_store = mail_flags_store_new();
197 if (flags_store == NULL)
198 goto free_session;
199
200 data = malloc(sizeof(* data));
201 if (data == NULL)
202 goto free_flags_store;
203
204 data->imap_mailbox = NULL;
205 data->imap_session = imap;
206 data->imap_flags_store = flags_store;
207
208 session->sess_data = data;
209
210 return MAIL_NO_ERROR;
211
212 free_flags_store:
213 mail_flags_store_free(flags_store);
214 free_session:
215 mailimap_free(imap);
216 err:
217 return MAIL_ERROR_MEMORY;
218}
219
220static void imap_flags_store_process(mailimap * imap,
221 struct mail_flags_store * flags_store)
222{
223 unsigned int i;
224 int r;
225 mailmessage * first;
226 mailmessage * last;
227
228 mail_flags_store_sort(flags_store);
229
230 if (carray_count(flags_store->fls_tab) == 0)
231 return;
232
233 first = carray_get(flags_store->fls_tab, 0);
234 last = first;
235
236 for(i = 1 ; i < carray_count(flags_store->fls_tab) ; i ++) {
237 mailmessage * msg;
238
239 msg = carray_get(flags_store->fls_tab, i);
240
241 if (last->msg_index + 1 == msg->msg_index) {
242 r = mail_flags_compare(first->msg_flags, msg->msg_flags);
243 if (r == 0) {
244 last = msg;
245 continue;
246 }
247 }
248
249 r = imap_store_flags(imap, first->msg_index,
250 last->msg_index, first->msg_flags);
251
252 first = msg;
253 last = msg;
254 }
255
256 r = imap_store_flags(imap, first->msg_index, last->msg_index,
257 first->msg_flags);
258
259 mail_flags_store_clear(flags_store);
260}
261
262static void imapdriver_uninitialize(mailsession * session)
263{
264 struct imap_session_state_data * data;
265
266 data = get_data(session);
267
268 imap_flags_store_process(data->imap_session,
269 data->imap_flags_store);
270 mail_flags_store_free(data->imap_flags_store);
271
272 mailimap_free(data->imap_session);
273 if (data->imap_mailbox != NULL)
274 free(data->imap_mailbox);
275 free(data);
276
277 session->sess_data = NULL;
278}
279
280static int imapdriver_connect_stream(mailsession * session, mailstream * s)
281{
282 int r;
283
284 r = mailimap_connect(get_imap_session(session), s);
285
286 return imap_error_to_mail_error(r);
287}
288
289static int imapdriver_login(mailsession * session,
290 char * userid, char * password)
291{
292 int r;
293
294 r = mailimap_login(get_imap_session(session), userid, password);
295
296 return imap_error_to_mail_error(r);
297}
298
299static int imapdriver_logout(mailsession * session)
300{
301 int r;
302
303 imap_flags_store_process(get_imap_session(session),
304 get_data(session)->imap_flags_store);
305
306 r = mailimap_logout(get_imap_session(session));
307
308 return imap_error_to_mail_error(r);
309}
310
311static int imapdriver_noop(mailsession * session)
312{
313 int r;
314
315 r = mailimap_noop(get_imap_session(session));
316
317 return imap_error_to_mail_error(r);
318}
319
320static int imapdriver_build_folder_name(mailsession * session, char * mb,
321 char * name, char ** result)
322{
323 char delimiter[2] = "X";
324 char * folder_name;
325 mailimap * imap;
326 struct mailimap_mailbox_list * mb_list;
327 int r;
328 clist * imap_list;
329
330 imap = get_imap_session(session);
331
332 r = mailimap_list(imap, mb, "", &imap_list);
333 if (r != MAILIMAP_NO_ERROR)
334 return r;
335
336 if (clist_begin(imap_list) == NULL)
337 return MAIL_ERROR_LIST;
338
339 mb_list = clist_begin(imap_list)->data;
340 delimiter[0] = mb_list->mb_delimiter;
341
342 folder_name = malloc(strlen(mb) + strlen(delimiter) + strlen(name) + 1);
343 if (folder_name == NULL)
344 return MAIL_ERROR_MEMORY;
345
346 strcpy(folder_name, mb);
347 strcat(folder_name, delimiter);
348 strcat(folder_name, name);
349
350 * result = folder_name;
351
352 return MAIL_NO_ERROR;
353}
354
355/* folders operations */
356
357static int imapdriver_create_folder(mailsession * session, char * mb)
358{
359 int r;
360
361 r = mailimap_create(get_imap_session(session), mb);
362
363 return imap_error_to_mail_error(r);
364}
365
366static int imapdriver_delete_folder(mailsession * session, char * mb)
367{
368 int r;
369
370 r = mailimap_delete(get_imap_session(session), mb);
371
372 return imap_error_to_mail_error(r);
373}
374
375static int imapdriver_rename_folder(mailsession * session, char * mb,
376 char * new_name)
377{
378 int r;
379
380 r = mailimap_rename(get_imap_session(session), mb, new_name);
381
382 return imap_error_to_mail_error(r);
383}
384
385static int imapdriver_check_folder(mailsession * session)
386{
387 int r;
388
389 imap_flags_store_process(get_imap_session(session),
390 get_data(session)->imap_flags_store);
391
392 r = mailimap_check(get_imap_session(session));
393
394 return imap_error_to_mail_error(r);
395}
396
397static int imapdriver_examine_folder(mailsession * session, char * mb)
398{
399 int r;
400
401 r = mailimap_examine(get_imap_session(session), mb);
402
403 return imap_error_to_mail_error(r);
404}
405
406static int imapdriver_select_folder(mailsession * session, char * mb)
407{
408 int r;
409 char * new_mb;
410 char * old_mb;
411
412 old_mb = get_data(session)->imap_mailbox;
413 if (old_mb != NULL)
414 if (strcmp(mb, old_mb) == 0)
415 return MAIL_NO_ERROR;
416
417 imap_flags_store_process(get_imap_session(session),
418 get_data(session)->imap_flags_store);
419
420 r = mailimap_select(get_imap_session(session), mb);
421
422 switch (r) {
423 case MAILIMAP_NO_ERROR:
424 new_mb = strdup(mb);
425 if (new_mb == NULL) {
426 if (old_mb != NULL)
427 free(old_mb);
428 get_data(session)->imap_mailbox = NULL;
429 return MAIL_ERROR_MEMORY;
430 }
431
432 get_data(session)->imap_mailbox = new_mb;
433
434 return MAIL_NO_ERROR;
435 default:
436 return imap_error_to_mail_error(r);
437 }
438}
439
440static int imapdriver_expunge_folder(mailsession * session)
441{
442 int r;
443
444 imap_flags_store_process(get_imap_session(session),
445 get_data(session)->imap_flags_store);
446
447 r = mailimap_expunge(get_imap_session(session));
448
449 return imap_error_to_mail_error(r);
450}
451
452static int status_selected_folder(mailsession * session, char * mb,
453 uint32_t * result_messages, uint32_t * result_recent,
454 uint32_t * result_unseen)
455{
456 int r;
457 int res;
458 mailimap * imap;
459 uint32_t exists;
460 uint32_t unseen;
461 uint32_t recent;
462 struct mailimap_search_key * search_key;
463 clist * search_result;
464
465 imap = get_imap_session(session);
466
467 exists = imap->imap_selection_info->sel_exists;
468 recent = imap->imap_selection_info->sel_recent;
469
470 search_key = mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UNSEEN,
471 NULL, NULL, NULL, NULL, NULL,
472 NULL, NULL, NULL, NULL, NULL,
473 NULL, NULL, NULL, NULL, 0,
474 NULL, NULL, NULL, NULL, NULL,
475 NULL, 0, NULL, NULL, NULL);
476 if (search_key == NULL) {
477 res = MAIL_ERROR_MEMORY;
478 goto err;
479 }
480
481 /* default : use the RECENT count if search fails */
482 unseen = recent;
483 r = mailimap_search(imap, NULL, search_key, &search_result);
484 mailimap_search_key_free(search_key);
485 if (r == MAILIMAP_NO_ERROR) {
486 /* if this succeed, we use the real count */
487 unseen = clist_count(search_result);
488 mailimap_mailbox_data_search_free(search_result);
489 }
490
491 * result_messages = exists;
492 * result_unseen = unseen;
493 * result_recent = recent;
494
495 return MAIL_NO_ERROR;
496
497 err:
498 return res;
499}
500
501static int status_unselected_folder(mailsession * session, char * mb,
502 uint32_t * result_messages, uint32_t * result_recent,
503 uint32_t * result_unseen)
504{
505 struct mailimap_status_att_list * att_list;
506 struct mailimap_mailbox_data_status * status;
507 int r;
508 int res;
509 clistiter * cur;
510 mailimap * imap;
511
512 imap = get_imap_session(session);
513
514 att_list = mailimap_status_att_list_new_empty();
515 if (att_list == NULL) {
516 res = MAIL_ERROR_MEMORY;
517 goto err;
518 }
519
520 r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_MESSAGES);
521 switch (r) {
522 case MAILIMAP_NO_ERROR:
523 break;
524 default:
525 res = MAIL_ERROR_MEMORY;
526 goto free;
527 }
528
529 r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_RECENT);
530 switch (r) {
531 case MAILIMAP_NO_ERROR:
532 break;
533 default:
534 res = MAIL_ERROR_MEMORY;
535 goto free;
536 }
537
538 r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_UNSEEN);
539 switch (r) {
540 case MAILIMAP_NO_ERROR:
541 break;
542 default:
543 res = MAIL_ERROR_MEMORY;
544 goto free;
545 }
546
547 r = mailimap_status(imap, mb, att_list, &status);
548
549 switch (r) {
550 case MAILIMAP_NO_ERROR:
551 break;
552 default:
553 res = imap_error_to_mail_error(r);
554 goto free;
555 }
556
557 * result_messages = 0;
558 * result_recent = 0;
559 * result_unseen = 0;
560
561 for (cur = clist_begin(status->st_info_list);
562 cur != NULL ; cur = clist_next(cur)) {
563 struct mailimap_status_info * status_info;
564
565 status_info = clist_content(cur);
566 switch (status_info->st_att) {
567 case MAILIMAP_STATUS_ATT_MESSAGES:
568 * result_messages = status_info->st_value;
569 break;
570 case MAILIMAP_STATUS_ATT_RECENT:
571 * result_recent = status_info->st_value;
572 break;
573 case MAILIMAP_STATUS_ATT_UNSEEN:
574 * result_unseen = status_info->st_value;
575 break;
576 }
577 }
578
579 mailimap_mailbox_data_status_free(status);
580 mailimap_status_att_list_free(att_list);
581
582 return MAIL_NO_ERROR;
583
584 free:
585 mailimap_status_att_list_free(att_list);
586 err:
587 return res;
588}
589
590static int imapdriver_status_folder(mailsession * session, char * mb,
591 uint32_t * result_messages, uint32_t * result_recent,
592 uint32_t * result_unseen)
593{
594 int res;
595 int current_folder;
596 char * current_mb;
597
598 if (mb == NULL) {
599 mb = get_data(session)->imap_mailbox;
600 if (mb == NULL) {
601 res = MAIL_ERROR_BAD_STATE;
602 goto err;
603 }
604 }
605
606 current_mb = get_data(session)->imap_mailbox;
607 if (strcmp(mb, current_mb) == 0)
608 current_folder = 1;
609 else
610 current_folder = 0;
611
612 if (current_folder)
613 return status_selected_folder(session, mb, result_messages,
614 result_recent, result_unseen);
615 else
616 return status_unselected_folder(session, mb, result_messages,
617 result_recent, result_unseen);
618
619 err:
620 return res;
621}
622
623/* TODO : more efficient functions */
624
625static int imapdriver_messages_number(mailsession * session, char * mb,
626 uint32_t * result)
627{
628 uint32_t messages;
629 uint32_t recent;
630 uint32_t unseen;
631 int r;
632
633 r = imapdriver_status_folder(session, mb, &messages, &recent, &unseen);
634 if (r != MAIL_NO_ERROR)
635 return r;
636
637 * result = messages;
638
639 return MAIL_NO_ERROR;
640}
641
642static int imapdriver_recent_number(mailsession * session, char * mb,
643 uint32_t * result)
644{
645 uint32_t messages;
646 uint32_t recent;
647 uint32_t unseen;
648 int r;
649
650 r = imapdriver_status_folder(session, mb, &messages, &recent, &unseen);
651 if (r != MAIL_NO_ERROR)
652 return r;
653
654 * result = recent;
655
656 return MAIL_NO_ERROR;
657}
658
659static int imapdriver_unseen_number(mailsession * session, char * mb,
660 uint32_t * result)
661{
662 uint32_t messages;
663 uint32_t recent;
664 uint32_t unseen;
665 int r;
666
667 r = imapdriver_status_folder(session, mb, &messages, &recent, &unseen);
668 if (r != MAIL_NO_ERROR)
669 return r;
670
671 * result = unseen;
672
673 return MAIL_NO_ERROR;
674}
675
676enum {
677 IMAP_LIST, IMAP_LSUB
678};
679
680static int imapdriver_list_lsub_folders(mailsession * session, int type,
681 char * mb,
682 struct mail_list ** result)
683{
684 clist * imap_list;
685 struct mail_list * resp;
686 int r;
687 int res;
688
689 switch (type) {
690 case IMAP_LIST:
691 r = mailimap_list(get_imap_session(session), mb,
692 "*", &imap_list);
693 break;
694 case IMAP_LSUB:
695 r = mailimap_lsub(get_imap_session(session), mb,
696 "*", &imap_list);
697 break;
698 default:
699 res = MAIL_ERROR_LIST;
700 goto err;
701 }
702
703 switch (r) {
704 case MAILIMAP_NO_ERROR:
705 break;
706 default:
707 res = imap_error_to_mail_error(r);
708 goto err;
709 }
710
711 r = imap_list_to_list(imap_list, &resp);
712 if (r != MAIL_NO_ERROR) {
713 mailimap_list_result_free(imap_list);
714 res = r;
715 goto err;
716 }
717
718 mailimap_list_result_free(imap_list);
719
720 * result = resp;
721
722 return MAIL_NO_ERROR;
723
724 err:
725 return res;
726}
727
728static int imapdriver_list_folders(mailsession * session, char * mb,
729 struct mail_list ** result)
730{
731 return imapdriver_list_lsub_folders(session, IMAP_LIST, mb,
732 result);
733}
734
735static int imapdriver_lsub_folders(mailsession * session, char * mb,
736 struct mail_list ** result)
737{
738 return imapdriver_list_lsub_folders(session, IMAP_LSUB, mb,
739 result);
740}
741
742static int imapdriver_subscribe_folder(mailsession * session, char * mb)
743{
744 int r;
745
746 r = mailimap_subscribe(get_imap_session(session), mb);
747
748 return imap_error_to_mail_error(r);
749}
750
751static int imapdriver_unsubscribe_folder(mailsession * session, char * mb)
752{
753 int r;
754
755 r = mailimap_unsubscribe(get_imap_session(session), mb);
756
757 return imap_error_to_mail_error(r);
758}
759
760/* messages operations */
761
762static int imapdriver_append_message(mailsession * session,
763 char * message, size_t size)
764{
765 int r;
766
767 r = mailimap_append_simple(get_imap_session(session),
768 get_data(session)->imap_mailbox,
769 message, size);
770
771 return imap_error_to_mail_error(r);
772}
773
774static int imapdriver_copy_message(mailsession * session,
775 uint32_t num, char * mb)
776{
777 int r;
778 struct mailimap_set * set;
779 int res;
780
781 set = mailimap_set_new_single(num);
782 if (set == NULL) {
783 res = MAIL_ERROR_MEMORY;
784 goto err;
785 }
786
787 r = mailimap_uid_copy(get_imap_session(session), set, mb);
788
789 mailimap_set_free(set);
790
791 return imap_error_to_mail_error(r);
792
793 err:
794 return res;
795}
796
797static int imapdriver_get_messages_list(mailsession * session,
798 struct mailmessage_list ** result)
799{
800 return imap_get_messages_list(get_imap_session(session),
801 session, imap_message_driver, 1,
802 result);
803}
804
805
806
807static int
808imapdriver_get_envelopes_list(mailsession * session,
809 struct mailmessage_list * env_list)
810{
811 struct mailimap_set * set;
812 struct mailimap_fetch_att * fetch_att;
813 struct mailimap_fetch_type * fetch_type;
814 int res;
815 clist * fetch_result;
816 int r;
817 uint32_t exists;
818 clist * msg_list;
819
820 if (get_imap_session(session)->imap_selection_info == NULL) {
821 res = MAIL_ERROR_BAD_STATE;
822 goto err;
823 }
824
825 imap_flags_store_process(get_imap_session(session),
826 get_data(session)->imap_flags_store);
827
828 exists = get_imap_session(session)->imap_selection_info->sel_exists;
829
830 if (exists == 0)
831 return MAIL_NO_ERROR;
832
833 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
834 if (fetch_type == NULL) {
835 res = MAIL_ERROR_MEMORY;
836 goto err;
837 }
838
839 fetch_att = mailimap_fetch_att_new_uid();
840 if (fetch_att == NULL) {
841 res = MAIL_ERROR_MEMORY;
842 goto free_fetch_type;
843 }
844
845 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
846 if (r != MAILIMAP_NO_ERROR) {
847 mailimap_fetch_att_free(fetch_att);
848 res = MAIL_ERROR_MEMORY;
849 goto free_fetch_type;
850 }
851
852 fetch_att = mailimap_fetch_att_new_flags();
853 if (fetch_att == NULL) {
854 res = MAIL_ERROR_MEMORY;
855 goto free_fetch_type;
856 }
857
858 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
859 if (r != MAILIMAP_NO_ERROR) {
860 mailimap_fetch_att_free(fetch_att);
861 res = MAIL_ERROR_MEMORY;
862 goto free_fetch_type;
863 }
864
865 r = imap_add_envelope_fetch_att(fetch_type);
866 if (r != MAIL_NO_ERROR) {
867 res = r;
868 goto free_fetch_type;
869 }
870
871 r = maildriver_env_list_to_msg_list(env_list, &msg_list);
872 if (r != MAIL_NO_ERROR) {
873 res = MAIL_ERROR_MEMORY;
874 goto free_fetch_type;
875 }
876
877 if (clist_begin(msg_list) == NULL) {
878 /* no need to fetch envelopes */
879
880 mailimap_fetch_type_free(fetch_type);
881 clist_free(msg_list);
882 return MAIL_NO_ERROR;
883 }
884
885 r = msg_list_to_imap_set(msg_list, &set);
886 if (r != MAIL_NO_ERROR) {
887 clist_foreach(msg_list, (clist_func) free, NULL);
888 clist_free(msg_list);
889 res = MAIL_ERROR_MEMORY;
890 goto free_fetch_type;
891 }
892 clist_foreach(msg_list, (clist_func) free, NULL);
893 clist_free(msg_list);
894
895 r = mailimap_uid_fetch(get_imap_session(session), set,
896 fetch_type, &fetch_result);
897
898 mailimap_fetch_type_free(fetch_type);
899 mailimap_set_free(set);
900
901 switch (r) {
902 case MAILIMAP_NO_ERROR:
903 break;
904 default:
905 return imap_error_to_mail_error(r);
906 }
907
908 if (clist_begin(fetch_result) == NULL) {
909 res = MAIL_ERROR_FETCH;
910 goto err;
911 }
912
913 r = imap_fetch_result_to_envelop_list(fetch_result, env_list);
914 mailimap_fetch_list_free(fetch_result);
915
916 if (r != MAIL_NO_ERROR) {
917 res = MAIL_ERROR_MEMORY;
918 goto err;
919 }
920
921 return MAIL_NO_ERROR;
922
923 free_fetch_type:
924 mailimap_fetch_type_free(fetch_type);
925 err:
926 return res;
927}
928
929
930#if 0
931static int imapdriver_search_messages(mailsession * session, char * charset,
932 struct mail_search_key * key,
933 struct mail_search_result ** result)
934{
935 struct mailimap_search_key * imap_key;
936 int r;
937 clist * imap_result;
938 clist * result_list;
939 struct mail_search_result * search_result;
940 clistiter * cur;
941
942 r = mail_search_to_imap_search(key, &imap_key);
943 if (r != MAIL_NO_ERROR)
944 return MAIL_ERROR_MEMORY;
945
946 r = mailimap_uid_search(get_imap_session(session), charset, imap_key,
947 &imap_result);
948
949 mailimap_search_key_free(imap_key);
950
951 switch (r) {
952 case MAILIMAP_NO_ERROR:
953 break;
954 default:
955 return imap_error_to_mail_error(r);
956 }
957
958 result_list = clist_new();
959 if (result_list == NULL)
960 return MAIL_ERROR_MEMORY;
961
962 for(cur = clist_begin(imap_result) ; cur != NULL ; cur = clist_next(cur)) {
963 uint32_t val = * (uint32_t *) clist_content(cur);
964 uint32_t * new;
965
966 new = malloc(sizeof(* new));
967 if (new == NULL) {
968 goto free_imap_result;
969 }
970
971 * new = val;
972
973 r = clist_append(result_list, new);
974 if (r != 0) {
975 free(new);
976 goto free_imap_result;
977 }
978 }
979
980 search_result = mail_search_result_new(result_list);
981 if (search_result == NULL)
982 goto free_imap_result;
983
984 mailimap_search_result_free(imap_result);
985
986 * result = search_result;
987
988 return MAIL_NO_ERROR;
989
990 free_imap_result:
991 mailimap_search_result_free(imap_result);
992 return MAIL_ERROR_MEMORY;
993}
994#endif
995
996static int imapdriver_starttls(mailsession * session)
997{
998 mailimap * imap;
999 int r;
1000 struct mailimap_capability_data * cap_data;
1001 clistiter * cur;
1002 int starttls;
1003 int fd;
1004 mailstream_low * low;
1005 mailstream_low * new_low;
1006 int capability_available;
1007
1008 imap = get_imap_session(session);
1009
1010 capability_available = FALSE;
1011 if (imap->imap_connection_info != NULL)
1012 if (imap->imap_connection_info->imap_capability != NULL) {
1013 capability_available = TRUE;
1014 cap_data = imap->imap_connection_info->imap_capability;
1015 }
1016
1017 if (!capability_available) {
1018 r = mailimap_capability(imap, &cap_data);
1019 switch (r) {
1020 case MAILIMAP_NO_ERROR:
1021 break;
1022 default:
1023 return imap_error_to_mail_error(r);
1024 }
1025 }
1026
1027 starttls = FALSE;
1028 for(cur = clist_begin(cap_data->cap_list) ; cur != NULL ;
1029 cur = clist_next(cur)) {
1030 struct mailimap_capability * cap;
1031
1032 cap = clist_content(cur);
1033
1034 if (cap->cap_type == MAILIMAP_CAPABILITY_NAME)
1035 if (strcasecmp(cap->cap_data.cap_name, "STARTTLS") == 0) {
1036 starttls = TRUE;
1037 break;
1038 }
1039 }
1040
1041 if (!capability_available)
1042 mailimap_capability_data_free(cap_data);
1043
1044 if (!starttls)
1045 return MAIL_ERROR_NO_TLS;
1046
1047 r = mailimap_starttls(imap);
1048
1049 switch (r) {
1050 case MAILIMAP_NO_ERROR:
1051 break;
1052 default:
1053 return imap_error_to_mail_error(r);
1054 }
1055
1056 low = mailstream_get_low(imap->imap_stream);
1057 fd = mailstream_low_get_fd(low);
1058 if (fd == -1)
1059 return MAIL_ERROR_STREAM;
1060
1061 new_low = mailstream_low_ssl_open(fd);
1062 if (new_low == NULL)
1063 return MAIL_ERROR_STREAM;
1064
1065 mailstream_low_free(low);
1066 mailstream_set_low(imap->imap_stream, new_low);
1067
1068 return MAIL_NO_ERROR;
1069}
1070
1071static int imapdriver_get_message(mailsession * session,
1072 uint32_t num, mailmessage ** result)
1073{
1074 mailmessage * msg_info;
1075 int r;
1076
1077 msg_info = mailmessage_new();
1078 if (msg_info == NULL)
1079 return MAIL_ERROR_MEMORY;
1080
1081 r = mailmessage_init(msg_info, session, imap_message_driver, num, 0);
1082 if (r != MAIL_NO_ERROR) {
1083 mailmessage_free(msg_info);
1084 return r;
1085 }
1086
1087 * result = msg_info;
1088
1089 return MAIL_NO_ERROR;
1090}
1091
1092/* Retrieve a message by UID
1093
1094 libEtPan! uid format for IMAP is "UIDVALIDITY-UID"
1095 where UIDVALIDITY and UID are decimal representation of
1096 respectively uidvalidity and uid numbers.
1097
1098 Return value:
1099 MAIL_ERROR_INVAL if uid is NULL or has an incorrect format.
1100 MAIL_ERROR_MSG_NOT_FOUND if uidvalidity has changed or uid was not found
1101 MAIL_NO_ERROR if message was found. Result is in result
1102*/
1103
1104static int imapdriver_get_message_by_uid(mailsession * session,
1105 const char * uid,
1106 mailmessage ** result)
1107{
1108 uint32_t uidvalidity;
1109 uint32_t num;
1110 char * p1, * p2;
1111 mailimap * imap;
1112
1113 if (uid == NULL)
1114 return MAIL_ERROR_INVAL;
1115
1116 uidvalidity = strtoul(uid, &p1, 10);
1117 if (p1 == uid || * p1 != '-')
1118 return MAIL_ERROR_INVAL;
1119
1120 p1++;
1121 num = strtoul(p1, &p2, 10);
1122 if (p2 == p1 || * p2 != '\0')
1123 return MAIL_ERROR_INVAL;
1124
1125 imap = get_imap_session(session);
1126 if (imap->imap_selection_info->sel_uidvalidity != uidvalidity)
1127 return MAIL_ERROR_MSG_NOT_FOUND;
1128
1129 return imapdriver_get_message(session, num, result);
1130}
diff --git a/kmicromail/libetpan/generic/imapdriver.h b/kmicromail/libetpan/generic/imapdriver.h
new file mode 100644
index 0000000..2bf36c7
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver.h
@@ -0,0 +1,52 @@
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#ifndef IMAPDRIVER_H
37
38#define IMAPDRIVER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/imapdriver_types.h>
45
46extern mailsession_driver * imap_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_cached.c b/kmicromail/libetpan/generic/imapdriver_cached.c
new file mode 100644
index 0000000..e6af8e8
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached.c
@@ -0,0 +1,1274 @@
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 "imapdriver_cached.h"
37
38#include "libetpan-config.h"
39
40#include <stdio.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <fcntl.h>
44#include <string.h>
45#include <unistd.h>
46#include <stdlib.h>
47
48#include "mail.h"
49#include "imapdriver_tools.h"
50#include "mail_cache_db.h"
51#include "mailmessage.h"
52#include "imapdriver_cached_message.h"
53#include "maildriver.h"
54#include "imapdriver_types.h"
55#include "generic_cache.h"
56#include "imfcache.h"
57#include "maildriver_tools.h"
58#include "imapdriver.h"
59
60static int imapdriver_cached_initialize(mailsession * session);
61static void imapdriver_cached_uninitialize(mailsession * session);
62
63static int imapdriver_cached_parameters(mailsession * session,
64 int id, void * value);
65
66static int imapdriver_cached_connect_stream(mailsession * session,
67 mailstream * s);
68
69static int imapdriver_cached_starttls(mailsession * session);
70
71static int imapdriver_cached_login(mailsession * session,
72 char * userid, char * password);
73static int imapdriver_cached_logout(mailsession * session);
74static int imapdriver_cached_noop(mailsession * session);
75static int imapdriver_cached_build_folder_name(mailsession * session,
76 char * mb,
77 char * name, char ** result);
78static int imapdriver_cached_create_folder(mailsession * session, char * mb);
79static int imapdriver_cached_delete_folder(mailsession * session, char * mb);
80static int imapdriver_cached_rename_folder(mailsession * session, char * mb,
81 char * new_name);
82static int imapdriver_cached_check_folder(mailsession * session);
83static int imapdriver_cached_examine_folder(mailsession * session,
84 char * mb);
85static int imapdriver_cached_select_folder(mailsession * session, char * mb);
86static int imapdriver_cached_expunge_folder(mailsession * session);
87static int imapdriver_cached_status_folder(mailsession * session, char * mb,
88 uint32_t * result_messages,
89 uint32_t * result_recent,
90 uint32_t * result_unseen);
91static int imapdriver_cached_messages_number(mailsession * session,
92 char * mb,
93 uint32_t * result);
94static int imapdriver_cached_recent_number(mailsession * session, char * mb,
95 uint32_t * result);
96static int imapdriver_cached_unseen_number(mailsession * session, char * mb,
97 uint32_t * result);
98static int imapdriver_cached_list_folders(mailsession * session, char * mb,
99 struct mail_list ** result);
100static int imapdriver_cached_lsub_folders(mailsession * session, char * mb,
101 struct mail_list ** result);
102static int imapdriver_cached_subscribe_folder(mailsession * session,
103 char * mb);
104static int imapdriver_cached_unsubscribe_folder(mailsession * session,
105 char * mb);
106static int imapdriver_cached_append_message(mailsession * session,
107 char * message, size_t size);
108static int imapdriver_cached_copy_message(mailsession * session,
109 uint32_t num, char * mb);
110
111static int imapdriver_cached_get_messages_list(mailsession * session,
112 struct mailmessage_list **
113 result);
114static int
115imapdriver_cached_get_envelopes_list(mailsession * session,
116 struct mailmessage_list * env_list);
117static int imapdriver_cached_remove_message(mailsession * session,
118 uint32_t num);
119
120#if 0
121static int imapdriver_cached_search_messages(mailsession * session,
122 char * charset,
123 struct mail_search_key * key,
124 struct mail_search_result **
125 result);
126#endif
127
128static int imapdriver_cached_get_message(mailsession * session,
129 uint32_t num, mailmessage ** result);
130
131static int imapdriver_cached_get_message_by_uid(mailsession * session,
132 const char * uid,
133 mailmessage ** result);
134
135static mailsession_driver local_imap_cached_session_driver = {
136 .sess_name = "imap-cached",
137
138 .sess_initialize = imapdriver_cached_initialize,
139 .sess_uninitialize = imapdriver_cached_uninitialize,
140
141 .sess_parameters = imapdriver_cached_parameters,
142
143 .sess_connect_stream = imapdriver_cached_connect_stream,
144 .sess_connect_path = NULL,
145 .sess_starttls = imapdriver_cached_starttls,
146 .sess_login = imapdriver_cached_login,
147 .sess_logout = imapdriver_cached_logout,
148 .sess_noop = imapdriver_cached_noop,
149
150 .sess_build_folder_name = imapdriver_cached_build_folder_name,
151 .sess_create_folder = imapdriver_cached_create_folder,
152 .sess_delete_folder = imapdriver_cached_delete_folder,
153 .sess_rename_folder = imapdriver_cached_rename_folder,
154 .sess_check_folder = imapdriver_cached_check_folder,
155 .sess_examine_folder = imapdriver_cached_examine_folder,
156 .sess_select_folder = imapdriver_cached_select_folder,
157 .sess_expunge_folder = imapdriver_cached_expunge_folder,
158 .sess_status_folder = imapdriver_cached_status_folder,
159 .sess_messages_number = imapdriver_cached_messages_number,
160 .sess_recent_number = imapdriver_cached_recent_number,
161 .sess_unseen_number = imapdriver_cached_unseen_number,
162 .sess_list_folders = imapdriver_cached_list_folders,
163 .sess_lsub_folders = imapdriver_cached_lsub_folders,
164 .sess_subscribe_folder = imapdriver_cached_subscribe_folder,
165 .sess_unsubscribe_folder = imapdriver_cached_unsubscribe_folder,
166
167 .sess_append_message = imapdriver_cached_append_message,
168 .sess_copy_message = imapdriver_cached_copy_message,
169 .sess_move_message = NULL,
170
171 .sess_get_messages_list = imapdriver_cached_get_messages_list,
172 .sess_get_envelopes_list = imapdriver_cached_get_envelopes_list,
173 .sess_remove_message = imapdriver_cached_remove_message,
174#if 0
175 .sess_search_messages = imapdriver_cached_search_messages,
176#endif
177
178 .sess_get_message = imapdriver_cached_get_message,
179 .sess_get_message_by_uid = imapdriver_cached_get_message_by_uid,
180};
181
182mailsession_driver * imap_cached_session_driver =
183&local_imap_cached_session_driver;
184
185#define CACHE_MESSAGE_LIST
186
187static inline struct imap_cached_session_state_data *
188get_cached_data(mailsession * session)
189{
190 return session->sess_data;
191}
192
193static inline mailsession * get_ancestor(mailsession * s)
194{
195 return get_cached_data(s)->imap_ancestor;
196}
197
198static inline
199struct imap_session_state_data * get_ancestor_data(mailsession * s)
200{
201 return get_ancestor(s)->sess_data;
202}
203
204static inline mailimap * get_imap_session(mailsession * session)
205{
206 return get_ancestor_data(session)->imap_session;
207}
208
209static int imapdriver_cached_initialize(mailsession * session)
210{
211 struct imap_cached_session_state_data * data;
212
213 data = malloc(sizeof(* data));
214 if (data == NULL)
215 goto err;
216
217 data->imap_ancestor = mailsession_new(imap_session_driver);
218 if (data->imap_ancestor == NULL)
219 goto free_data;
220 data->imap_quoted_mb = NULL;
221 data->imap_cache_directory[0] = '\0';
222 data->imap_uid_list = carray_new(128);
223 if (data->imap_uid_list == NULL)
224 goto free_session;
225
226 session->sess_data = data;
227
228 return MAIL_NO_ERROR;
229
230 free_session:
231 mailsession_free(data->imap_ancestor);
232 free_data:
233 free(data);
234 err:
235 return MAIL_ERROR_MEMORY;
236}
237
238static void
239free_quoted_mb(struct imap_cached_session_state_data * imap_cached_data)
240{
241 if (imap_cached_data->imap_quoted_mb != NULL) {
242 free(imap_cached_data->imap_quoted_mb);
243 imap_cached_data->imap_quoted_mb = NULL;
244 }
245}
246
247struct uid_cache_item {
248 uint32_t uid;
249 uint32_t size;
250};
251
252static int update_uid_cache(mailsession * session,
253 struct mailmessage_list * env_list)
254{
255 unsigned int i;
256 int r;
257 struct imap_cached_session_state_data * data;
258 int res;
259
260 data = get_cached_data(session);
261
262 /* free all UID cache */
263 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
264 struct uid_cache_item * cache_item;
265
266 cache_item = carray_get(data->imap_uid_list, i);
267 free(cache_item);
268 }
269
270 /* build UID cache */
271 r = carray_set_size(data->imap_uid_list,
272 carray_count(env_list->msg_tab));
273 if (r < 0) {
274 res = MAIL_ERROR_MEMORY;
275 goto err;
276 }
277
278 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
279 struct uid_cache_item * cache_item;
280 mailmessage * msg;
281
282 cache_item = malloc(sizeof(* cache_item));
283 if (cache_item == NULL) {
284 res = MAIL_ERROR_MEMORY;
285 goto err;
286 }
287 msg = carray_get(env_list->msg_tab, i);
288 cache_item->uid = msg->msg_index;
289 cache_item->size = msg->msg_size;
290
291 carray_set(data->imap_uid_list, i, cache_item);
292 }
293
294 return MAIL_NO_ERROR;
295
296 err:
297 return res;
298}
299
300static void check_for_uid_cache(mailsession * session)
301{
302#if 0
303 mailsession * imap;
304#endif
305 mailimap * imap;
306#if 0
307 struct imap_session_state_data * imap_data;
308#endif
309 clist * list;
310 clistiter * cur;
311 struct imap_cached_session_state_data * data;
312 unsigned int i;
313 unsigned dest;
314
315 data = get_cached_data(session);
316#if 0
317 imap = get_ancestor(session);
318
319 imap_data = imap->data;
320#endif
321
322 imap = get_imap_session(session);
323
324 if (imap->imap_response_info == NULL)
325 return;
326
327 list = imap->imap_response_info->rsp_expunged;
328 if (list == NULL)
329 return;
330
331 dest = 0;
332 i = 0;
333 /* remove expunged */
334 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
335 uint32_t expunged;
336
337 expunged = * (uint32_t *) clist_content(cur);
338
339 while (i < carray_count(data->imap_uid_list)) {
340 struct uid_cache_item * cache_item;
341
342 if (dest + 1 == expunged) {
343 cache_item = carray_get(data->imap_uid_list, i);
344 free(cache_item);
345 i ++;
346 break;
347 }
348 else {
349 cache_item = carray_get(data->imap_uid_list, i);
350 carray_set(data->imap_uid_list, dest, cache_item);
351 i ++;
352 dest ++;
353 }
354 }
355 }
356 /* complete list */
357 while (i < carray_count(data->imap_uid_list)) {
358 struct uid_cache_item * cache_item;
359
360 cache_item = carray_get(data->imap_uid_list, i);
361 carray_set(data->imap_uid_list, dest, cache_item);
362 i ++;
363 dest ++;
364 }
365 carray_set_size(data->imap_uid_list, dest);
366}
367
368static void imapdriver_cached_uninitialize(mailsession * session)
369{
370 struct imap_cached_session_state_data * data;
371 unsigned int i;
372
373 data = get_cached_data(session);
374
375 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
376 struct uid_cache_item * cache_item;
377
378 cache_item = carray_get(data->imap_uid_list, i);
379 free(cache_item);
380 }
381 carray_free(data->imap_uid_list);
382 free_quoted_mb(data);
383 mailsession_free(data->imap_ancestor);
384 free(data);
385
386 session->sess_data = NULL;
387}
388
389
390static int imapdriver_cached_parameters(mailsession * session,
391 int id, void * value)
392{
393 struct imap_cached_session_state_data * data;
394 int r;
395
396 data = get_cached_data(session);
397
398 switch (id) {
399 case IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY:
400 strncpy(data->imap_cache_directory, value, PATH_MAX);
401 data->imap_cache_directory[PATH_MAX - 1] = '\0';
402
403 r = generic_cache_create_dir(data->imap_cache_directory);
404 if (r != MAIL_NO_ERROR)
405 return r;
406
407 return MAIL_NO_ERROR;
408 }
409
410 return MAIL_ERROR_INVAL;
411}
412
413
414static int imapdriver_cached_connect_stream(mailsession * session,
415 mailstream * s)
416{
417 int r;
418
419 check_for_uid_cache(session);
420
421 r = mailsession_connect_stream(get_ancestor(session), s);
422
423 check_for_uid_cache(session);
424
425 return r;
426}
427
428static int imapdriver_cached_starttls(mailsession * session)
429{
430 int r;
431
432 r = mailsession_starttls(get_ancestor(session));
433
434 check_for_uid_cache(session);
435
436 return r;
437}
438
439static int imapdriver_cached_login(mailsession * session,
440 char * userid, char * password)
441{
442 int r;
443
444 r = mailsession_login(get_ancestor(session), userid, password);
445
446 check_for_uid_cache(session);
447
448 return r;
449}
450
451static int imapdriver_cached_logout(mailsession * session)
452{
453 int r;
454
455 r = mailsession_logout(get_ancestor(session));
456
457 check_for_uid_cache(session);
458
459 if (r == MAIL_NO_ERROR) {
460 struct imap_cached_session_state_data * imap_cached_data;
461
462 imap_cached_data = get_cached_data(session);
463
464 free_quoted_mb(imap_cached_data);
465 }
466
467 return r;
468}
469
470static int imapdriver_cached_noop(mailsession * session)
471{
472 int r;
473
474 r = mailsession_noop(get_ancestor(session));
475
476 check_for_uid_cache(session);
477
478 return r;
479}
480
481static int imapdriver_cached_build_folder_name(mailsession * session,
482 char * mb,
483 char * name, char ** result)
484{
485 int r;
486
487 r = mailsession_build_folder_name(get_ancestor(session), mb,
488 name, result);
489
490 check_for_uid_cache(session);
491
492 return r;
493}
494
495static int imapdriver_cached_create_folder(mailsession * session, char * mb)
496{
497 int r;
498
499 r = mailsession_create_folder(get_ancestor(session), mb);
500
501 check_for_uid_cache(session);
502
503 return r;
504}
505
506static int imapdriver_cached_delete_folder(mailsession * session, char * mb)
507{
508 int r;
509
510 r = mailsession_delete_folder(get_ancestor(session), mb);
511
512 check_for_uid_cache(session);
513
514 return r;
515}
516
517static int imapdriver_cached_rename_folder(mailsession * session, char * mb,
518 char * new_name)
519{
520 int r;
521
522 r = mailsession_rename_folder(get_ancestor(session), mb, new_name);
523
524 check_for_uid_cache(session);
525
526 return r;
527}
528
529static int imapdriver_cached_check_folder(mailsession * session)
530{
531 int r;
532
533 r = mailsession_check_folder(get_ancestor(session));
534
535 check_for_uid_cache(session);
536
537 return r;
538}
539
540static int imapdriver_cached_examine_folder(mailsession * session,
541 char * mb)
542{
543 int r;
544
545 r = mailsession_examine_folder(get_ancestor(session), mb);
546
547 check_for_uid_cache(session);
548
549 return r;
550}
551
552static int get_cache_folder(mailsession * session, char ** result)
553{
554#if 0
555 mailsession * imap_session;
556#endif
557 mailimap * imap;
558 char * mb;
559 char * cache_dir;
560 char * dirname;
561 char * quoted_mb;
562 int res;
563 int r;
564 char key[PATH_MAX];
565#if 0
566 struct imap_session_state_data * imap_data;
567 struct imap_cached_session_state_data * cached_data;
568#endif
569
570#if 0
571 imap_session = get_ancestor(session);
572 imap_data = imap_session->data;
573 imap = imap_data->session;
574#endif
575 imap = get_imap_session(session);
576
577 mb = get_ancestor_data(session)->imap_mailbox;
578
579 cache_dir = get_cached_data(session)->imap_cache_directory;
580
581 if (imap->imap_state != MAILIMAP_STATE_SELECTED)
582 return MAIL_ERROR_BAD_STATE;
583
584 if (imap->imap_selection_info == NULL)
585 return MAIL_ERROR_BAD_STATE;
586
587 quoted_mb = maildriver_quote_mailbox(mb);
588 if (quoted_mb == NULL) {
589 res = MAIL_ERROR_MEMORY;
590 goto err;
591 }
592
593 snprintf(key, PATH_MAX, "%s/%s", cache_dir, quoted_mb);
594
595 dirname = strdup(key);
596 if (dirname == NULL) {
597 res = MAIL_ERROR_MEMORY;
598 goto free_mb;
599 }
600
601 r = generic_cache_create_dir(dirname);
602 if (r != MAIL_NO_ERROR) {
603 res = r;
604 goto free_dirname;
605 }
606
607 free(quoted_mb);
608
609 * result = dirname;
610
611 return MAIL_NO_ERROR;
612
613 free_dirname:
614 free(dirname);
615 free_mb:
616 free(quoted_mb);
617 err:
618 return res;
619}
620
621static int imapdriver_cached_select_folder(mailsession * session, char * mb)
622{
623 int r;
624 char * quoted_mb;
625 struct imap_cached_session_state_data * data;
626 mailsession * imap;
627 char * old_mb;
628
629 imap = get_ancestor(session);
630
631 old_mb = get_ancestor_data(session)->imap_mailbox;
632 if (old_mb != NULL)
633 if (strcmp(mb, old_mb) == 0)
634 return MAIL_NO_ERROR;
635
636 r = mailsession_select_folder(get_ancestor(session), mb);
637 if (r != MAIL_NO_ERROR)
638 return r;
639
640 check_for_uid_cache(session);
641
642 r = get_cache_folder(session, &quoted_mb);
643 if (r != MAIL_NO_ERROR)
644 return r;
645
646 data = get_cached_data(session);
647 if (data->imap_quoted_mb != NULL)
648 free(data->imap_quoted_mb);
649 data->imap_quoted_mb = quoted_mb;
650
651 /* clear UID cache */
652 carray_set_size(data->imap_uid_list, 0);
653
654 return MAIL_NO_ERROR;
655}
656
657static int imapdriver_cached_expunge_folder(mailsession * session)
658{
659 int r;
660
661 r = mailsession_expunge_folder(get_ancestor(session));
662
663 check_for_uid_cache(session);
664
665 return r;
666}
667
668static int imapdriver_cached_status_folder(mailsession * session, char * mb,
669 uint32_t * result_messages, uint32_t * result_recent,
670 uint32_t * result_unseen)
671{
672 int r;
673
674 r = mailsession_status_folder(get_ancestor(session), mb, result_messages,
675 result_recent, result_unseen);
676
677 check_for_uid_cache(session);
678
679 return r;
680}
681
682static int imapdriver_cached_messages_number(mailsession * session,
683 char * mb,
684 uint32_t * result)
685{
686 int r;
687
688 r = mailsession_messages_number(get_ancestor(session), mb, result);
689
690 check_for_uid_cache(session);
691
692 return r;
693}
694
695static int imapdriver_cached_recent_number(mailsession * session, char * mb,
696 uint32_t * result)
697{
698 int r;
699
700 r = mailsession_recent_number(get_ancestor(session), mb, result);
701
702 check_for_uid_cache(session);
703
704 return r;
705}
706
707static int imapdriver_cached_unseen_number(mailsession * session, char * mb,
708 uint32_t * result)
709{
710 int r;
711
712 r = mailsession_unseen_number(get_ancestor(session), mb, result);
713
714 check_for_uid_cache(session);
715
716 return r;
717}
718
719static int imapdriver_cached_list_folders(mailsession * session, char * mb,
720 struct mail_list ** result)
721{
722 int r;
723
724 r = mailsession_list_folders(get_ancestor(session), mb, result);
725
726 check_for_uid_cache(session);
727
728 return r;
729}
730
731static int imapdriver_cached_lsub_folders(mailsession * session, char * mb,
732 struct mail_list ** result)
733{
734 int r;
735
736 r = mailsession_lsub_folders(get_ancestor(session), mb, result);
737
738 check_for_uid_cache(session);
739
740 return r;
741}
742
743static int imapdriver_cached_subscribe_folder(mailsession * session,
744 char * mb)
745{
746 int r;
747
748 r = mailsession_subscribe_folder(get_ancestor(session), mb);
749
750 check_for_uid_cache(session);
751
752 return r;
753}
754
755static int imapdriver_cached_unsubscribe_folder(mailsession * session,
756 char * mb)
757{
758 int r;
759
760 r = mailsession_unsubscribe_folder(get_ancestor(session), mb);
761
762 check_for_uid_cache(session);
763
764 return r;
765}
766
767static int imapdriver_cached_append_message(mailsession * session,
768 char * message, size_t size)
769{
770 int r;
771
772 r = mailsession_append_message(get_ancestor(session), message, size);
773
774 check_for_uid_cache(session);
775
776 return r;
777}
778
779static int imapdriver_cached_copy_message(mailsession * session,
780 uint32_t num, char * mb)
781{
782 int r;
783
784 r = mailsession_copy_message(get_ancestor(session), num, mb);
785
786 check_for_uid_cache(session);
787
788 return r;
789}
790
791static int cmp_uid(uint32_t ** pa, uint32_t ** pb)
792{
793 uint32_t * a;
794 uint32_t * b;
795
796 a = * pa;
797 b = * pb;
798
799 return * a - * b;
800}
801
802
803static int imapdriver_cached_get_messages_list(mailsession * session,
804 struct mailmessage_list **
805 result)
806{
807#if 0
808 mailsession * imap_session;
809#endif
810 mailimap * imap;
811 uint32_t uid_max;
812 struct imap_cached_session_state_data * data;
813 struct mailmessage_list * env_list;
814 unsigned i;
815 int r;
816 int res;
817 carray * tab;
818
819#if 0
820 data = session->data;
821 imap_session = get_ancestor(session);
822 imap = ((struct imap_session_state_data *) (imap_session->data))->session;
823#endif
824 data = get_cached_data(session);
825 imap = get_imap_session(session);
826
827 uid_max = 0;
828
829#ifdef CACHE_MESSAGE_LIST
830 /* get UID max */
831 uid_max = 0;
832 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
833 struct uid_cache_item * cache_item;
834
835 cache_item = carray_get(data->imap_uid_list, i);
836 if (cache_item->uid > uid_max)
837 uid_max = cache_item->uid;
838 }
839#endif
840
841 r = imap_get_messages_list(imap, session, imap_cached_message_driver,
842 uid_max + 1, &env_list);
843
844 check_for_uid_cache(session);
845
846 if (r != MAIL_NO_ERROR) {
847 res = r;
848 goto err;
849 }
850
851#ifdef CACHE_MESSAGE_LIST
852 /* remove unsollicited message */
853 i = 0;
854 while (i < carray_count(env_list->msg_tab)) {
855 mailmessage * msg;
856
857 msg = carray_get(env_list->msg_tab, i);
858 if (msg->msg_index < uid_max + 1)
859 carray_delete(env_list->msg_tab, i);
860 else
861 i ++;
862 }
863
864 tab = carray_new(carray_count(env_list->msg_tab) +
865 carray_count(data->imap_uid_list));
866 if (tab == NULL) {
867 res = MAIL_ERROR_MEMORY;
868 goto free;
869 }
870 carray_set_size(tab,
871 carray_count(env_list->msg_tab) + carray_count(data->imap_uid_list));
872
873 /* sort cached data before adding them to the list */
874 qsort(carray_data(data->imap_uid_list), carray_count(data->imap_uid_list),
875 sizeof(* carray_data(data->imap_uid_list)),
876 (int (*)(const void *, const void *)) cmp_uid);
877
878 /* adds cached UID */
879 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
880 struct uid_cache_item * cache_item;
881 mailmessage * msg;
882
883 cache_item = carray_get(data->imap_uid_list, i);
884
885 msg = mailmessage_new();
886 if (msg == NULL) {
887 res = MAIL_ERROR_MEMORY;
888 goto free;
889 }
890
891 r = mailmessage_init(msg, session, imap_cached_message_driver,
892 cache_item->uid, cache_item->size);
893 if (r != MAIL_NO_ERROR) {
894 mailmessage_free(msg);
895 res = r;
896 goto free;
897 }
898
899 carray_set(tab, i, msg);
900 }
901
902 /* adds new elements */
903 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
904 mailmessage * msg;
905
906 msg = carray_get(env_list->msg_tab, i);
907 carray_set(tab, carray_count(data->imap_uid_list) + i, msg);
908 }
909
910 /* replace list of messages in env_list */
911 carray_free(env_list->msg_tab);
912 env_list->msg_tab = tab;
913
914 r = update_uid_cache(session, env_list);
915 if (r != MAIL_NO_ERROR) {
916 res = r;
917 goto free;
918 }
919#endif
920
921 * result = env_list;
922
923 return MAIL_NO_ERROR;
924
925 free:
926 mailmessage_list_free(env_list);
927 err:
928 return res;
929}
930
931static int get_flags_list(mailsession * session,
932 struct mailmessage_list * env_list)
933{
934 struct mailimap_set * set;
935 struct mailimap_fetch_att * fetch_att;
936 struct mailimap_fetch_type * fetch_type;
937 int res;
938 clist * fetch_result;
939 int r;
940 clist * msg_list;
941#if 0
942 struct imap_session_state_data * data;
943#endif
944 unsigned i;
945 unsigned dest;
946
947#if 0
948 data = session->data;
949#endif
950
951 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
952 if (fetch_type == NULL) {
953 res = MAIL_ERROR_MEMORY;
954 goto err;
955 }
956
957 fetch_att = mailimap_fetch_att_new_uid();
958 if (fetch_att == NULL) {
959 res = MAIL_ERROR_MEMORY;
960 goto free_fetch_type;
961 }
962
963 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
964 if (r != MAILIMAP_NO_ERROR) {
965 mailimap_fetch_att_free(fetch_att);
966 res = MAIL_ERROR_MEMORY;
967 goto free_fetch_type;
968 }
969
970 fetch_att = mailimap_fetch_att_new_flags();
971 if (fetch_att == NULL) {
972 res = MAIL_ERROR_MEMORY;
973 goto free_fetch_type;
974 }
975
976 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
977 if (r != MAILIMAP_NO_ERROR) {
978 mailimap_fetch_att_free(fetch_att);
979 res = MAIL_ERROR_MEMORY;
980 goto free_fetch_type;
981 }
982
983 r = maildriver_env_list_to_msg_list_no_flags(env_list, &msg_list);
984 if (r != MAIL_NO_ERROR) {
985 res = MAIL_ERROR_MEMORY;
986 goto free_fetch_type;
987 }
988
989 if (clist_begin(msg_list) == NULL) {
990 /* no need to fetch envelopes */
991
992 clist_free(msg_list);
993 mailimap_fetch_type_free(fetch_type);
994 return MAIL_NO_ERROR;
995 }
996
997 r = msg_list_to_imap_set(msg_list, &set);
998 if (r != MAIL_NO_ERROR) {
999 clist_foreach(msg_list, (clist_func) free, NULL);
1000 clist_free(msg_list);
1001 res = MAIL_ERROR_MEMORY;
1002 goto free_fetch_type;
1003 }
1004 clist_foreach(msg_list, (clist_func) free, NULL);
1005 clist_free(msg_list);
1006
1007 r = mailimap_uid_fetch(get_imap_session(session), set,
1008 fetch_type, &fetch_result);
1009
1010 mailimap_fetch_type_free(fetch_type);
1011 mailimap_set_free(set);
1012
1013 switch (r) {
1014 case MAILIMAP_NO_ERROR:
1015 break;
1016 default:
1017 return imap_error_to_mail_error(r);
1018 }
1019
1020 r = imap_fetch_result_to_envelop_list(fetch_result, env_list);
1021 mailimap_fetch_list_free(fetch_result);
1022
1023 if (r != MAIL_NO_ERROR) {
1024 res = MAIL_ERROR_MEMORY;
1025 goto err;
1026 }
1027
1028 /* remove messages that don't have flags */
1029 i = 0;
1030 dest = 0;
1031 while (i < carray_count(env_list->msg_tab)) {
1032 mailmessage * msg;
1033
1034 msg = carray_get(env_list->msg_tab, i);
1035 if (msg->msg_flags != NULL) {
1036 carray_set(env_list->msg_tab, dest, msg);
1037 dest ++;
1038 }
1039 else {
1040 mailmessage_free(msg);
1041 }
1042 i ++;
1043 }
1044 carray_set_size(env_list->msg_tab, dest);
1045
1046 return MAIL_NO_ERROR;
1047
1048 free_fetch_type:
1049 mailimap_fetch_type_free(fetch_type);
1050 err:
1051 return res;
1052}
1053
1054
1055#define ENV_NAME "env.db"
1056
1057static void get_uid_from_filename(char * filename)
1058{
1059 char * p;
1060
1061 p = strstr(filename, "-part");
1062 if (p != NULL)
1063 * p = 0;
1064 p = strstr(filename, "-envelope");
1065 if (p != NULL)
1066 * p = 0;
1067 p = strstr(filename, "-rfc822");
1068 if (p != NULL)
1069 * p = 0;
1070}
1071
1072static int
1073imapdriver_cached_get_envelopes_list(mailsession * session,
1074 struct mailmessage_list * env_list)
1075{
1076 int r;
1077 int res;
1078 uint32_t i;
1079 struct imap_cached_session_state_data * data;
1080 MMAPString * mmapstr;
1081 struct mail_cache_db * cache_db;
1082 char filename[PATH_MAX];
1083
1084 data = get_cached_data(session);
1085 if (data->imap_quoted_mb == NULL) {
1086 res = MAIL_ERROR_BAD_STATE;
1087 goto err;
1088 }
1089
1090 mmapstr = mmap_string_new("");
1091 if (mmapstr == NULL) {
1092 res = MAIL_ERROR_MEMORY;
1093 goto err;
1094 }
1095
1096 snprintf(filename, PATH_MAX, "%s/%s", data->imap_quoted_mb, ENV_NAME);
1097
1098 r = mail_cache_db_open_lock(filename, &cache_db);
1099 if (r < 0) {
1100 res = MAIL_ERROR_MEMORY;
1101 goto free_mmapstr;
1102 }
1103
1104 /* fill with cached */
1105
1106 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1107 mailmessage * msg;
1108 struct mailimf_fields * fields;
1109
1110 msg = carray_get(env_list->msg_tab, i);
1111
1112 if (msg->msg_fields == NULL) {
1113 r = imapdriver_get_cached_envelope(cache_db, mmapstr,
1114 session, msg, &fields);
1115 if (r == MAIL_NO_ERROR) {
1116 msg->msg_cached = TRUE;
1117 msg->msg_fields = fields;
1118 }
1119 }
1120 }
1121
1122 mail_cache_db_close_unlock(filename, cache_db);
1123
1124 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
1125
1126 check_for_uid_cache(session);
1127
1128 if (r != MAIL_NO_ERROR) {
1129 res = r;
1130 goto free_mmapstr;
1131 }
1132
1133 r = get_flags_list(session, env_list);
1134
1135 if (r != MAIL_NO_ERROR) {
1136 res = r;
1137 goto free_mmapstr;
1138 }
1139
1140#ifdef CACHE_MESSAGE_LIST
1141 r = update_uid_cache(session, env_list);
1142 if (r != MAIL_NO_ERROR) {
1143 res = r;
1144 goto free_mmapstr;
1145 }
1146#endif
1147
1148 /* must write cache */
1149
1150 r = mail_cache_db_open_lock(filename, &cache_db);
1151 if (r < 0) {
1152 res = MAIL_ERROR_MEMORY;
1153 goto free_mmapstr;
1154 }
1155
1156 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1157 mailmessage * msg;
1158
1159 msg = carray_get(env_list->msg_tab, i);
1160
1161 if (msg->msg_fields != NULL) {
1162 if (!msg->msg_cached) {
1163 r = imapdriver_write_cached_envelope(cache_db, mmapstr,
1164 session, msg, msg->msg_fields);
1165 }
1166 }
1167 }
1168
1169 /* flush cache */
1170
1171 maildriver_cache_clean_up(cache_db, NULL, env_list);
1172
1173 mail_cache_db_close_unlock(filename, cache_db);
1174 mmap_string_free(mmapstr);
1175
1176 /* remove cache files */
1177
1178 maildriver_message_cache_clean_up(data->imap_quoted_mb, env_list,
1179 get_uid_from_filename);
1180
1181 return MAIL_NO_ERROR;
1182
1183 free_mmapstr:
1184 mmap_string_free(mmapstr);
1185 err:
1186 return res;
1187}
1188
1189static int imapdriver_cached_remove_message(mailsession * session,
1190 uint32_t num)
1191{
1192 int r;
1193
1194 r = mailsession_remove_message(get_ancestor(session), num);
1195
1196 check_for_uid_cache(session);
1197
1198 return r;
1199}
1200
1201#if 0
1202static int imapdriver_cached_search_messages(mailsession * session,
1203 char * charset,
1204 struct mail_search_key * key,
1205 struct mail_search_result **
1206 result)
1207{
1208 int r;
1209
1210 r = mailsession_search_messages(get_ancestor(session), charset, key, result);
1211
1212 check_for_uid_cache(session);
1213
1214 return r;
1215}
1216#endif
1217
1218static int imapdriver_cached_get_message(mailsession * session,
1219 uint32_t num, mailmessage ** result)
1220{
1221 mailmessage * msg_info;
1222 int r;
1223
1224 msg_info = mailmessage_new();
1225 if (msg_info == NULL)
1226 return MAIL_ERROR_MEMORY;
1227
1228 r = mailmessage_init(msg_info, session, imap_cached_message_driver, num, 0);
1229 if (r != MAIL_NO_ERROR) {
1230 mailmessage_free(msg_info);
1231 return r;
1232 }
1233
1234 * result = msg_info;
1235
1236 return MAIL_NO_ERROR;
1237}
1238
1239/* Retrieve a message by UID
1240 * libEtPan! uid format for IMAP is "UIDVALIDITY-UID"
1241 * where UIDVALIDITY and UID are decimal representation of
1242 * respectively uidvalidity and uid numbers.
1243 * Return value:
1244 * MAIL_ERROR_INVAL if uid is NULL or has an incorrect format.
1245 * MAIL_ERROR_MSG_NOT_FOUND if uidvalidity has changed or uid was not found
1246 * MAIL_NO_ERROR if message was found. Result is in result
1247 */
1248static int imapdriver_cached_get_message_by_uid(mailsession * session,
1249 const char * uid,
1250 mailmessage ** result)
1251{
1252 uint32_t uidvalidity;
1253 uint32_t num;
1254 char * p1, * p2;
1255 mailimap *imap;
1256
1257 if (uid == NULL)
1258 return MAIL_ERROR_INVAL;
1259
1260 uidvalidity = strtoul(uid, &p1, 10);
1261 if (p1 == uid || * p1 != '-')
1262 return MAIL_ERROR_INVAL;
1263
1264 p1++;
1265 num = strtoul(p1, &p2, 10);
1266 if (p2 == p1 || * p2 != '\0')
1267 return MAIL_ERROR_INVAL;
1268
1269 imap = get_imap_session(session);
1270 if (imap->imap_selection_info->sel_uidvalidity != uidvalidity)
1271 return MAIL_ERROR_MSG_NOT_FOUND;
1272
1273 return imapdriver_cached_get_message(session, num, result);
1274}
diff --git a/kmicromail/libetpan/generic/imapdriver_cached.h b/kmicromail/libetpan/generic/imapdriver_cached.h
new file mode 100644
index 0000000..92bb60d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached.h
@@ -0,0 +1,52 @@
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#ifndef IMAPDRIVER_CACHED_H
37
38#define IMAPDRIVER_CACHED_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * imap_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_cached_message.c b/kmicromail/libetpan/generic/imapdriver_cached_message.c
new file mode 100644
index 0000000..c0542a3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached_message.c
@@ -0,0 +1,664 @@
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 "imapdriver_cached_message.h"
37
38#include "imapdriver_tools.h"
39#include "imapdriver_message.h"
40#include "imapdriver_cached.h"
41#include "imapdriver_types.h"
42#include "imapdriver.h"
43#include "mailmessage.h"
44#include "generic_cache.h"
45#include "mail_cache_db.h"
46
47#include <string.h>
48#include <stdlib.h>
49
50static int imap_initialize(mailmessage * msg_info);
51
52static void imap_uninitialize(mailmessage * msg_info);
53
54static void imap_flush(mailmessage * msg_info);
55
56static void imap_check(mailmessage * msg_info);
57
58static void imap_fetch_result_free(mailmessage * msg_info,
59 char * msg);
60
61static int imap_fetch(mailmessage * msg_info,
62 char ** result,
63 size_t * result_len);
64
65static int imap_fetch_header(mailmessage * msg_info,
66 char ** result,
67 size_t * result_len);
68
69static int imap_fetch_body(mailmessage * msg_info,
70 char ** result, size_t * result_len);
71
72static int imap_fetch_size(mailmessage * msg_info,
73 size_t * result);
74
75static int imap_get_bodystructure(mailmessage * msg_info,
76 struct mailmime ** result);
77
78static int imap_fetch_section(mailmessage * msg_info,
79 struct mailmime * mime,
80 char ** result, size_t * result_len);
81
82static int imap_fetch_section_header(mailmessage * msg_info,
83 struct mailmime * mime,
84 char ** result,
85 size_t * result_len);
86
87static int imap_fetch_section_mime(mailmessage * msg_info,
88 struct mailmime * mime,
89 char ** result,
90 size_t * result_len);
91
92static int imap_fetch_section_body(mailmessage * msg_info,
93 struct mailmime * mime,
94 char ** result,
95 size_t * result_len);
96
97
98static int imap_fetch_envelope(mailmessage * msg_info,
99 struct mailimf_fields ** result);
100
101static int imap_get_flags(mailmessage * msg_info,
102 struct mail_flags ** result);
103
104static mailmessage_driver local_imap_cached_message_driver = {
105 .msg_name = "imap-cached",
106
107 .msg_initialize = imap_initialize,
108 .msg_uninitialize = imap_uninitialize,
109
110 .msg_flush = imap_flush,
111 .msg_check = imap_check,
112
113 .msg_fetch_result_free = imap_fetch_result_free,
114
115 .msg_fetch = imap_fetch,
116 .msg_fetch_header = imap_fetch_header,
117 .msg_fetch_body = imap_fetch_body,
118 .msg_fetch_size = imap_fetch_size,
119 .msg_get_bodystructure = imap_get_bodystructure,
120 .msg_fetch_section = imap_fetch_section,
121 .msg_fetch_section_header = imap_fetch_section_header,
122 .msg_fetch_section_mime = imap_fetch_section_mime,
123 .msg_fetch_section_body = imap_fetch_section_body,
124 .msg_fetch_envelope = imap_fetch_envelope,
125
126 .msg_get_flags = imap_get_flags,
127};
128
129mailmessage_driver * imap_cached_message_driver =
130&local_imap_cached_message_driver;
131
132static inline struct imap_cached_session_state_data *
133get_cached_session_data(mailmessage * msg)
134{
135 return msg->msg_session->sess_data;
136}
137
138static inline mailmessage * get_ancestor(mailmessage * msg_info)
139{
140 return msg_info->msg_data;
141}
142
143static inline struct imap_cached_session_state_data *
144cached_session_get_data(mailsession * s)
145{
146 return s->sess_data;
147}
148
149static inline mailsession * cached_session_get_ancestor(mailsession * s)
150{
151 return cached_session_get_data(s)->imap_ancestor;
152}
153
154static inline struct imap_session_state_data *
155cached_session_get_ancestor_data(mailsession * s)
156{
157 return cached_session_get_ancestor(s)->sess_data;
158}
159
160static inline mailimap *
161cached_session_get_imap_session(mailsession * session)
162{
163 return cached_session_get_ancestor_data(session)->imap_session;
164}
165
166static inline mailimap * get_imap_session(mailmessage * msg)
167{
168 return cached_session_get_imap_session(msg->msg_session);
169}
170
171static inline mailsession * get_ancestor_session(mailmessage * msg_info)
172{
173 return cached_session_get_ancestor(msg_info->msg_session);
174}
175
176
177static void generate_key_from_mime_section(char * key, size_t size,
178 struct mailmime * mime)
179{
180 clistiter * cur;
181 MMAPString * gstr;
182 struct mailmime_section * part;
183 int r;
184
185 snprintf(key, size, "unvalid");
186
187 r = mailmime_get_section_id(mime, &part);
188 if (r != MAILIMF_NO_ERROR)
189 goto err;
190
191 gstr = mmap_string_new("part");
192 if (gstr == NULL)
193 goto free_section;
194
195 for(cur = clist_begin(part->sec_list) ;
196 cur != NULL ; cur = clist_next(cur)) {
197 char s[20];
198
199 snprintf(s, 20, ".%u", * (uint32_t *) clist_content(cur));
200 if (mmap_string_append(gstr, s) == NULL)
201 goto free_str;
202 }
203
204 snprintf(key, size, "%s", gstr->str);
205
206 mmap_string_free(gstr);
207 mailmime_section_free(part);
208
209 return;
210
211 free_str:
212 mmap_string_free(gstr);
213 free_section:
214 mailmime_section_free(part);
215 err:
216}
217
218static void generate_key_from_section(char * key, size_t size,
219 mailmessage * msg_info,
220 struct mailmime * mime, int type)
221{
222 char section_str[PATH_MAX];
223
224 generate_key_from_mime_section(section_str, PATH_MAX, mime);
225
226 switch (type) {
227 case IMAP_SECTION_MESSAGE:
228 snprintf(key, size, "%s-%s", msg_info->msg_uid, section_str);
229 break;
230 case IMAP_SECTION_HEADER:
231 snprintf(key, size, "%s-%s-header", msg_info->msg_uid, section_str);
232 break;
233 case IMAP_SECTION_MIME:
234 snprintf(key, size, "%s-%s-mime", msg_info->msg_uid, section_str);
235 break;
236 case IMAP_SECTION_BODY:
237 snprintf(key, size, "%s-%s-text", msg_info->msg_uid, section_str);
238 break;
239 }
240}
241
242static void generate_key_from_message(char * key, size_t size,
243 mailmessage * msg_info,
244 int type)
245{
246 switch (type) {
247 case MAILIMAP_MSG_ATT_RFC822:
248 snprintf(key, size, "%s-rfc822", msg_info->msg_uid);
249 break;
250 case MAILIMAP_MSG_ATT_RFC822_HEADER:
251 snprintf(key, size, "%s-rfc822-header", msg_info->msg_uid);
252 break;
253 case MAILIMAP_MSG_ATT_RFC822_TEXT:
254 snprintf(key, size, "%s-rfc822-text", msg_info->msg_uid);
255 break;
256 case MAILIMAP_MSG_ATT_ENVELOPE:
257 snprintf(key, size, "%s-envelope", msg_info->msg_uid);
258 break;
259 }
260}
261
262static void build_cache_name(char * filename, size_t size,
263 mailmessage * msg, char * key)
264{
265 char * quoted_mb;
266
267 quoted_mb = get_cached_session_data(msg)->imap_quoted_mb;
268
269 snprintf(filename, size, "%s/%s", quoted_mb, key);
270}
271
272static int imap_initialize(mailmessage * msg_info)
273{
274 mailmessage * ancestor;
275 int r;
276 char key[PATH_MAX];
277 char * uid;
278 mailimap * imap;
279
280 ancestor = mailmessage_new();
281 if (ancestor == NULL)
282 return MAIL_ERROR_MEMORY;
283
284 r = mailmessage_init(ancestor, get_ancestor_session(msg_info),
285 imap_message_driver,
286 msg_info->msg_index, 0);
287 if (r != MAIL_NO_ERROR) {
288 mailmessage_free(ancestor);
289 return r;
290 }
291
292 imap = get_imap_session(msg_info);
293
294 snprintf(key, PATH_MAX, "%u-%u",
295 imap->imap_selection_info->sel_uidvalidity, msg_info->msg_index);
296 uid = strdup(key);
297 if (uid == NULL) {
298 mailmessage_free(ancestor);
299 return MAIL_ERROR_MEMORY;
300 }
301
302 msg_info->msg_data = ancestor;
303 msg_info->msg_uid = uid;
304
305 return MAIL_NO_ERROR;
306}
307
308static void imap_uninitialize(mailmessage * msg_info)
309{
310 mailmessage_free(get_ancestor(msg_info));
311 msg_info->msg_data = NULL;
312}
313
314static void imap_flush(mailmessage * msg_info)
315{
316 if (msg_info->msg_mime != NULL) {
317 mailmime_free(msg_info->msg_mime);
318 msg_info->msg_mime = NULL;
319 }
320}
321
322static void imap_check(mailmessage * msg_info)
323{
324 get_ancestor(msg_info)->msg_flags = msg_info->msg_flags;
325 mailmessage_check(get_ancestor(msg_info));
326 get_ancestor(msg_info)->msg_flags = NULL;
327}
328
329static void imap_fetch_result_free(mailmessage * msg_info,
330 char * msg)
331{
332 mailmessage_fetch_result_free(get_ancestor(msg_info), msg);
333}
334
335static int imap_fetch(mailmessage * msg_info,
336 char ** result,
337 size_t * result_len)
338{
339 char key[PATH_MAX];
340 char filename[PATH_MAX];
341 int r;
342 char * str;
343 size_t len;
344
345 generate_key_from_message(key, PATH_MAX,
346 msg_info, MAILIMAP_MSG_ATT_RFC822);
347
348 build_cache_name(filename, PATH_MAX, msg_info, key);
349
350 r = generic_cache_read(filename, &str, &len);
351 if (r == MAIL_NO_ERROR) {
352 * result = str;
353 * result_len = len;
354
355 return MAIL_NO_ERROR;
356 }
357
358 r = mailmessage_fetch(get_ancestor(msg_info),
359 result, result_len);
360 if (r == MAIL_NO_ERROR)
361 generic_cache_store(filename, * result, strlen(* result));
362
363 return r;
364}
365
366static int imap_fetch_header(mailmessage * msg_info,
367 char ** result,
368 size_t * result_len)
369{
370 char key[PATH_MAX];
371 char filename[PATH_MAX];
372 int r;
373 char * str;
374 size_t len;
375
376 generate_key_from_message(key, PATH_MAX,
377 msg_info, MAILIMAP_MSG_ATT_RFC822_HEADER);
378
379 build_cache_name(filename, PATH_MAX, msg_info, key);
380
381 r = generic_cache_read(filename, &str, &len);
382 if (r == MAIL_NO_ERROR) {
383 * result = str;
384 * result_len = len;
385
386 return MAIL_NO_ERROR;
387 }
388
389 r = mailmessage_fetch_header(get_ancestor(msg_info), result,
390 result_len);
391 if (r == MAIL_NO_ERROR)
392 generic_cache_store(filename, * result, * result_len);
393
394 return r;
395}
396
397static int imap_fetch_body(mailmessage * msg_info,
398 char ** result, size_t * result_len)
399{
400 char key[PATH_MAX];
401 char filename[PATH_MAX];
402 int r;
403 char * str;
404 size_t len;
405
406 generate_key_from_message(key, PATH_MAX,
407 msg_info, MAILIMAP_MSG_ATT_RFC822_TEXT);
408
409 build_cache_name(filename, PATH_MAX, msg_info, key);
410
411 r = generic_cache_read(filename, &str, &len);
412 if (r == MAIL_NO_ERROR) {
413 * result = str;
414 * result_len = len;
415 return MAIL_NO_ERROR;
416 }
417
418 r = mailmessage_fetch_body(get_ancestor(msg_info), result,
419 result_len);
420 if (r == MAIL_NO_ERROR)
421 generic_cache_store(filename, * result, * result_len);
422
423 return r;
424}
425
426static int imap_fetch_size(mailmessage * msg_info,
427 size_t * result)
428{
429 return mailmessage_fetch_size(get_ancestor(msg_info), result);
430}
431
432static int imap_get_bodystructure(mailmessage * msg_info,
433 struct mailmime ** result)
434{
435 int r;
436
437 if (msg_info->msg_mime != NULL) {
438 * result = msg_info->msg_mime;
439
440 return MAIL_NO_ERROR;
441 }
442
443 r = mailmessage_get_bodystructure(get_ancestor(msg_info),
444 result);
445 if (r == MAIL_NO_ERROR) {
446 msg_info->msg_mime = get_ancestor(msg_info)->msg_mime;
447 get_ancestor(msg_info)->msg_mime = NULL;
448 }
449
450 return r;
451}
452
453static int imap_fetch_section(mailmessage * msg_info,
454 struct mailmime * mime,
455 char ** result, size_t * result_len)
456{
457 char key[PATH_MAX];
458 char filename[PATH_MAX];
459 int r;
460 char * str;
461 size_t len;
462
463 generate_key_from_section(key, PATH_MAX,
464 msg_info, mime, IMAP_SECTION_MESSAGE);
465
466 build_cache_name(filename, PATH_MAX, msg_info, key);
467
468 r = generic_cache_read(filename, &str, &len);
469 if (r == MAIL_NO_ERROR) {
470 * result = str;
471 * result_len = len;
472
473 return MAIL_NO_ERROR;
474 }
475
476 r = mailmessage_fetch_section(get_ancestor(msg_info),
477 mime, result, result_len);
478 if (r == MAIL_NO_ERROR)
479 generic_cache_store(filename, * result, * result_len);
480
481 return r;
482}
483
484static int imap_fetch_section_header(mailmessage * msg_info,
485 struct mailmime * mime,
486 char ** result,
487 size_t * result_len)
488{
489 char key[PATH_MAX];
490 char filename[PATH_MAX];
491 int r;
492 char * str;
493 size_t len;
494
495 generate_key_from_section(key, PATH_MAX,
496 msg_info, mime, IMAP_SECTION_HEADER);
497
498 build_cache_name(filename, PATH_MAX, msg_info, key);
499
500 r = generic_cache_read(filename, &str, &len);
501 if (r == MAIL_NO_ERROR) {
502 * result = str;
503 * result_len = len;
504
505 return MAIL_NO_ERROR;
506 }
507
508 r = mailmessage_fetch_section_header(get_ancestor(msg_info),
509 mime, result, result_len);
510 if (r == MAIL_NO_ERROR)
511 generic_cache_store(filename, * result, * result_len);
512
513 return r;
514}
515
516static int imap_fetch_section_mime(mailmessage * msg_info,
517 struct mailmime * mime,
518 char ** result,
519 size_t * result_len)
520{
521 char key[PATH_MAX];
522 char filename[PATH_MAX];
523 int r;
524 char * str;
525 size_t len;
526
527 generate_key_from_section(key, PATH_MAX,
528 msg_info, mime, IMAP_SECTION_MIME);
529
530 build_cache_name(filename, PATH_MAX, msg_info, key);
531
532 r = generic_cache_read(filename, &str, &len);
533 if (r == MAIL_NO_ERROR) {
534 * result = str;
535 * result_len = len;
536
537 return MAIL_NO_ERROR;
538 }
539
540 r = mailmessage_fetch_section_mime(get_ancestor(msg_info),
541 mime, result, result_len);
542 if (r == MAIL_NO_ERROR)
543 generic_cache_store(filename, * result, * result_len);
544
545 return r;
546}
547
548static int imap_fetch_section_body(mailmessage * msg_info,
549 struct mailmime * mime,
550 char ** result,
551 size_t * result_len)
552{
553 char key[PATH_MAX];
554 char filename[PATH_MAX];
555 int r;
556 char * str;
557 size_t len;
558
559 generate_key_from_section(key, PATH_MAX,
560 msg_info, mime, IMAP_SECTION_BODY);
561
562 build_cache_name(filename, PATH_MAX, msg_info, key);
563
564 r = generic_cache_read(filename, &str, &len);
565 if (r == MAIL_NO_ERROR) {
566
567 * result = str;
568 * result_len = len;
569
570 return MAIL_NO_ERROR;
571 }
572
573 r = mailmessage_fetch_section_body(get_ancestor(msg_info),
574 mime, result, result_len);
575 if (r == MAIL_NO_ERROR)
576 generic_cache_store(filename, * result, * result_len);
577
578 return r;
579}
580
581static int imap_get_flags(mailmessage * msg_info,
582 struct mail_flags ** result)
583{
584 int r;
585 struct mail_flags * flags;
586
587 if (msg_info->msg_flags != NULL) {
588 * result = msg_info->msg_flags;
589 return MAIL_NO_ERROR;
590 }
591
592 r = mailmessage_get_flags(get_ancestor(msg_info), &flags);
593 if (r != MAIL_NO_ERROR)
594 return r;
595
596 get_ancestor(msg_info)->msg_flags = NULL;
597 msg_info->msg_flags = flags;
598 * result = flags;
599
600 return MAIL_NO_ERROR;
601}
602
603#define ENV_NAME "env.db"
604
605static int imap_fetch_envelope(mailmessage * msg_info,
606 struct mailimf_fields ** result)
607{
608 struct mailimf_fields * fields;
609 int r;
610 struct mail_cache_db * cache_db;
611 MMAPString * mmapstr;
612 char filename[PATH_MAX];
613 struct imap_cached_session_state_data * data;
614 int res;
615
616 data = get_cached_session_data(msg_info);
617 if (data->imap_quoted_mb == NULL) {
618 res = MAIL_ERROR_BAD_STATE;
619 goto err;
620 }
621
622 snprintf(filename, PATH_MAX, "%s/%s", data->imap_quoted_mb, ENV_NAME);
623
624 r = mail_cache_db_open_lock(filename, &cache_db);
625 if (r < 0) {
626 res = MAIL_ERROR_MEMORY;
627 goto err;
628 }
629
630 mmapstr = mmap_string_new("");
631 if (mmapstr == NULL) {
632 res = MAIL_ERROR_MEMORY;
633 goto close_db;
634 }
635
636 r = imapdriver_get_cached_envelope(cache_db, mmapstr,
637 msg_info->msg_session, msg_info, &fields);
638
639 if ((r != MAIL_ERROR_CACHE_MISS) && (r != MAIL_NO_ERROR)) {
640 res = r;
641 goto close_db;
642 }
643
644 r = mailmessage_fetch_envelope(get_ancestor(msg_info), &fields);
645 if (r != MAIL_NO_ERROR) {
646 res = r;
647 goto close_db;
648 }
649
650 r = imapdriver_write_cached_envelope(cache_db, mmapstr,
651 msg_info->msg_session, msg_info, fields);
652
653 * result = fields;
654
655 mmap_string_free(mmapstr);
656 mail_cache_db_close_unlock(filename, cache_db);
657
658 return MAIL_NO_ERROR;
659
660 close_db:
661 mail_cache_db_close_unlock(filename, cache_db);
662 err:
663 return res;
664}
diff --git a/kmicromail/libetpan/generic/imapdriver_cached_message.h b/kmicromail/libetpan/generic/imapdriver_cached_message.h
new file mode 100644
index 0000000..49d63cb
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached_message.h
@@ -0,0 +1,52 @@
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#ifndef IMAPDRIVER_CACHED_MESSAGE_H
37
38#define IMAPDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * imap_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_message.c b/kmicromail/libetpan/generic/imapdriver_message.c
new file mode 100644
index 0000000..47c7f78
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_message.c
@@ -0,0 +1,1239 @@
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 "imapdriver_message.h"
37
38#include "imapdriver_tools.h"
39#include "imapdriver.h"
40#include "imapdriver_types.h"
41#include "mailimap.h"
42#include "maildriver_tools.h"
43#include "generic_cache.h"
44
45#include <stdlib.h>
46#include <string.h>
47
48static int imap_initialize(mailmessage * msg_info);
49
50static void imap_fetch_result_free(mailmessage * msg_info,
51 char * msg);
52
53static int imap_fetch(mailmessage * msg_info,
54 char ** result,
55 size_t * result_len);
56
57static int imap_fetch_header(mailmessage * msg_info,
58 char ** result,
59 size_t * result_len);
60
61static int imap_fetch_body(mailmessage * msg_info,
62 char ** result, size_t * result_len);
63
64static int imap_fetch_size(mailmessage * msg_info,
65 size_t * result);
66
67static int imap_get_bodystructure(mailmessage * msg_info,
68 struct mailmime ** result);
69
70static int imap_fetch_section(mailmessage * msg_info,
71 struct mailmime * mime,
72 char ** result, size_t * result_len);
73
74static int imap_fetch_section_header(mailmessage * msg_info,
75 struct mailmime * mime,
76 char ** result,
77 size_t * result_len);
78
79static int imap_fetch_section_mime(mailmessage * msg_info,
80 struct mailmime * mime,
81 char ** result,
82 size_t * result_len);
83
84static int imap_fetch_section_body(mailmessage * msg_info,
85 struct mailmime * mime,
86 char ** result,
87 size_t * result_len);
88
89static int imap_fetch_envelope(mailmessage * msg_info,
90 struct mailimf_fields ** result);
91
92static int imap_get_flags(mailmessage * msg_info,
93 struct mail_flags ** result);
94
95static void imap_flush(mailmessage * msg_info);
96
97static void imap_check(mailmessage * msg_info);
98
99static mailmessage_driver local_imap_message_driver = {
100 .msg_name = "imap",
101
102 .msg_initialize = imap_initialize,
103 .msg_uninitialize = NULL,
104
105 .msg_flush = imap_flush,
106 .msg_check = imap_check,
107
108 .msg_fetch_result_free = imap_fetch_result_free,
109
110 .msg_fetch = imap_fetch,
111 .msg_fetch_header = imap_fetch_header,
112 .msg_fetch_body = imap_fetch_body,
113 .msg_fetch_size = imap_fetch_size,
114 .msg_get_bodystructure = imap_get_bodystructure,
115 .msg_fetch_section = imap_fetch_section,
116 .msg_fetch_section_header = imap_fetch_section_header,
117 .msg_fetch_section_mime = imap_fetch_section_mime,
118 .msg_fetch_section_body = imap_fetch_section_body,
119 .msg_fetch_envelope = imap_fetch_envelope,
120
121 .msg_get_flags = imap_get_flags,
122};
123
124mailmessage_driver * imap_message_driver = &local_imap_message_driver;
125
126static inline struct imap_session_state_data *
127get_session_data(mailmessage * msg)
128{
129 return msg->msg_session->sess_data;
130}
131
132static inline mailimap * get_imap_session(mailmessage * msg)
133{
134 return get_session_data(msg)->imap_session;
135}
136
137
138
139static int imap_initialize(mailmessage * msg_info)
140{
141 char key[PATH_MAX];
142 char * uid;
143 mailimap * imap;
144
145 imap = get_imap_session(msg_info);
146
147 snprintf(key, PATH_MAX, "%u-%u",
148 imap->imap_selection_info->sel_uidvalidity, msg_info->msg_index);
149
150 uid = strdup(key);
151 if (uid == NULL) {
152 return MAIL_ERROR_MEMORY;
153 }
154
155 msg_info->msg_uid = uid;
156
157 return MAIL_NO_ERROR;
158}
159
160
161static void imap_fetch_result_free(mailmessage * msg_info,
162 char * msg)
163{
164 if (msg != NULL) {
165 if (mmap_string_unref(msg) != 0)
166 free(msg);
167 }
168}
169
170
171static void imap_flush(mailmessage * msg_info)
172{
173 if (msg_info->msg_mime != NULL) {
174 mailmime_free(msg_info->msg_mime);
175 msg_info->msg_mime = NULL;
176 }
177}
178
179static void imap_check(mailmessage * msg_info)
180{
181 int r;
182
183 if (msg_info->msg_flags != NULL) {
184 r = mail_flags_store_set(get_session_data(msg_info)->imap_flags_store,
185 msg_info);
186 /* ignore errors */
187 }
188}
189
190static int imap_fetch(mailmessage * msg_info,
191 char ** result,
192 size_t * result_len)
193{
194 int r;
195 struct mailimap_set * set;
196 struct mailimap_fetch_att * fetch_att;
197 struct mailimap_fetch_type * fetch_type;
198 clist * fetch_result;
199 struct mailimap_msg_att * msg_att;
200 struct mailimap_msg_att_item * msg_att_item;
201 char * text;
202 size_t text_length;
203 int res;
204 clistiter * cur;
205 struct mailimap_section * section;
206
207 set = mailimap_set_new_single(msg_info->msg_index);
208 if (set == NULL) {
209 res = MAIL_ERROR_MEMORY;
210 goto err;
211 }
212
213#if 0
214 fetch_att = mailimap_fetch_att_new_rfc822();
215 if (fetch_att == NULL) {
216 res = MAIL_ERROR_MEMORY;
217 goto free_set;
218 }
219
220 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
221 if (fetch_type == NULL) {
222 res = MAIL_ERROR_MEMORY;
223 goto free_fetch_att;
224 }
225
226 r = mailimap_uid_fetch(get_imap_session(msg_info->session), set,
227 fetch_type, &fetch_result);
228
229 mailimap_fetch_type_free(fetch_type);
230#endif
231
232 section = mailimap_section_new(NULL);
233 if (section == NULL) {
234 res = MAIL_ERROR_MEMORY;
235 goto free_set;
236 }
237
238 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
239 if (fetch_att == NULL) {
240 mailimap_section_free(section);
241 res = MAIL_ERROR_MEMORY;
242 goto free_set;
243 }
244
245 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
246 if (fetch_type == NULL) {
247 res = MAIL_ERROR_MEMORY;
248 goto free_fetch_att;
249 }
250
251 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
252 fetch_type, &fetch_result);
253
254 mailimap_fetch_type_free(fetch_type);
255 mailimap_set_free(set);
256
257 switch (r) {
258 case MAILIMAP_NO_ERROR:
259 break;
260 default:
261 return imap_error_to_mail_error(r);
262 }
263
264 if (clist_begin(fetch_result) == NULL) {
265 mailimap_fetch_list_free(fetch_result);
266 return MAIL_ERROR_FETCH;
267 }
268
269 msg_att = clist_begin(fetch_result)->data;
270
271 text = NULL;
272 text_length = 0;
273
274 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
275 cur = clist_next(cur)) {
276 msg_att_item = clist_content(cur);
277
278 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
279#if 0
280 if (msg_att_item->msg_att_static->type == MAILIMAP_MSG_ATT_RFC822) {
281 text = msg_att_item->msg_att_static->rfc822;
282 msg_att_item->msg_att_static->rfc822 = NULL;
283 text_length = msg_att_item->msg_att_static->length;
284 }
285#endif
286 if (msg_att_item->att_data.att_static->att_type ==
287 MAILIMAP_MSG_ATT_BODY_SECTION) {
288 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
289 /* detach */
290 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
291 text_length =
292 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
293 }
294 }
295 }
296
297 mailimap_fetch_list_free(fetch_result);
298
299 if (text == NULL)
300 return MAIL_ERROR_FETCH;
301
302 * result = text;
303 * result_len = text_length;
304
305 return MAIL_NO_ERROR;
306
307 free_fetch_att:
308 mailimap_fetch_att_free(fetch_att);
309 free_set:
310 mailimap_set_free(set);
311 err:
312 return res;
313}
314
315static int imap_fetch_header(mailmessage * msg_info,
316 char ** result,
317 size_t * result_len)
318{
319 int r;
320 struct mailimap_set * set;
321 struct mailimap_fetch_att * fetch_att;
322 struct mailimap_fetch_type * fetch_type;
323 clist * fetch_result;
324 struct mailimap_msg_att * msg_att;
325 struct mailimap_msg_att_item * msg_att_item;
326 char * text;
327 size_t text_length;
328 int res;
329 clistiter * cur;
330 struct mailimap_section * section;
331
332 set = mailimap_set_new_single(msg_info->msg_index);
333 if (set == NULL) {
334 res = MAIL_ERROR_MEMORY;
335 goto err;
336 }
337
338#if 0
339 fetch_att = mailimap_fetch_att_new_rfc822_header();
340 if (fetch_att == NULL) {
341 res = MAIL_ERROR_MEMORY;
342 goto free_set;
343 }
344
345 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
346 if (fetch_type == NULL) {
347 res = MAIL_ERROR_MEMORY;
348 goto free_fetch_att;
349 }
350
351 r = mailimap_uid_fetch(get_imap_session(msg_info->session),
352 set, fetch_type, &fetch_result);
353
354 mailimap_fetch_type_free(fetch_type);
355#endif
356
357 section = mailimap_section_new_header();
358 if (section == NULL) {
359 res = MAIL_ERROR_MEMORY;
360 goto free_set;
361 }
362
363 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
364 if (fetch_att == NULL) {
365 mailimap_section_free(section);
366 res = MAIL_ERROR_MEMORY;
367 goto free_set;
368 }
369
370 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
371 if (fetch_type == NULL) {
372 res = MAIL_ERROR_MEMORY;
373 goto free_fetch_att;
374 }
375
376 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
377 fetch_type, &fetch_result);
378
379 mailimap_fetch_type_free(fetch_type);
380 mailimap_set_free(set);
381
382 switch (r) {
383 case MAILIMAP_NO_ERROR:
384 break;
385 default:
386 return imap_error_to_mail_error(r);
387 }
388
389 if (clist_begin(fetch_result) == NULL) {
390 mailimap_fetch_list_free(fetch_result);
391 return MAIL_ERROR_FETCH;
392 }
393
394 msg_att = clist_begin(fetch_result)->data;
395
396 text = NULL;
397 text_length = 0;
398
399 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
400 cur = clist_next(cur)) {
401 msg_att_item = clist_content(cur);
402
403 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
404#if 0
405 if (msg_att_item->msg_att_static->type ==
406 MAILIMAP_MSG_ATT_RFC822_HEADER) {
407 text = msg_att_item->msg_att_static->rfc822_header;
408 msg_att_item->msg_att_static->rfc822_header = NULL;
409 text_length = msg_att_item->msg_att_static->length;
410 }
411#endif
412 if (msg_att_item->att_data.att_static->att_type ==
413 MAILIMAP_MSG_ATT_BODY_SECTION) {
414 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
415 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
416 text_length =
417 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
418 }
419 }
420 }
421
422 mailimap_fetch_list_free(fetch_result);
423
424 if (text == NULL)
425 return MAIL_ERROR_FETCH;
426
427 * result = text;
428 * result_len = text_length;
429
430 return MAIL_NO_ERROR;
431
432 free_fetch_att:
433 mailimap_fetch_att_free(fetch_att);
434 free_set:
435 mailimap_set_free(set);
436 err:
437 return res;
438}
439
440static int imap_fetch_body(mailmessage * msg_info,
441 char ** result, size_t * result_len)
442{
443 int r;
444 struct mailimap_set * set;
445 struct mailimap_fetch_att * fetch_att;
446 struct mailimap_fetch_type * fetch_type;
447 clist * fetch_result;
448 struct mailimap_msg_att * msg_att;
449 struct mailimap_msg_att_item * msg_att_item;
450 char * text;
451 size_t text_length;
452 int res;
453 clistiter * cur;
454 struct mailimap_section * section;
455
456 set = mailimap_set_new_single(msg_info->msg_index);
457 if (set == NULL) {
458 res = MAIL_ERROR_MEMORY;
459 goto err;
460 }
461
462#if 0
463 fetch_att = mailimap_fetch_att_new_rfc822_text();
464 if (fetch_att == NULL) {
465 res = MAIL_ERROR_MEMORY;
466 goto free_set;
467 }
468
469 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
470 if (fetch_type == NULL) {
471 res = MAIL_ERROR_MEMORY;
472 goto free_fetch_att;
473 }
474
475 r = mailimap_uid_fetch(get_imap_session(msg_info->session), set,
476 fetch_type, &fetch_result);
477
478 mailimap_fetch_type_free(fetch_type);
479#endif
480 section = mailimap_section_new_text();
481 if (section == NULL) {
482 res = MAIL_ERROR_MEMORY;
483 goto free_set;
484 }
485
486 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
487 if (fetch_att == NULL) {
488 mailimap_section_free(section);
489 res = MAIL_ERROR_MEMORY;
490 goto free_set;
491 }
492
493 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
494 if (fetch_type == NULL) {
495 res = MAIL_ERROR_MEMORY;
496 goto free_fetch_att;
497 }
498
499 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
500 fetch_type, &fetch_result);
501
502 mailimap_fetch_type_free(fetch_type);
503 mailimap_set_free(set);
504
505 switch (r) {
506 case MAILIMAP_NO_ERROR:
507 break;
508 default:
509 return imap_error_to_mail_error(r);
510 }
511
512 cur = clist_begin(fetch_result);
513 if (cur == NULL) {
514 mailimap_fetch_list_free(fetch_result);
515 return MAIL_ERROR_FETCH;
516 }
517
518 msg_att = clist_content(cur);
519
520 text = NULL;
521 text_length = 0;
522
523 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
524 cur = clist_next(cur)) {
525 msg_att_item = clist_content(cur);
526
527 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
528#if 0
529 if (msg_att_item->msg_att_static->type ==
530 MAILIMAP_MSG_ATT_RFC822_TEXT) {
531 text = msg_att_item->msg_att_static->rfc822_text;
532 msg_att_item->msg_att_static->rfc822_text = NULL;
533 text_length = msg_att_item->msg_att_static->length;
534 }
535#endif
536 if (msg_att_item->att_data.att_static->att_type ==
537 MAILIMAP_MSG_ATT_BODY_SECTION) {
538 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
539 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
540 text_length =
541 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
542 }
543 }
544 }
545
546 mailimap_fetch_list_free(fetch_result);
547
548 if (text == NULL)
549 return MAIL_ERROR_FETCH;
550
551 * result = text;
552 * result_len = text_length;
553
554 return MAIL_NO_ERROR;
555
556 free_fetch_att:
557 mailimap_fetch_att_free(fetch_att);
558 free_set:
559 mailimap_set_free(set);
560 err:
561 return res;
562}
563
564static int imap_fetch_size(mailmessage * msg_info,
565 size_t * result)
566{
567 int r;
568 struct mailimap_set * set;
569 struct mailimap_fetch_att * fetch_att;
570 struct mailimap_fetch_type * fetch_type;
571 clist * fetch_result;
572 struct mailimap_msg_att * msg_att;
573 struct mailimap_msg_att_item * msg_att_item;
574 size_t size;
575 int res;
576 clistiter * cur;
577
578 set = mailimap_set_new_single(msg_info->msg_index);
579 if (set == NULL) {
580 res = MAIL_ERROR_MEMORY;
581 goto err;
582 }
583
584 fetch_att = mailimap_fetch_att_new_rfc822_size();
585 if (fetch_att == NULL) {
586 res = MAIL_ERROR_MEMORY;
587 goto free_set;
588 }
589
590 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
591 if (fetch_type == NULL) {
592 res = MAIL_ERROR_MEMORY;
593 goto free_fetch_att;
594 }
595
596 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
597 fetch_type, &fetch_result);
598
599 mailimap_fetch_type_free(fetch_type);
600 mailimap_set_free(set);
601
602 switch (r) {
603 case MAILIMAP_ERROR_BAD_STATE:
604 return MAIL_ERROR_BAD_STATE;
605 case MAILIMAP_ERROR_STREAM:
606 return MAIL_ERROR_STREAM;
607 case MAILIMAP_NO_ERROR:
608 break;
609 default:
610 return MAIL_ERROR_FETCH;
611 }
612
613 if (clist_begin(fetch_result) == NULL) {
614 mailimap_fetch_list_free(fetch_result);
615 return MAIL_ERROR_FETCH;
616 }
617
618 msg_att = clist_begin(fetch_result)->data;
619
620 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
621 cur = clist_next(cur)) {
622 msg_att_item = clist_content(cur);
623
624 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
625
626 if (msg_att_item->att_data.att_static->att_type ==
627 MAILIMAP_MSG_ATT_RFC822_SIZE) {
628 size = msg_att_item->att_data.att_static->att_data.att_rfc822_size;
629
630 * result = size;
631
632 mailimap_fetch_list_free(fetch_result);
633 return MAIL_NO_ERROR;
634 }
635 }
636 }
637
638 mailimap_fetch_list_free(fetch_result);
639
640 return MAIL_ERROR_FETCH;
641
642 free_fetch_att:
643 mailimap_fetch_att_free(fetch_att);
644 free_set:
645 mailimap_set_free(set);
646 err:
647 return res;
648}
649
650static int imap_get_bodystructure(mailmessage * msg_info,
651 struct mailmime ** result)
652{
653 int r;
654 struct mailimap_set * set;
655 struct mailimap_fetch_att * fetch_att;
656 struct mailimap_fetch_type * fetch_type;
657 clist * fetch_result;
658 struct mailimap_msg_att * msg_att;
659 struct mailimap_body * imap_body;
660 struct mailmime * body;
661 int res;
662 struct mailimf_fields * fields;
663 struct mailmime * new_body;
664 struct mailmime_content * content_message;
665 struct mailimap_envelope * envelope;
666 uint32_t uid;
667 char * references;
668 size_t ref_size;
669 clistiter * cur;
670
671 if (msg_info->msg_mime != NULL) {
672 * result = msg_info->msg_mime;
673
674 return MAIL_NO_ERROR;
675 }
676
677 set = mailimap_set_new_single(msg_info->msg_index);
678 if (set == NULL) {
679 res = MAIL_ERROR_MEMORY;
680 goto err;
681 }
682
683 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
684 if (fetch_type == NULL) {
685 res = MAIL_ERROR_MEMORY;
686 goto free_set;
687 }
688
689 fetch_att = mailimap_fetch_att_new_uid();
690 if (fetch_att == NULL) {
691 res = MAIL_ERROR_MEMORY;
692 goto free_fetch_type;
693 }
694
695 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
696 if (r != MAILIMAP_NO_ERROR) {
697 mailimap_fetch_att_free(fetch_att);
698 res = MAIL_ERROR_MEMORY;
699 goto free_fetch_type;
700 }
701
702 fetch_att = mailimap_fetch_att_new_bodystructure();
703 if (fetch_att == NULL) {
704 res = MAIL_ERROR_MEMORY;
705 goto free_fetch_type;
706 }
707
708 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
709 if (r != MAILIMAP_NO_ERROR) {
710 mailimap_fetch_att_free(fetch_att);
711 res = MAIL_ERROR_MEMORY;
712 goto free_fetch_type;
713 }
714
715 r = imap_add_envelope_fetch_att(fetch_type);
716 if (r != MAIL_NO_ERROR) {
717 res = r;
718 goto free_fetch_type;
719 }
720
721
722 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
723 fetch_type, &fetch_result);
724
725 mailimap_fetch_type_free(fetch_type);
726 mailimap_set_free(set);
727
728 switch (r) {
729 case MAILIMAP_NO_ERROR:
730 break;
731 default:
732 return imap_error_to_mail_error(r);
733 }
734
735 cur = clist_begin(fetch_result);
736 if (cur == NULL) {
737 mailimap_fetch_list_free(fetch_result);
738 return MAIL_ERROR_FETCH;
739 }
740
741 msg_att = clist_content(cur);
742
743 uid = 0;
744 references = NULL;
745 ref_size = 0;
746 imap_body = NULL;
747 envelope = NULL;
748
749 r = imap_get_msg_att_info(msg_att,
750 &uid, &envelope, &references, &ref_size, NULL, &imap_body);
751 if (r != MAIL_NO_ERROR) {
752 mailimap_fetch_list_free(fetch_result);
753 res = r;
754 goto err;
755 }
756
757 if (uid != msg_info->msg_index) {
758 mailimap_fetch_list_free(fetch_result);
759 res = MAIL_ERROR_MSG_NOT_FOUND;
760 goto err;
761 }
762
763 if (imap_body == NULL) {
764 mailimap_fetch_list_free(fetch_result);
765 res = MAIL_ERROR_FETCH;
766 goto err;
767 }
768
769 r = imap_body_to_body(imap_body, &body);
770 if (r != MAIL_NO_ERROR) {
771 mailimap_fetch_list_free(fetch_result);
772 res = r;
773 goto err;
774 }
775
776 fields = NULL;
777 if (envelope != NULL) {
778 r = imap_env_to_fields(envelope, references, ref_size, &fields);
779 if (r != MAIL_NO_ERROR) {
780 mailmime_free(body);
781 mailimap_fetch_list_free(fetch_result);
782 res = r;
783 goto err;
784 }
785 }
786
787 content_message = mailmime_get_content_message();
788 if (content_message == NULL) {
789 if (fields != NULL)
790 mailimf_fields_free(fields);
791 mailmime_free(body);
792 mailimap_fetch_list_free(fetch_result);
793 res = MAIL_ERROR_MEMORY;
794 goto err;
795 }
796
797 new_body = mailmime_new(MAILMIME_MESSAGE, NULL,
798 0, NULL, content_message,
799 NULL, NULL, NULL, NULL, fields, body);
800
801 if (new_body == NULL) {
802 mailmime_content_free(content_message);
803 if (fields != NULL)
804 mailimf_fields_free(fields);
805 mailmime_free(body);
806 mailimap_fetch_list_free(fetch_result);
807 res = MAIL_ERROR_MEMORY;
808 goto err;
809 }
810 msg_info->msg_mime = new_body;
811
812 mailimap_fetch_list_free(fetch_result);
813
814 * result = new_body;
815
816 return MAIL_NO_ERROR;
817
818 free_fetch_type:
819 mailimap_fetch_type_free(fetch_type);
820 free_set:
821 mailimap_set_free(set);
822 err:
823 return res;
824}
825
826static int
827fetch_imap(mailmessage * msg,
828 struct mailimap_fetch_type * fetch_type,
829 char ** result, size_t * result_len)
830{
831 int r;
832 struct mailimap_msg_att * msg_att;
833 struct mailimap_msg_att_item * msg_att_item;
834 clist * fetch_result;
835 struct mailimap_set * set;
836 char * text;
837 size_t text_length;
838 clistiter * cur;
839
840 set = mailimap_set_new_single(msg->msg_index);
841 if (set == NULL)
842 return MAIL_ERROR_MEMORY;
843
844 r = mailimap_uid_fetch(get_imap_session(msg), set,
845 fetch_type, &fetch_result);
846
847 mailimap_set_free(set);
848
849 switch (r) {
850 case MAILIMAP_NO_ERROR:
851 break;
852 default:
853 return imap_error_to_mail_error(r);
854 }
855
856 if (clist_begin(fetch_result) == NULL) {
857 mailimap_fetch_list_free(fetch_result);
858 return MAIL_ERROR_FETCH;
859 }
860
861 msg_att = clist_begin(fetch_result)->data;
862
863 text = NULL;
864 text_length = 0;
865
866 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
867 cur = clist_next(cur)) {
868 msg_att_item = clist_content(cur);
869
870 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
871
872 if (msg_att_item->att_data.att_static->att_type ==
873 MAILIMAP_MSG_ATT_BODY_SECTION) {
874 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
875 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
876 text_length =
877 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
878 }
879 }
880 }
881
882 mailimap_fetch_list_free(fetch_result);
883
884 if (text == NULL)
885 return MAIL_ERROR_FETCH;
886
887 * result = text;
888 * result_len = text_length;
889
890 return MAIL_NO_ERROR;
891}
892
893
894static int imap_fetch_section(mailmessage * msg_info,
895 struct mailmime * mime,
896 char ** result, size_t * result_len)
897{
898 struct mailimap_section * section;
899 struct mailimap_fetch_att * fetch_att;
900 int r;
901 struct mailimap_fetch_type * fetch_type;
902 char * text;
903 size_t text_length;
904 struct mailmime_section * part;
905
906 if (mime->mm_parent == NULL)
907 return imap_fetch(msg_info, result, result_len);
908
909 r = mailmime_get_section_id(mime, &part);
910 if (r != MAILIMF_NO_ERROR)
911 return maildriver_imf_error_to_mail_error(r);
912
913 r = section_to_imap_section(part, IMAP_SECTION_MESSAGE, &section);
914 mailmime_section_free(part);
915 if (r != MAIL_NO_ERROR)
916 return r;
917
918 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
919 if (fetch_att == NULL) {
920 mailimap_section_free(section);
921 return MAIL_ERROR_MEMORY;
922 }
923
924 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
925 if (fetch_type == NULL) {
926 mailimap_fetch_att_free(fetch_att);
927 return MAIL_ERROR_MEMORY;
928 }
929
930 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
931
932 mailimap_fetch_type_free(fetch_type);
933
934 if (r != MAIL_NO_ERROR)
935 return r;
936
937 * result = text;
938 * result_len = text_length;
939
940 return MAIL_NO_ERROR;
941}
942
943static int imap_fetch_section_header(mailmessage * msg_info,
944 struct mailmime * mime,
945 char ** result,
946 size_t * result_len)
947{
948 struct mailimap_section * section;
949 struct mailimap_fetch_att * fetch_att;
950 int r;
951 struct mailimap_fetch_type * fetch_type;
952 char * text;
953 size_t text_length;
954 struct mailmime_section * part;
955
956 if (mime->mm_parent == NULL)
957 return imap_fetch_header(msg_info, result, result_len);
958
959 r = mailmime_get_section_id(mime, &part);
960 if (r != MAILIMF_NO_ERROR)
961 return maildriver_imf_error_to_mail_error(r);
962
963 r = section_to_imap_section(part, IMAP_SECTION_HEADER, &section);
964 mailmime_section_free(part);
965 if (r != MAIL_NO_ERROR)
966 return r;
967
968 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
969 if (fetch_att == NULL) {
970 mailimap_section_free(section);
971 return MAIL_ERROR_MEMORY;
972 }
973
974 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
975 if (fetch_type == NULL) {
976 mailimap_fetch_att_free(fetch_att);
977 return MAIL_ERROR_MEMORY;
978 }
979
980 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
981 mailimap_fetch_type_free(fetch_type);
982
983 if (r != MAIL_NO_ERROR)
984 return r;
985
986 * result = text;
987 * result_len = text_length;
988
989 return MAIL_NO_ERROR;
990}
991
992static int imap_fetch_section_mime(mailmessage * msg_info,
993 struct mailmime * mime,
994 char ** result,
995 size_t * result_len)
996{
997 struct mailimap_section * section;
998 struct mailimap_fetch_att * fetch_att;
999 int r;
1000 struct mailimap_fetch_type * fetch_type;
1001 char * text;
1002 size_t text_length;
1003 struct mailmime_section * part;
1004
1005 if (mime->mm_parent == NULL)
1006 return MAIL_ERROR_INVAL;
1007
1008 if (mime->mm_parent->mm_parent == NULL)
1009 return imap_fetch_header(msg_info, result, result_len);
1010
1011 r = mailmime_get_section_id(mime, &part);
1012 if (r != MAILIMF_NO_ERROR)
1013 return maildriver_imf_error_to_mail_error(r);
1014
1015 r = section_to_imap_section(part, IMAP_SECTION_MIME, &section);
1016 mailmime_section_free(part);
1017 if (r != MAIL_NO_ERROR)
1018 return MAIL_ERROR_MEMORY;
1019
1020 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
1021 if (fetch_att == NULL) {
1022 mailimap_section_free(section);
1023 return MAIL_ERROR_MEMORY;
1024 }
1025
1026 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
1027 if (fetch_type == NULL) {
1028 mailimap_fetch_att_free(fetch_att);
1029 return MAIL_ERROR_MEMORY;
1030 }
1031
1032 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
1033
1034 mailimap_fetch_type_free(fetch_type);
1035
1036 if (r != MAIL_NO_ERROR)
1037 return r;
1038
1039 * result = text;
1040 * result_len = text_length;
1041
1042 return MAIL_NO_ERROR;
1043}
1044
1045static int imap_fetch_section_body(mailmessage * msg_info,
1046 struct mailmime * mime,
1047 char ** result,
1048 size_t * result_len)
1049{
1050 struct mailimap_section * section;
1051 struct mailimap_fetch_att * fetch_att;
1052 int r;
1053 struct mailimap_fetch_type * fetch_type;
1054 char * text;
1055 size_t text_length;
1056 struct mailmime_section * part;
1057
1058 if (mime->mm_parent == NULL)
1059 return imap_fetch_body(msg_info, result, result_len);
1060
1061 if (mime->mm_parent->mm_parent == NULL)
1062 return imap_fetch_body(msg_info, result, result_len);
1063
1064 r = mailmime_get_section_id(mime, &part);
1065 if (r != MAILIMF_NO_ERROR)
1066 return maildriver_imf_error_to_mail_error(r);
1067
1068 r = section_to_imap_section(part, IMAP_SECTION_BODY, &section);
1069 mailmime_section_free(part);
1070 if (r != MAIL_NO_ERROR)
1071 return MAIL_ERROR_MEMORY;
1072
1073 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
1074 if (fetch_att == NULL) {
1075 mailimap_section_free(section);
1076 return MAIL_ERROR_MEMORY;
1077 }
1078
1079 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
1080 if (fetch_type == NULL) {
1081 mailimap_fetch_att_free(fetch_att);
1082 return MAIL_ERROR_MEMORY;
1083 }
1084
1085 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
1086
1087 mailimap_fetch_type_free(fetch_type);
1088
1089 if (r != MAIL_NO_ERROR)
1090 return r;
1091
1092 * result = text;
1093 * result_len = text_length;
1094
1095 return MAIL_NO_ERROR;
1096}
1097
1098static int imap_get_flags(mailmessage * msg_info,
1099 struct mail_flags ** result)
1100{
1101 int r;
1102 struct mail_flags * flags;
1103
1104 if (msg_info->msg_flags != NULL) {
1105 * result = msg_info->msg_flags;
1106 return MAIL_NO_ERROR;
1107 }
1108
1109 flags = mail_flags_store_get(get_session_data(msg_info)->imap_flags_store,
1110 msg_info->msg_index);
1111
1112 if (flags == NULL) {
1113 r = imap_fetch_flags(get_imap_session(msg_info),
1114 msg_info->msg_index, &flags);
1115 if (r != MAIL_NO_ERROR)
1116 return r;
1117 }
1118
1119 msg_info->msg_flags = flags;
1120
1121 * result = flags;
1122
1123 return MAIL_NO_ERROR;
1124}
1125
1126static int imap_fetch_envelope(mailmessage * msg_info,
1127 struct mailimf_fields ** result)
1128{
1129 int r;
1130 struct mailimap_set * set;
1131 struct mailimap_fetch_att * fetch_att;
1132 struct mailimap_fetch_type * fetch_type;
1133 clist * fetch_result;
1134 struct mailimap_msg_att * msg_att;
1135 int res;
1136 struct mailimf_fields * fields;
1137 struct mailimap_envelope * envelope;
1138 uint32_t uid;
1139 char * references;
1140 size_t ref_size;
1141
1142 set = mailimap_set_new_single(msg_info->msg_index);
1143 if (set == NULL) {
1144 res = MAIL_ERROR_MEMORY;
1145 goto err;
1146 }
1147
1148 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
1149 if (fetch_type == NULL) {
1150 res = MAIL_ERROR_MEMORY;
1151 goto free_set;
1152 }
1153
1154 fetch_att = mailimap_fetch_att_new_uid();
1155 if (fetch_att == NULL) {
1156 res = MAIL_ERROR_MEMORY;
1157 goto free_fetch_type;
1158 }
1159
1160 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
1161 if (r != MAILIMAP_NO_ERROR) {
1162 mailimap_fetch_att_free(fetch_att);
1163 res = MAIL_ERROR_MEMORY;
1164 goto free_fetch_type;
1165 }
1166
1167 r = imap_add_envelope_fetch_att(fetch_type);
1168 if (r != MAIL_NO_ERROR) {
1169 res = r;
1170 goto free_fetch_type;
1171 }
1172
1173 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
1174 fetch_type, &fetch_result);
1175
1176 mailimap_fetch_type_free(fetch_type);
1177 mailimap_set_free(set);
1178
1179 switch (r) {
1180 case MAILIMAP_NO_ERROR:
1181 break;
1182 default:
1183 return imap_error_to_mail_error(r);
1184 }
1185
1186 if (clist_begin(fetch_result) == NULL) {
1187 mailimap_fetch_list_free(fetch_result);
1188 return MAIL_ERROR_FETCH;
1189 }
1190
1191 msg_att = clist_begin(fetch_result)->data;
1192
1193 uid = 0;
1194 references = NULL;
1195 ref_size = 0;
1196 envelope = NULL;
1197
1198 r = imap_get_msg_att_info(msg_att,
1199 &uid,
1200 &envelope,
1201 &references,
1202 &ref_size,
1203 NULL,
1204 NULL);
1205 if (r != MAIL_NO_ERROR) {
1206 mailimap_fetch_list_free(fetch_result);
1207 res = r;
1208 goto err;
1209 }
1210
1211 if (uid != msg_info->msg_index) {
1212 mailimap_fetch_list_free(fetch_result);
1213 res = MAIL_ERROR_MSG_NOT_FOUND;
1214 goto err;
1215 }
1216
1217 fields = NULL;
1218 if (envelope != NULL) {
1219 r = imap_env_to_fields(envelope, references, ref_size, &fields);
1220 if (r != MAIL_NO_ERROR) {
1221 mailimap_fetch_list_free(fetch_result);
1222 res = r;
1223 goto err;
1224 }
1225 }
1226
1227 mailimap_fetch_list_free(fetch_result);
1228
1229 * result = fields;
1230
1231 return MAIL_NO_ERROR;
1232
1233 free_fetch_type:
1234 mailimap_fetch_type_free(fetch_type);
1235 free_set:
1236 mailimap_set_free(set);
1237 err:
1238 return res;
1239}
diff --git a/kmicromail/libetpan/generic/imapdriver_message.h b/kmicromail/libetpan/generic/imapdriver_message.h
new file mode 100644
index 0000000..9142633
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_message.h
@@ -0,0 +1,52 @@
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#ifndef IMAPDRIVER_MESSAGE_H
37
38#define IMAPDRIVER_MESSAGE_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * imap_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_tools.c b/kmicromail/libetpan/generic/imapdriver_tools.c
new file mode 100644
index 0000000..3d737f3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_tools.c
@@ -0,0 +1,3599 @@
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 "imapdriver_tools.h"
37
38#include "maildriver.h"
39
40#include <stdlib.h>
41#include <string.h>
42
43#include "mail.h"
44#include "imapdriver_types.h"
45#include "maildriver_tools.h"
46#include "generic_cache.h"
47#include "mailmessage.h"
48#include "mail_cache_db.h"
49
50
51
52static inline struct imap_session_state_data *
53session_get_data(mailsession * session)
54{
55 return session->sess_data;
56}
57
58static inline struct imap_cached_session_state_data *
59cached_session_get_data(mailsession * session)
60{
61 return session->sess_data;
62}
63
64static inline mailsession *
65cached_session_get_ancestor(mailsession * session)
66{
67 return cached_session_get_data(session)->imap_ancestor;
68}
69
70static inline struct imap_session_state_data *
71cached_session_get_ancestor_data(mailsession * session)
72{
73 return session_get_data(cached_session_get_ancestor(session));
74}
75
76static inline mailimap *
77cached_session_get_imap_session(mailsession * session)
78{
79 return cached_session_get_ancestor_data(session)->imap_session;
80}
81
82static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn,
83 struct mail_flags ** result);
84
85
86int imap_error_to_mail_error(int error)
87{
88 switch (error) {
89 case MAILIMAP_NO_ERROR:
90 return MAIL_NO_ERROR;
91
92 case MAILIMAP_NO_ERROR_AUTHENTICATED:
93 return MAIL_NO_ERROR_AUTHENTICATED;
94
95 case MAILIMAP_NO_ERROR_NON_AUTHENTICATED:
96 return MAIL_NO_ERROR_NON_AUTHENTICATED;
97
98 case MAILIMAP_ERROR_BAD_STATE:
99 return MAIL_ERROR_BAD_STATE;
100
101 case MAILIMAP_ERROR_STREAM:
102 return MAIL_ERROR_STREAM;
103
104 case MAILIMAP_ERROR_PARSE:
105 return MAIL_ERROR_PARSE;
106
107 case MAILIMAP_ERROR_CONNECTION_REFUSED:
108 return MAIL_ERROR_CONNECT;
109
110 case MAILIMAP_ERROR_MEMORY:
111 return MAIL_ERROR_MEMORY;
112
113 case MAILIMAP_ERROR_FATAL:
114 return MAIL_ERROR_FATAL;
115
116 case MAILIMAP_ERROR_PROTOCOL:
117 return MAIL_ERROR_PROTOCOL;
118
119 case MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION:
120 return MAIL_ERROR_CONNECT;
121
122 case MAILIMAP_ERROR_APPEND:
123 return MAIL_ERROR_APPEND;
124
125 case MAILIMAP_ERROR_NOOP:
126 return MAIL_ERROR_NOOP;
127
128 case MAILIMAP_ERROR_LOGOUT:
129 return MAIL_ERROR_LOGOUT;
130
131 case MAILIMAP_ERROR_CAPABILITY:
132 return MAIL_ERROR_CAPABILITY;
133
134 case MAILIMAP_ERROR_CHECK:
135 return MAIL_ERROR_CHECK;
136
137 case MAILIMAP_ERROR_CLOSE:
138 return MAIL_ERROR_CLOSE;
139
140 case MAILIMAP_ERROR_EXPUNGE:
141 return MAIL_ERROR_EXPUNGE;
142
143 case MAILIMAP_ERROR_COPY:
144 case MAILIMAP_ERROR_UID_COPY:
145 return MAIL_ERROR_COPY;
146
147 case MAILIMAP_ERROR_CREATE:
148 return MAIL_ERROR_CREATE;
149
150 case MAILIMAP_ERROR_DELETE:
151 return MAIL_ERROR_DELETE;
152
153 case MAILIMAP_ERROR_EXAMINE:
154 return MAIL_ERROR_EXAMINE;
155
156 case MAILIMAP_ERROR_FETCH:
157 case MAILIMAP_ERROR_UID_FETCH:
158 return MAIL_ERROR_FETCH;
159
160 case MAILIMAP_ERROR_LIST:
161 return MAIL_ERROR_LIST;
162
163 case MAILIMAP_ERROR_LOGIN:
164 return MAIL_ERROR_LOGIN;
165
166 case MAILIMAP_ERROR_LSUB:
167 return MAIL_ERROR_LSUB;
168
169 case MAILIMAP_ERROR_RENAME:
170 return MAIL_ERROR_RENAME;
171
172 case MAILIMAP_ERROR_SEARCH:
173 case MAILIMAP_ERROR_UID_SEARCH:
174 return MAIL_ERROR_SEARCH;
175
176 case MAILIMAP_ERROR_SELECT:
177 return MAIL_ERROR_SELECT;
178
179 case MAILIMAP_ERROR_STATUS:
180 return MAIL_ERROR_STATUS;
181
182 case MAILIMAP_ERROR_STORE:
183 case MAILIMAP_ERROR_UID_STORE:
184 return MAIL_ERROR_STORE;
185
186 case MAILIMAP_ERROR_SUBSCRIBE:
187 return MAIL_ERROR_SUBSCRIBE;
188
189 case MAILIMAP_ERROR_UNSUBSCRIBE:
190 return MAIL_ERROR_UNSUBSCRIBE;
191
192 case MAILIMAP_ERROR_STARTTLS:
193 return MAIL_ERROR_STARTTLS;
194
195 case MAILIMAP_ERROR_INVAL:
196 return MAIL_ERROR_INVAL;
197
198 default:
199 return MAIL_ERROR_INVAL;
200 }
201}
202
203
204
205
206
207static int
208imap_body_parameter_to_content(struct mailimap_body_fld_param *
209 body_parameter,
210 char * subtype,
211 struct mailmime_type * mime_type,
212 struct mailmime_content ** result);
213
214static int
215imap_body_type_text_to_content_type(char * subtype,
216 struct mailimap_body_fld_param *
217 body_parameter,
218 struct mailmime_content ** result);
219
220
221int imap_list_to_list(clist * imap_list, struct mail_list ** result)
222{
223 clistiter * cur;
224 clist * list;
225 struct mail_list * resp;
226 int r;
227 int res;
228
229 list = clist_new();
230 if (list == NULL) {
231 res = MAIL_ERROR_MEMORY;
232 goto err;
233 }
234
235 for(cur = clist_begin(imap_list) ; cur != NULL ; cur = clist_next(cur)) {
236 struct mailimap_mailbox_list * mb_list;
237 char * new_mb;
238
239 mb_list = clist_content(cur);
240
241 new_mb = strdup(mb_list->mb_name);
242 if (new_mb == NULL) {
243 res = MAIL_ERROR_MEMORY;
244 goto free_list;
245 }
246
247 r = clist_append(list, new_mb);
248 if (r != 0) {
249 free(new_mb);
250 res = MAIL_ERROR_MEMORY;
251 goto free_list;
252 }
253 }
254
255 resp = mail_list_new(list);
256 if (resp == NULL) {
257 res = MAIL_ERROR_MEMORY;
258 goto free_list;
259 }
260
261 * result = resp;
262
263 return MAIL_NO_ERROR;
264
265 free_list:
266 clist_foreach(list, (clist_func) free, NULL);
267 clist_free(list);
268 err:
269 return res;
270}
271
272int
273section_to_imap_section(struct mailmime_section * section, int type,
274 struct mailimap_section ** result)
275{
276 struct mailimap_section_part * section_part;
277 struct mailimap_section * imap_section;
278 clist * list;
279 clistiter * cur;
280 int r;
281 int res;
282
283 list = clist_new();
284 if (list == NULL) {
285 res = MAIL_ERROR_MEMORY;
286 goto err;
287 }
288
289 for(cur = clist_begin(section->sec_list) ; cur != NULL ;
290 cur = clist_next(cur)) {
291 uint32_t value;
292 uint32_t * id;
293
294 value = * (uint32_t *) clist_content(cur);
295 id = malloc(sizeof(* id));
296 if (id == NULL) {
297 res = MAIL_ERROR_MEMORY;
298 goto free_list;
299 }
300 * id = value;
301 r = clist_append(list, id);
302 if (r != 0) {
303 res = MAIL_ERROR_MEMORY;
304 free(id);
305 goto free_list;
306 }
307 }
308
309 section_part = mailimap_section_part_new(list);
310 if (section_part == NULL) {
311 res = MAIL_ERROR_MEMORY;
312 goto free_list;
313 }
314
315 imap_section = NULL;
316
317 switch (type) {
318 case IMAP_SECTION_MESSAGE:
319 imap_section = mailimap_section_new_part(section_part);
320 break;
321 case IMAP_SECTION_HEADER:
322 imap_section = mailimap_section_new_part_header(section_part);
323 break;
324 case IMAP_SECTION_MIME:
325 imap_section = mailimap_section_new_part_mime(section_part);
326 break;
327 case IMAP_SECTION_BODY:
328 imap_section = mailimap_section_new_part_text(section_part);
329 break;
330 }
331
332 if (imap_section == NULL) {
333 res = MAIL_ERROR_MEMORY;
334 goto free_part;
335 }
336
337 * result = imap_section;
338
339 return MAIL_NO_ERROR;
340
341 free_part:
342 mailimap_section_part_free(section_part);
343 free_list:
344 if (list != NULL) {
345 clist_foreach(list, (clist_func) free, NULL);
346 clist_free(list);
347 }
348 err:
349 return res;
350}
351
352
353
354static int
355imap_body_media_basic_to_content_type(struct mailimap_media_basic *
356 media_basic,
357 struct mailimap_body_fld_param *
358 body_parameter,
359 struct mailmime_content ** result)
360{
361 struct mailmime_content * content;
362 struct mailmime_type * mime_type;
363 struct mailmime_discrete_type * discrete_type;
364 struct mailmime_composite_type * composite_type;
365 char * discrete_type_extension;
366 int discrete_type_type;
367 int composite_type_type;
368 int mime_type_type;
369 char * subtype;
370 int r;
371 int res;
372
373 discrete_type = NULL;
374 composite_type = NULL;
375 discrete_type_extension = NULL;
376 subtype = NULL;
377 discrete_type_type = 0;
378 composite_type_type = 0;
379 mime_type_type = 0;
380
381 switch (media_basic->med_type) {
382 case MAILIMAP_MEDIA_BASIC_APPLICATION:
383 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
384 discrete_type_type = MAILMIME_DISCRETE_TYPE_APPLICATION;
385 break;
386
387 case MAILIMAP_MEDIA_BASIC_AUDIO:
388 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
389 discrete_type_type = MAILMIME_DISCRETE_TYPE_APPLICATION;
390 break;
391
392 case MAILIMAP_MEDIA_BASIC_IMAGE:
393 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
394 discrete_type_type = MAILMIME_DISCRETE_TYPE_IMAGE;
395 break;
396
397 case MAILIMAP_MEDIA_BASIC_MESSAGE:
398 mime_type_type = MAILMIME_TYPE_COMPOSITE_TYPE;
399 composite_type_type = MAILMIME_COMPOSITE_TYPE_MESSAGE;
400 break;
401
402 case MAILIMAP_MEDIA_BASIC_VIDEO:
403 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
404 discrete_type_type = MAILMIME_DISCRETE_TYPE_VIDEO;
405 break;
406
407 case MAILIMAP_MEDIA_BASIC_OTHER:
408 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
409 discrete_type_type = MAILMIME_DISCRETE_TYPE_EXTENSION;
410 discrete_type_extension = media_basic->med_basic_type;
411 if (discrete_type_extension == NULL) {
412 res = MAIL_ERROR_INVAL;
413 goto err;
414 }
415
416 break;
417
418 default:
419 res = MAIL_ERROR_INVAL;
420 goto err;
421 }
422
423 switch (mime_type_type) {
424 case MAILMIME_TYPE_DISCRETE_TYPE:
425 if (discrete_type_extension != NULL) {
426 discrete_type_extension = strdup(discrete_type_extension);
427 if (discrete_type_extension == NULL) {
428 res = MAIL_ERROR_MEMORY;
429 goto err;
430 }
431 }
432
433 discrete_type = mailmime_discrete_type_new(discrete_type_type,
434 discrete_type_extension);
435 if (discrete_type == NULL) {
436 if (discrete_type_extension != NULL)
437 free(discrete_type_extension);
438 res = MAIL_ERROR_MEMORY;
439 goto err;
440 }
441
442 break;
443
444 case MAILMIME_TYPE_COMPOSITE_TYPE:
445 composite_type = mailmime_composite_type_new(composite_type_type,
446 NULL);
447 if (composite_type == NULL) {
448 res = MAIL_ERROR_MEMORY;
449 goto err;
450 }
451
452 break;
453
454 default:
455 res = MAIL_ERROR_INVAL;
456 goto err;
457 }
458
459 mime_type = mailmime_type_new(mime_type_type, discrete_type, composite_type);
460 if (mime_type == NULL) {
461 res = MAIL_ERROR_MEMORY;
462 goto free;
463 }
464
465 r = imap_body_parameter_to_content(body_parameter, media_basic->med_subtype,
466 mime_type, &content);
467 if (r != MAIL_NO_ERROR) {
468 res = r;
469 goto free_type;
470 }
471
472 * result = content;
473
474 return MAIL_NO_ERROR;
475
476 free_type:
477 mailmime_type_free(mime_type);
478 free:
479 if (discrete_type != NULL)
480 mailmime_discrete_type_free(discrete_type);
481 if (composite_type != NULL)
482 mailmime_composite_type_free(composite_type);
483 err:
484 return res;
485}
486
487static int
488imap_disposition_to_mime_disposition(struct mailimap_body_fld_dsp * imap_dsp,
489 struct mailmime_disposition ** result)
490{
491 size_t cur_token;
492 int r;
493 struct mailmime_disposition_type * dsp_type;
494 struct mailmime_disposition * dsp;
495 clist * parameters;
496 int res;
497
498 cur_token = 0;
499 r = mailmime_disposition_type_parse(imap_dsp->dsp_type,
500 strlen(imap_dsp->dsp_type), &cur_token, &dsp_type);
501 if (r != MAILIMF_NO_ERROR) {
502 res = MAILIMF_ERROR_PARSE;
503 goto err;
504 }
505
506 parameters = clist_new();
507 if (parameters == NULL) {
508 res = MAIL_ERROR_MEMORY;
509 goto err;
510 }
511
512 if (imap_dsp->dsp_attributes != NULL) {
513 clistiter * cur;
514
515 for(cur = clist_begin(imap_dsp->dsp_attributes->pa_list) ; cur != NULL ;
516 cur = clist_next(cur)) {
517 struct mailimap_single_body_fld_param * imap_param;
518 struct mailmime_disposition_parm * dsp_param;
519 struct mailmime_parameter * param;
520 char * filename;
521 char * creation_date;
522 char * modification_date;
523 char * read_date;
524 size_t size;
525 int type;
526
527 imap_param = clist_content(cur);
528
529 filename = NULL;
530 creation_date = NULL;
531 modification_date = NULL;
532 read_date = NULL;
533 size = 0;
534 param = NULL;
535
536 type = mailmime_disposition_guess_type(imap_param->pa_name,
537 strlen(imap_param->pa_name), 0);
538
539 switch (type) {
540 case MAILMIME_DISPOSITION_PARM_FILENAME:
541 if (strcasecmp(imap_param->pa_name, "filename") != 0) {
542 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
543 break;
544 }
545 filename = strdup(imap_param->pa_value);
546 if (filename == NULL) {
547 res = MAIL_ERROR_MEMORY;
548 goto free_dsp_type;
549 }
550 break;
551
552 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
553 if (strcasecmp(imap_param->pa_name, "creation-date") != 0) {
554 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
555 break;
556 }
557 creation_date = strdup(imap_param->pa_value);
558 if (creation_date == NULL) {
559 res = MAIL_ERROR_MEMORY;
560 goto free_dsp_type;
561 }
562 break;
563
564 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
565 if (strcasecmp(imap_param->pa_name, "modification-date") != 0) {
566 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
567 break;
568 }
569 modification_date = strdup(imap_param->pa_value);
570 if (modification_date == NULL) {
571 res = MAIL_ERROR_MEMORY;
572 goto free_dsp_type;
573 }
574 break;
575
576 case MAILMIME_DISPOSITION_PARM_READ_DATE:
577 if (strcasecmp(imap_param->pa_name, "read-date") != 0) {
578 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
579 break;
580 }
581 read_date = strdup(imap_param->pa_value);
582 if (read_date == NULL) {
583 res = MAIL_ERROR_MEMORY;
584 goto free_dsp_type;
585 }
586 break;
587
588 case MAILMIME_DISPOSITION_PARM_SIZE:
589 if (strcasecmp(imap_param->pa_name, "size") != 0) {
590 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
591 break;
592 }
593 size = strtoul(imap_param->pa_value, NULL, 10);
594 break;
595 }
596
597 if (type == MAILMIME_DISPOSITION_PARM_PARAMETER) {
598 char * name;
599 char * value;
600
601 name = strdup(imap_param->pa_name);
602 if (name == NULL) {
603 res = MAIL_ERROR_MEMORY;
604 goto free_dsp_type;
605 }
606
607 value = strdup(imap_param->pa_value);
608 if (value == NULL) {
609 res = MAIL_ERROR_MEMORY;
610 free(name);
611 goto free_dsp_type;
612 }
613
614 param = mailmime_parameter_new(name, value);
615 if (param == NULL) {
616 free(value);
617 free(name);
618 res = MAIL_ERROR_MEMORY;
619 goto free_dsp_type;
620 }
621
622 }
623
624 dsp_param = mailmime_disposition_parm_new(type, filename,
625 creation_date,
626 modification_date,
627 read_date,
628 size, param);
629 if (dsp_param == NULL) {
630 if (filename != NULL)
631 free(filename);
632 if (creation_date != NULL)
633 free(creation_date);
634 if (modification_date != NULL)
635 free(modification_date);
636 if (read_date != NULL)
637 free(read_date);
638 if (param != NULL)
639 mailmime_parameter_free(param);
640 res = MAIL_ERROR_MEMORY;
641 goto free_list;
642 }
643
644 r = clist_append(parameters, dsp_param);
645 if (r != 0) {
646 mailmime_disposition_parm_free(dsp_param);
647 res = MAIL_ERROR_MEMORY;
648 goto free_list;
649 }
650 }
651 }
652
653 dsp = mailmime_disposition_new(dsp_type, parameters);
654 if (dsp == NULL) {
655 res = MAIL_ERROR_MEMORY;
656 goto free_list;
657 }
658
659 * result = dsp;
660
661 return MAIL_NO_ERROR;
662
663 free_list:
664 clist_foreach(parameters,
665 (clist_func) mailmime_disposition_parm_free, NULL);
666 clist_free(parameters);
667 free_dsp_type:
668 mailmime_disposition_type_free(dsp_type);
669 err:
670 return res;
671}
672
673static int
674imap_language_to_mime_language(struct mailimap_body_fld_lang * imap_lang,
675 struct mailmime_language ** result)
676{
677 clist * list;
678 clistiter * cur;
679 int res;
680 char * single;
681 int r;
682 struct mailmime_language * lang;
683
684 list = clist_new();
685 if (list == NULL) {
686 res = MAIL_ERROR_MEMORY;
687 goto err;
688 }
689
690 switch (imap_lang->lg_type) {
691 case MAILIMAP_BODY_FLD_LANG_SINGLE:
692 if (imap_lang->lg_data.lg_single != NULL) {
693 single = strdup(imap_lang->lg_data.lg_single);
694 if (single == NULL) {
695 res = MAIL_ERROR_MEMORY;
696 goto free;
697 }
698 r = clist_append(list, single);
699 if (r < 0) {
700 free(single);
701 res = MAIL_ERROR_MEMORY;
702 goto free;
703 }
704 }
705
706 break;
707
708 case MAILIMAP_BODY_FLD_LANG_LIST:
709 for(cur = clist_begin(imap_lang->lg_data.lg_list) ;
710 cur != NULL ; cur = clist_next(cur)) {
711 single = strdup(clist_content(cur));
712 if (single == NULL) {
713 res = MAIL_ERROR_MEMORY;
714 goto free;
715 }
716 r = clist_append(list, single);
717 if (r < 0) {
718 free(single);
719 res = MAIL_ERROR_MEMORY;
720 goto free;
721 }
722 }
723 }
724
725 lang = mailmime_language_new(list);
726 if (lang == NULL) {
727 res = MAIL_ERROR_MEMORY;
728 goto free;
729 }
730
731 * result = lang;
732
733 return MAIL_NO_ERROR;
734
735 free:
736 clist_foreach(list, (clist_func) free, NULL);
737 clist_free(list);
738 err:
739 return res;
740}
741
742static int
743imap_body_fields_to_mime_fields(struct mailimap_body_fields * body_fields,
744 struct mailimap_body_fld_dsp * imap_dsp,
745 struct mailimap_body_fld_lang * imap_lang,
746 struct mailmime_fields ** result,
747 uint32_t * pbody_size)
748{
749 struct mailmime_field * mime_field;
750 struct mailmime_fields * mime_fields;
751 clist * list;
752 char * id;
753 struct mailmime_mechanism * encoding;
754 char * description;
755 struct mailmime_disposition * dsp;
756 struct mailmime_language * lang;
757 int type;
758 int r;
759 int res;
760
761 list = clist_new();
762 if (list == NULL) {
763 res = MAIL_ERROR_MEMORY;
764 goto err;
765 }
766
767 if (body_fields != NULL) {
768
769 if (pbody_size != NULL)
770 * pbody_size = body_fields->bd_size;
771
772 if (body_fields->bd_id != NULL) {
773 type = MAILMIME_FIELD_ID;
774 id = strdup(body_fields->bd_id);
775 if (id == NULL) {
776 res = MAIL_ERROR_MEMORY;
777 goto free_list;
778 }
779
780 mime_field = mailmime_field_new(type, NULL,
781 NULL, id, NULL, 0, NULL, NULL);
782 if (mime_field == NULL) {
783 free(id);
784 res = MAIL_ERROR_MEMORY;
785 goto free_list;
786 }
787
788 r = clist_append(list, mime_field);
789 if (r != 0) {
790 mailmime_field_free(mime_field);
791 res = MAIL_ERROR_MEMORY;
792 goto free_list;
793 }
794 }
795
796 if (body_fields->bd_description != NULL) {
797 type = MAILMIME_FIELD_DESCRIPTION;
798 description = strdup(body_fields->bd_description);
799 if (description == NULL) {
800 res = MAIL_ERROR_MEMORY;
801 goto free_list;
802 }
803
804 mime_field = mailmime_field_new(type, NULL,
805 NULL, NULL, description, 0, NULL, NULL);
806 if (mime_field == NULL) {
807 free(description);
808 res = MAIL_ERROR_MEMORY;
809 goto free_list;
810 }
811
812 r = clist_append(list, mime_field);
813 if (r != 0) {
814 mailmime_field_free(mime_field);
815 res = MAIL_ERROR_MEMORY;
816 goto free_list;
817 }
818 }
819
820 if (body_fields->bd_encoding != NULL) {
821 char * encoding_value;
822 int encoding_type;
823
824 type = MAILMIME_FIELD_TRANSFER_ENCODING;
825
826 encoding_value = NULL;
827 switch (body_fields->bd_encoding->enc_type) {
828 case MAILIMAP_BODY_FLD_ENC_7BIT:
829 encoding_type = MAILMIME_MECHANISM_7BIT;
830 break;
831 case MAILIMAP_BODY_FLD_ENC_8BIT:
832 encoding_type = MAILMIME_MECHANISM_8BIT;
833 break;
834 case MAILIMAP_BODY_FLD_ENC_BINARY:
835 encoding_type = MAILMIME_MECHANISM_BINARY;
836 break;
837 case MAILIMAP_BODY_FLD_ENC_BASE64:
838 encoding_type = MAILMIME_MECHANISM_BASE64;
839 break;
840 case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE:
841 encoding_type = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
842 break;
843 case MAILIMAP_BODY_FLD_ENC_OTHER:
844 encoding_type = MAILMIME_MECHANISM_TOKEN;
845 encoding_value = strdup(body_fields->bd_encoding->enc_value);
846 if (encoding_value == NULL) {
847 res = MAIL_ERROR_MEMORY;
848 goto free_list;
849 }
850 break;
851 default:
852 res = MAIL_ERROR_INVAL;
853 goto free_list;
854 }
855
856 encoding = mailmime_mechanism_new(encoding_type, encoding_value);
857 if (encoding == NULL) {
858 if (encoding_value != NULL)
859 free(encoding_value);
860 res = MAIL_ERROR_MEMORY;
861 goto free_list;
862 }
863
864 mime_field = mailmime_field_new(type, NULL,
865 encoding, NULL, NULL, 0, NULL, NULL);
866 if (mime_field == NULL) {
867 mailmime_mechanism_free(encoding);
868 res = MAIL_ERROR_MEMORY;
869 goto free_list;
870 }
871
872 r = clist_append(list, mime_field);
873 if (r != 0) {
874 mailmime_field_free(mime_field);
875 res = MAIL_ERROR_MEMORY;
876 goto free_list;
877 }
878 }
879 }
880
881 if (imap_dsp != NULL) {
882 r = imap_disposition_to_mime_disposition(imap_dsp, &dsp);
883 if (r != MAIL_ERROR_PARSE) {
884 if (r != MAIL_NO_ERROR) {
885 res = MAIL_ERROR_MEMORY;
886 goto free_list;
887 }
888
889 type = MAILMIME_FIELD_DISPOSITION;
890
891 mime_field = mailmime_field_new(type, NULL,
892 NULL, NULL, NULL, 0, dsp, NULL);
893 if (mime_field == NULL) {
894 mailmime_disposition_free(dsp);
895 res = MAIL_ERROR_MEMORY;
896 goto free_list;
897 }
898
899 r = clist_append(list, mime_field);
900 if (r != 0) {
901 mailmime_field_free(mime_field);
902 res = MAIL_ERROR_MEMORY;
903 goto free_list;
904 }
905 }
906 }
907
908 if (imap_lang != NULL) {
909 r = imap_language_to_mime_language(imap_lang, &lang);
910 if (r != MAIL_NO_ERROR) {
911 res = MAIL_ERROR_MEMORY;
912 goto free_list;
913 }
914
915 type = MAILMIME_FIELD_LANGUAGE;
916
917 mime_field = mailmime_field_new(type, NULL,
918 NULL, NULL, NULL, 0, NULL, lang);
919 if (mime_field == NULL) {
920 mailmime_language_free(lang);
921 res = MAIL_ERROR_MEMORY;
922 goto free_list;
923 }
924
925 r = clist_append(list, mime_field);
926 if (r != 0) {
927 mailmime_field_free(mime_field);
928 res = MAIL_ERROR_MEMORY;
929 goto free_list;
930 }
931 }
932
933 mime_fields = mailmime_fields_new(list);
934 if (mime_fields == NULL) {
935 res = MAIL_ERROR_MEMORY;
936 goto free_list;
937 }
938
939 * result = mime_fields;
940
941 return MAIL_NO_ERROR;
942
943 free_list:
944 clist_foreach(list, (clist_func) mailmime_fields_free, NULL);
945 clist_free(list);
946 err:
947 return res;
948}
949
950static int
951imap_body_type_basic_to_body(struct mailimap_body_type_basic *
952 imap_type_basic,
953 struct mailimap_body_ext_1part *
954 body_ext_1part,
955 struct mailmime ** result)
956{
957 struct mailmime_content * content;
958 struct mailmime_fields * mime_fields;
959 struct mailmime * body;
960 int r;
961 int res;
962 uint32_t mime_size;
963
964 r = imap_body_media_basic_to_content_type(imap_type_basic->bd_media_basic,
965 imap_type_basic->bd_fields->bd_parameter, &content);
966 if (r != MAIL_NO_ERROR) {
967 res = r;
968 goto err;
969 }
970
971 if (body_ext_1part != NULL)
972 r = imap_body_fields_to_mime_fields(imap_type_basic->bd_fields,
973 body_ext_1part->bd_disposition,
974 body_ext_1part->bd_language,
975 &mime_fields, &mime_size);
976 else
977 r = imap_body_fields_to_mime_fields(imap_type_basic->bd_fields,
978 NULL, NULL,
979 &mime_fields, &mime_size);
980 if (r != MAIL_NO_ERROR) {
981 res = r;
982 goto free_content;
983 }
984
985 body = mailmime_new(MAILMIME_SINGLE, NULL,
986 mime_size, mime_fields, content,
987 NULL, NULL, NULL, NULL, NULL, NULL);
988
989 if (body == NULL) {
990 res = MAIL_ERROR_MEMORY;
991 goto free_fields;
992 }
993
994 * result = body;
995
996 return MAIL_NO_ERROR;
997
998 free_fields:
999 mailmime_fields_free(mime_fields);
1000 free_content:
1001 mailmime_content_free(content);
1002 err:
1003 return res;
1004}
1005
1006static int
1007imap_body_type_text_to_body(struct mailimap_body_type_text *
1008 imap_type_text,
1009 struct mailimap_body_ext_1part *
1010 body_ext_1part,
1011 struct mailmime ** result)
1012{
1013 struct mailmime_content * content;
1014 struct mailmime_fields * mime_fields;
1015 struct mailmime * body;
1016 int r;
1017 int res;
1018 uint32_t mime_size;
1019
1020 r = imap_body_type_text_to_content_type(imap_type_text->bd_media_text,
1021 imap_type_text->bd_fields->bd_parameter,
1022 &content);
1023 if (r != MAIL_NO_ERROR) {
1024 res = r;
1025 goto err;
1026 }
1027
1028 if (body_ext_1part == NULL) {
1029 r = imap_body_fields_to_mime_fields(imap_type_text->bd_fields,
1030 NULL, NULL,
1031 &mime_fields, &mime_size);
1032 }
1033 else {
1034 r = imap_body_fields_to_mime_fields(imap_type_text->bd_fields,
1035 body_ext_1part->bd_disposition,
1036 body_ext_1part->bd_language,
1037 &mime_fields, &mime_size);
1038 }
1039 if (r != MAIL_NO_ERROR) {
1040 res = r;
1041 goto free_content;
1042 }
1043
1044 body = mailmime_new(MAILMIME_SINGLE, NULL,
1045 mime_size, mime_fields, content,
1046 NULL, NULL, NULL, NULL, NULL, NULL);
1047
1048 if (body == NULL) {
1049 res = MAIL_ERROR_MEMORY;
1050 goto free_fields;
1051 }
1052
1053 * result = body;
1054
1055 return MAIL_NO_ERROR;
1056
1057 free_fields:
1058 mailmime_fields_free(mime_fields);
1059 free_content:
1060 mailmime_content_free(content);
1061 err:
1062 return res;
1063}
1064
1065static int
1066imap_body_parameter_to_content(struct mailimap_body_fld_param *
1067 body_parameter,
1068 char * subtype,
1069 struct mailmime_type * mime_type,
1070 struct mailmime_content ** result)
1071{
1072 clist * parameters;
1073 char * new_subtype;
1074 struct mailmime_content * content;
1075 int r;
1076 int res;
1077
1078 new_subtype = strdup(subtype);
1079 if (new_subtype == NULL) {
1080 res = MAIL_ERROR_MEMORY;
1081 goto err;
1082 }
1083
1084 parameters = clist_new();
1085 if (parameters == NULL) {
1086 res = MAIL_ERROR_MEMORY;
1087 goto free_subtype;
1088 }
1089
1090 if (body_parameter != NULL) {
1091 clistiter * cur;
1092
1093 for(cur = clist_begin(body_parameter->pa_list) ; cur != NULL ;
1094 cur = clist_next(cur)) {
1095 struct mailimap_single_body_fld_param * imap_param;
1096 struct mailmime_parameter * param;
1097 char * name;
1098 char * value;
1099
1100 imap_param = clist_content(cur);
1101 name = strdup(imap_param->pa_name);
1102 if (name == NULL) {
1103 res = MAIL_ERROR_MEMORY;
1104 goto free_parameters;
1105 }
1106
1107 value = strdup(imap_param->pa_value);
1108 if (value == NULL) {
1109 free(name);
1110 res = MAIL_ERROR_MEMORY;
1111 goto free_parameters;
1112 }
1113
1114 param = mailmime_parameter_new(name, value);
1115 if (param == NULL) {
1116 free(value);
1117 free(name);
1118 res = MAIL_ERROR_MEMORY;
1119 goto free_parameters;
1120 }
1121
1122 r = clist_append(parameters, param);
1123 if (r != 0) {
1124 mailmime_parameter_free(param);
1125 res = MAIL_ERROR_MEMORY;
1126 goto free_parameters;
1127 }
1128 }
1129 }
1130
1131 content = mailmime_content_new(mime_type, new_subtype, parameters);
1132 if (content == NULL) {
1133 res = MAIL_ERROR_MEMORY;
1134 goto free_parameters;
1135 }
1136
1137 * result = content;
1138
1139 return MAIL_NO_ERROR;
1140
1141 free_parameters:
1142 clist_foreach(parameters, (clist_func) mailmime_parameter_free, NULL);
1143 clist_free(parameters);
1144 free_subtype:
1145 free(new_subtype);
1146 err:
1147 return res;
1148}
1149
1150static int
1151imap_body_type_text_to_content_type(char * subtype,
1152 struct mailimap_body_fld_param *
1153 body_parameter,
1154 struct mailmime_content ** result)
1155{
1156 struct mailmime_content * content;
1157 struct mailmime_type * mime_type;
1158 struct mailmime_discrete_type * discrete_type;
1159 int r;
1160 int res;
1161
1162 discrete_type = NULL;
1163
1164 discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT,
1165 NULL);
1166 if (discrete_type == NULL) {
1167 res = MAIL_ERROR_MEMORY;
1168 goto err;
1169 }
1170
1171 mime_type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE,
1172 discrete_type, NULL);
1173 if (mime_type == NULL) {
1174 mailmime_discrete_type_free(discrete_type);
1175 res = MAIL_ERROR_MEMORY;
1176 goto err;
1177 }
1178
1179 r = imap_body_parameter_to_content(body_parameter, subtype,
1180 mime_type, &content);
1181 if (r != MAIL_NO_ERROR) {
1182 res = r;
1183 goto free_type;
1184 }
1185
1186 * result = content;
1187
1188 return MAIL_NO_ERROR;
1189
1190 free_type:
1191 mailmime_type_free(mime_type);
1192 err:
1193 return res;
1194}
1195
1196
1197static int
1198imap_body_type_msg_to_body(struct mailimap_body_type_msg *
1199 imap_type_msg,
1200 struct mailimap_body_ext_1part *
1201 body_ext_1part,
1202 struct mailmime ** result)
1203{
1204 struct mailmime * body;
1205 struct mailmime * msg_body;
1206 struct mailmime_fields * mime_fields;
1207 struct mailmime_composite_type * composite_type;
1208 struct mailmime_type * mime_type;
1209 struct mailmime_content * content_type;
1210 struct mailimf_fields * fields;
1211 int r;
1212 int res;
1213 uint32_t mime_size;
1214
1215 r = imap_body_fields_to_mime_fields(imap_type_msg->bd_fields,
1216 body_ext_1part->bd_disposition, body_ext_1part->bd_language,
1217 &mime_fields, &mime_size);
1218 if (r != MAIL_NO_ERROR) {
1219 res = r;
1220 goto err;
1221 }
1222
1223 r = imap_env_to_fields(imap_type_msg->bd_envelope, NULL, 0, &fields);
1224 if (r != MAIL_NO_ERROR) {
1225 res = r;
1226 goto free_mime_fields;
1227 }
1228
1229 r = imap_body_to_body(imap_type_msg->bd_body, &msg_body);
1230 if (r != MAIL_NO_ERROR) {
1231 res = r;
1232 goto free_fields;
1233 }
1234
1235 composite_type =
1236 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE,
1237 NULL);
1238 if (composite_type == NULL) {
1239 res = MAIL_ERROR_MEMORY;
1240 goto free_fields;
1241 }
1242
1243 mime_type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE,
1244 NULL, composite_type);
1245 if (mime_type == NULL) {
1246 mailmime_composite_type_free(composite_type);
1247 res = MAIL_ERROR_MEMORY;
1248 goto free_fields;
1249 }
1250
1251 r = imap_body_parameter_to_content(imap_type_msg->bd_fields->bd_parameter,
1252 "rfc822", mime_type, &content_type);
1253 if (r != MAIL_NO_ERROR) {
1254 mailmime_type_free(mime_type);
1255 res = MAIL_ERROR_MEMORY;
1256 goto free_fields;
1257 }
1258
1259 body = mailmime_new(MAILMIME_MESSAGE, NULL,
1260 mime_size, mime_fields, content_type,
1261 NULL, NULL, NULL, NULL, fields, msg_body);
1262
1263 if (body == NULL) {
1264 res = MAIL_ERROR_MEMORY;
1265 goto free_content;
1266 }
1267
1268 * result = body;
1269
1270 return MAIL_NO_ERROR;
1271
1272 free_content:
1273 mailmime_content_free(content_type);
1274 free_fields:
1275 mailimf_fields_free(fields);
1276 free_mime_fields:
1277 mailmime_fields_free(mime_fields);
1278 err:
1279 return res;
1280}
1281
1282
1283static int
1284imap_body_type_1part_to_body(struct mailimap_body_type_1part *
1285 type_1part,
1286 struct mailmime ** result)
1287{
1288 struct mailmime * body;
1289 int r;
1290 int res;
1291
1292 switch (type_1part->bd_type) {
1293 case MAILIMAP_BODY_TYPE_1PART_BASIC:
1294 r = imap_body_type_basic_to_body(type_1part->bd_data.bd_type_basic,
1295 type_1part->bd_ext_1part,
1296 &body);
1297 if (r != MAIL_NO_ERROR) {
1298 res = r;
1299 goto err;
1300 }
1301
1302 break;
1303 case MAILIMAP_BODY_TYPE_1PART_MSG:
1304 r = imap_body_type_msg_to_body(type_1part->bd_data.bd_type_msg,
1305 type_1part->bd_ext_1part,
1306 &body);
1307 if (r != MAIL_NO_ERROR) {
1308 res = r;
1309 goto err;
1310 }
1311
1312 break;
1313 case MAILIMAP_BODY_TYPE_1PART_TEXT:
1314 r = imap_body_type_text_to_body(type_1part->bd_data.bd_type_text,
1315 type_1part->bd_ext_1part,
1316 &body);
1317 if (r != MAIL_NO_ERROR) {
1318 res = r;
1319 goto err;
1320 }
1321
1322 break;
1323 }
1324
1325 * result = body;
1326
1327 return MAIL_NO_ERROR;
1328
1329 err:
1330 return res;
1331}
1332
1333static int
1334imap_body_type_mpart_to_body(struct mailimap_body_type_mpart *
1335 type_mpart,
1336 struct mailmime ** result)
1337{
1338 struct mailmime_fields * mime_fields;
1339 struct mailmime_composite_type * composite_type;
1340 struct mailmime_type * mime_type;
1341 struct mailmime_content * content_type;
1342 struct mailmime * body;
1343 clistiter * cur;
1344 clist * list;
1345 int r;
1346 int res;
1347 uint32_t mime_size;
1348
1349 r = imap_body_fields_to_mime_fields(NULL,
1350 type_mpart->bd_ext_mpart->bd_disposition,
1351 type_mpart->bd_ext_mpart->bd_language,
1352 &mime_fields, &mime_size);
1353 if (r != MAIL_NO_ERROR) {
1354 res = r;
1355 goto err;
1356 }
1357
1358 composite_type =
1359 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART,
1360 NULL);
1361 if (composite_type == NULL) {
1362 res = MAIL_ERROR_MEMORY;
1363 goto free_fields;
1364 }
1365
1366 mime_type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE,
1367 NULL, composite_type);
1368 if (mime_type == NULL) {
1369 mailmime_composite_type_free(composite_type);
1370 res = MAIL_ERROR_MEMORY;
1371 goto free_fields;
1372 }
1373
1374 r = imap_body_parameter_to_content(type_mpart->bd_ext_mpart->bd_parameter,
1375 type_mpart->bd_media_subtype,
1376 mime_type, &content_type);
1377 if (r != MAIL_NO_ERROR) {
1378 mailmime_type_free(mime_type);
1379 res = r;
1380 goto free_fields;
1381 }
1382
1383 list = clist_new();
1384 if (list == NULL) {
1385 res = MAIL_ERROR_MEMORY;
1386 goto free_content;
1387 }
1388
1389 for(cur = clist_begin(type_mpart->bd_list) ; cur != NULL ;
1390 cur = clist_next(cur)) {
1391 struct mailimap_body * imap_body;
1392 struct mailmime * sub_body;
1393
1394 imap_body = clist_content(cur);
1395
1396 r = imap_body_to_body(imap_body, &sub_body);
1397 if (r != MAIL_NO_ERROR) {
1398 res = r;
1399 goto free_list;
1400 }
1401
1402 r = clist_append(list, sub_body);
1403 if (r != 0) {
1404 mailmime_free(sub_body);
1405 res = r;
1406 goto free_list;
1407 }
1408 }
1409
1410 body = mailmime_new(MAILMIME_MULTIPLE, NULL,
1411 mime_size, mime_fields, content_type,
1412 NULL, NULL, NULL, list, NULL, NULL);
1413
1414 if (body == NULL) {
1415 res = MAIL_ERROR_MEMORY;
1416 goto err;
1417 }
1418
1419 * result = body;
1420
1421 return MAIL_NO_ERROR;
1422
1423 free_list:
1424 clist_foreach(list, (clist_func) mailmime_free, NULL);
1425 clist_free(list);
1426 free_content:
1427 mailmime_content_free(content_type);
1428 free_fields:
1429 mailmime_fields_free(mime_fields);
1430 err:
1431 return res;
1432}
1433
1434
1435int imap_body_to_body(struct mailimap_body * imap_body,
1436 struct mailmime ** result)
1437{
1438 struct mailmime * body;
1439 int r;
1440 int res;
1441
1442 switch (imap_body->bd_type) {
1443 case MAILIMAP_BODY_1PART:
1444 r = imap_body_type_1part_to_body(imap_body->bd_data.bd_body_1part, &body);
1445 if (r != MAIL_NO_ERROR) {
1446 res = r;
1447 goto err;
1448 }
1449 break;
1450 case MAILIMAP_BODY_MPART:
1451 r = imap_body_type_mpart_to_body(imap_body->bd_data.bd_body_mpart, &body);
1452 if (r != MAIL_NO_ERROR) {
1453 res = r;
1454 goto err;
1455 }
1456 break;
1457 default:
1458 return MAIL_ERROR_INVAL;
1459 }
1460
1461 * result = body;
1462
1463 return MAIL_NO_ERROR;
1464
1465 err:
1466 return res;
1467}
1468
1469int imap_address_to_mailbox(struct mailimap_address * imap_addr,
1470 struct mailimf_mailbox ** result)
1471{
1472 char * dsp_name;
1473 char * addr;
1474 struct mailimf_mailbox * mb;
1475 int res;
1476
1477 if (imap_addr->ad_personal_name == NULL)
1478 dsp_name = NULL;
1479 else {
1480 dsp_name = strdup(imap_addr->ad_personal_name);
1481 if (dsp_name == NULL) {
1482 res = MAIL_ERROR_MEMORY;
1483 goto err;
1484 }
1485 }
1486
1487 if (imap_addr->ad_host_name == NULL) {
1488 addr = strdup(imap_addr->ad_mailbox_name);
1489 if (addr == NULL) {
1490 res = MAIL_ERROR_MEMORY;
1491 goto free_name;
1492 }
1493 }
1494 else {
1495 addr = malloc(strlen(imap_addr->ad_mailbox_name) +
1496 strlen(imap_addr->ad_host_name) + 2);
1497 if (addr == NULL) {
1498 res = MAIL_ERROR_MEMORY;
1499 goto free_name;
1500 }
1501 strcpy(addr, imap_addr->ad_mailbox_name);
1502 strcat(addr, "@");
1503 strcat(addr, imap_addr->ad_host_name);
1504 }
1505
1506 mb = mailimf_mailbox_new(dsp_name, addr);
1507 if (mb == NULL) {
1508 res = MAIL_ERROR_MEMORY;
1509 goto free_addr;
1510 }
1511
1512 * result = mb;
1513
1514 return MAIL_NO_ERROR;
1515
1516 free_addr:
1517 free(addr);
1518 free_name:
1519 free(dsp_name);
1520 err:
1521 return res;
1522}
1523
1524int imap_address_to_address(struct mailimap_address * imap_addr,
1525 struct mailimf_address ** result)
1526{
1527 struct mailimf_address * addr;
1528 struct mailimf_mailbox * mb;
1529 int r;
1530 int res;
1531
1532 r = imap_address_to_mailbox(imap_addr, &mb);
1533 if (r != MAIL_NO_ERROR) {
1534 res = r;
1535 goto err;
1536 }
1537
1538 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
1539 if (addr == NULL) {
1540 res = MAIL_ERROR_MEMORY;
1541 goto free_mb;
1542 }
1543
1544 * result = addr;
1545
1546 return MAIL_NO_ERROR;
1547
1548 free_mb:
1549 mailimf_mailbox_free(mb);
1550 err:
1551 return res;
1552}
1553
1554int
1555imap_mailbox_list_to_mailbox_list(clist * imap_mailbox_list,
1556 struct mailimf_mailbox_list ** result)
1557{
1558 clistiter * cur;
1559 clist * list;
1560 struct mailimf_mailbox_list * mb_list;
1561 int r;
1562 int res;
1563
1564 list = clist_new();
1565 if (list == NULL) {
1566 res = MAIL_ERROR_MEMORY;
1567 goto err;
1568 }
1569
1570 for(cur = clist_begin(imap_mailbox_list) ; cur != NULL ;
1571 cur = clist_next(cur)) {
1572 struct mailimap_address * imap_addr;
1573 struct mailimf_mailbox * mb;
1574
1575 imap_addr = clist_content(cur);
1576
1577 if (imap_addr->ad_mailbox_name == NULL)
1578 continue;
1579
1580 r = imap_address_to_mailbox(imap_addr, &mb);
1581 if (r != MAIL_NO_ERROR) {
1582 res = r;
1583 goto free_list;
1584 }
1585
1586 r = clist_append(list, mb);
1587 if (r != 0) {
1588 mailimf_mailbox_free(mb);
1589 res = MAIL_ERROR_MEMORY;
1590 goto free_list;
1591 }
1592 }
1593
1594 mb_list = mailimf_mailbox_list_new(list);
1595 if (mb_list == NULL) {
1596 res = MAIL_ERROR_MEMORY;
1597 goto free_list;
1598 }
1599
1600 * result = mb_list;
1601
1602 return MAIL_NO_ERROR;
1603
1604 free_list:
1605 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
1606 clist_free(list);
1607 err:
1608 return MAIL_ERROR_MEMORY;
1609}
1610
1611
1612
1613/*
1614 at exit, imap_mb_list will fall on the last element of the group,
1615 where mailbox name will be NIL, so that imap_mailbox_list_to_address_list
1616 can continue
1617*/
1618
1619static int imap_mailbox_list_to_group(clist * imap_mb_list, clistiter ** iter,
1620 struct mailimf_group ** result)
1621{
1622 clistiter * imap_mailbox_listiter;
1623 clist * list;
1624 struct mailimf_group * group;
1625 struct mailimap_address * imap_addr;
1626 char * group_name;
1627 clistiter * cur;
1628 struct mailimf_mailbox_list * mb_list;
1629 int r;
1630 int res;
1631
1632 imap_mailbox_listiter = * iter;
1633
1634 imap_addr = clist_content(imap_mailbox_listiter);
1635 if (imap_addr->ad_mailbox_name == NULL) {
1636 res = MAIL_ERROR_INVAL;
1637 goto err;
1638 }
1639
1640 group_name = strdup(imap_addr->ad_mailbox_name);
1641 if (group_name == NULL) {
1642 res = MAIL_ERROR_MEMORY;
1643 goto err;
1644 }
1645
1646 list = clist_new();
1647 if (list == NULL) {
1648 res = MAIL_ERROR_MEMORY;
1649 goto free_group_name;
1650 }
1651
1652 for(cur = clist_next(imap_mailbox_listiter) ; cur != NULL ;
1653 cur = clist_next(cur)) {
1654 struct mailimf_mailbox * mb;
1655
1656 imap_addr = clist_content(cur);
1657
1658 if (imap_addr->ad_mailbox_name == NULL) {
1659 break;
1660 }
1661
1662 r = imap_address_to_mailbox(imap_addr, &mb);
1663 if (r != MAIL_NO_ERROR) {
1664 res = r;
1665 goto free_list;
1666 }
1667
1668 r = clist_append(list, mb);
1669 if (r != 0) {
1670 mailimf_mailbox_free(mb);
1671 res = MAIL_ERROR_MEMORY;
1672 goto free_list;
1673 }
1674 }
1675
1676 mb_list = mailimf_mailbox_list_new(list);
1677 if (mb_list == NULL) {
1678 res = MAIL_ERROR_MEMORY;
1679 goto free_list;
1680 }
1681
1682 group = mailimf_group_new(group_name, mb_list);
1683 if (group == NULL) {
1684 mailimf_mailbox_list_free(mb_list);
1685 res = MAIL_ERROR_MEMORY;
1686 goto free_group_name;
1687 }
1688
1689 * result = group;
1690 * iter = cur;
1691
1692 return MAIL_NO_ERROR;
1693
1694 free_list:
1695 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
1696 clist_free(list);
1697 free_group_name:
1698 free(group_name);
1699 err:
1700 return res;
1701}
1702
1703int
1704imap_mailbox_list_to_address_list(clist * imap_mailbox_list,
1705 struct mailimf_address_list ** result)
1706{
1707 clistiter * cur;
1708 clist * list;
1709 struct mailimf_address_list * addr_list;
1710 int r;
1711 int res;
1712
1713 list = clist_new();
1714 if (list == NULL) {
1715 res = MAIL_ERROR_MEMORY;
1716 goto err;
1717 }
1718
1719 for(cur = clist_begin(imap_mailbox_list) ; cur != NULL ;
1720 cur = clist_next(cur)) {
1721 struct mailimap_address * imap_addr;
1722 struct mailimf_address * addr;
1723
1724 imap_addr = clist_content(cur);
1725
1726 if (imap_addr->ad_mailbox_name == NULL)
1727 continue;
1728
1729 if ((imap_addr->ad_host_name == NULL) &&
1730 (imap_addr->ad_mailbox_name != NULL)) {
1731 struct mailimf_group * group;
1732
1733 r = imap_mailbox_list_to_group(imap_mailbox_list, &cur, &group);
1734 if (r != MAIL_NO_ERROR) {
1735 res = r;
1736 goto free_list;
1737 }
1738
1739 addr = mailimf_address_new(MAILIMF_ADDRESS_GROUP, NULL, group);
1740 if (addr == NULL) {
1741 mailimf_group_free(group);
1742 res = MAIL_ERROR_MEMORY;
1743 goto free_list;
1744 }
1745 }
1746 else {
1747 r = imap_address_to_address(imap_addr, &addr);
1748 if (r != MAIL_NO_ERROR) {
1749 res = r;
1750 goto free_list;
1751 }
1752 }
1753
1754 r = clist_append(list, addr);
1755 if (r != 0) {
1756 mailimf_address_free(addr);
1757 res = MAIL_ERROR_MEMORY;
1758 goto free_list;
1759 }
1760 }
1761
1762 addr_list = mailimf_address_list_new(list);
1763 if (addr_list == NULL) {
1764 res = MAIL_ERROR_MEMORY;
1765 goto free_list;
1766 }
1767
1768 * result = addr_list;
1769
1770 return MAIL_NO_ERROR;
1771
1772 free_list:
1773 clist_foreach(list, (clist_func) mailimf_address_free, NULL);
1774 clist_free(list);
1775 err:
1776 return res;
1777}
1778
1779
1780int imap_add_envelope_fetch_att(struct mailimap_fetch_type * fetch_type)
1781{
1782 struct mailimap_fetch_att * fetch_att;
1783 int res;
1784 int r;
1785 char * header;
1786 clist * hdrlist;
1787 struct mailimap_header_list * imap_hdrlist;
1788 struct mailimap_section * section;
1789
1790 fetch_att = mailimap_fetch_att_new_envelope();
1791 if (fetch_att == NULL) {
1792 res = MAIL_ERROR_MEMORY;
1793 goto err;
1794 }
1795
1796 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
1797 if (r != MAILIMAP_NO_ERROR) {
1798 mailimap_fetch_att_free(fetch_att);
1799 res = MAIL_ERROR_MEMORY;
1800 goto err;
1801 }
1802
1803 header = strdup("References");
1804 if (header == NULL) {
1805 mailimap_fetch_att_free(fetch_att);
1806 res = MAIL_ERROR_MEMORY;
1807 goto err;
1808 }
1809
1810 hdrlist = clist_new();
1811 if (hdrlist == NULL) {
1812 free(header);
1813 mailimap_fetch_att_free(fetch_att);
1814 res = MAIL_ERROR_MEMORY;
1815 goto err;
1816 }
1817
1818 r = clist_append(hdrlist, header);
1819 if (r < 0) {
1820 free(header);
1821 clist_foreach(hdrlist, (clist_func) free, NULL);
1822 clist_free(hdrlist);
1823 mailimap_fetch_att_free(fetch_att);
1824 res = MAIL_ERROR_MEMORY;
1825 goto err;
1826 }
1827
1828 imap_hdrlist = mailimap_header_list_new(hdrlist);
1829 if (imap_hdrlist == 0) {
1830 clist_foreach(hdrlist, (clist_func) free, NULL);
1831 clist_free(hdrlist);
1832 mailimap_fetch_att_free(fetch_att);
1833 res = MAIL_ERROR_MEMORY;
1834 goto err;
1835 }
1836
1837 section = mailimap_section_new_header_fields(imap_hdrlist);
1838 if (section == NULL) {
1839 mailimap_header_list_free(imap_hdrlist);
1840 mailimap_fetch_att_free(fetch_att);
1841 res = MAIL_ERROR_MEMORY;
1842 goto err;
1843 }
1844
1845 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
1846 if (fetch_att == NULL) {
1847 mailimap_section_free(section);
1848 res = MAIL_ERROR_MEMORY;
1849 goto err;
1850 }
1851
1852 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
1853 if (r != MAILIMAP_NO_ERROR) {
1854 mailimap_fetch_att_free(fetch_att);
1855 res = MAIL_ERROR_MEMORY;
1856 goto err;
1857 }
1858
1859 return MAIL_NO_ERROR;
1860
1861 err:
1862 return res;
1863}
1864
1865
1866int imap_env_to_fields(struct mailimap_envelope * env,
1867 char * ref_str, size_t ref_size,
1868 struct mailimf_fields ** result)
1869{
1870 clist * list;
1871 struct mailimf_field * field;
1872 int r;
1873 struct mailimf_fields * fields;
1874 int res;
1875
1876 list = clist_new();
1877 if (list == NULL) {
1878 res = MAIL_ERROR_MEMORY;
1879 goto err;
1880 }
1881
1882 if (env->env_date != NULL) {
1883 size_t cur_token;
1884 struct mailimf_date_time * date_time;
1885
1886 cur_token = 0;
1887 r = mailimf_date_time_parse(env->env_date, strlen(env->env_date),
1888 &cur_token, &date_time);
1889
1890 if (r == MAILIMF_NO_ERROR) {
1891 struct mailimf_orig_date * orig;
1892
1893 orig = mailimf_orig_date_new(date_time);
1894 if (orig == NULL) {
1895 mailimf_date_time_free(date_time);
1896 res = MAIL_ERROR_MEMORY;
1897 goto free_list;
1898 }
1899
1900 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
1901 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1902 NULL, orig, NULL,
1903 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1904 NULL, NULL, NULL, NULL, NULL);
1905 if (field == NULL) {
1906 mailimf_orig_date_free(orig);
1907 res = MAIL_ERROR_MEMORY;
1908 goto free_list;
1909 }
1910
1911 r = clist_append(list, field);
1912 if (r != 0) {
1913 mailimf_field_free(field);
1914 res = MAIL_ERROR_MEMORY;
1915 goto free_list;
1916 }
1917 }
1918 }
1919
1920 if (env->env_subject != NULL) {
1921 char * subject;
1922 struct mailimf_subject * subject_field;
1923
1924 subject = strdup(env->env_subject);
1925 if (subject == NULL) {
1926 res = MAIL_ERROR_MEMORY;
1927 goto free_list;
1928 }
1929
1930
1931 subject_field = mailimf_subject_new(subject);
1932 if (subject_field == NULL) {
1933 free(subject);
1934 res = MAIL_ERROR_MEMORY;
1935 goto free_list;
1936 }
1937
1938 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
1939 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1940 NULL, NULL, NULL,
1941 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1942 NULL, subject_field, NULL, NULL, NULL);
1943 if (field == NULL) {
1944 mailimf_subject_free(subject_field);
1945 res = MAIL_ERROR_MEMORY;
1946 goto free_list;
1947 }
1948
1949 r = clist_append(list, field);
1950 if (r != 0) {
1951 mailimf_field_free(field);
1952 res = MAIL_ERROR_MEMORY;
1953 goto free_list;
1954 }
1955 }
1956
1957 if (env->env_from != NULL) {
1958 if (env->env_from->frm_list != NULL) {
1959 struct mailimf_mailbox_list * mb_list;
1960 struct mailimf_from * from;
1961
1962 r = imap_mailbox_list_to_mailbox_list(env->env_from->frm_list, &mb_list);
1963
1964 if (r != MAIL_NO_ERROR) {
1965 res = r;
1966 goto free_list;
1967 }
1968
1969 from = mailimf_from_new(mb_list);
1970 if (from == NULL) {
1971 mailimf_mailbox_list_free(mb_list);
1972 res = MAIL_ERROR_MEMORY;
1973 goto free_list;
1974 }
1975
1976 field = mailimf_field_new(MAILIMF_FIELD_FROM,
1977 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1978 NULL, NULL, from,
1979 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1980 NULL, NULL, NULL, NULL, NULL);
1981 if (field == NULL) {
1982 mailimf_from_free(from);
1983 res = MAIL_ERROR_MEMORY;
1984 goto free_list;
1985 }
1986
1987 r = clist_append(list, field);
1988 if (r != 0) {
1989 mailimf_field_free(field);
1990 res = MAIL_ERROR_MEMORY;
1991 goto free_list;
1992 }
1993 }
1994 }
1995
1996 if (env->env_sender != NULL) {
1997 if (env->env_sender->snd_list != NULL) {
1998 struct mailimf_sender * sender;
1999 struct mailimf_mailbox * mb;
2000
2001 r = imap_address_to_mailbox(clist_begin(env->env_sender->snd_list)->data, &mb);
2002
2003 if (r != MAIL_NO_ERROR) {
2004 res = r;
2005 goto free_list;
2006 }
2007
2008 sender = mailimf_sender_new(mb);
2009 if (sender == NULL) {
2010 mailimf_mailbox_free(mb);
2011 res = MAIL_ERROR_MEMORY;
2012 goto free_list;
2013 }
2014
2015 field = mailimf_field_new(MAILIMF_FIELD_SENDER,
2016 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2017 NULL, NULL, NULL,
2018 sender, NULL, NULL, NULL, NULL, NULL, NULL,
2019 NULL, NULL, NULL, NULL, NULL);
2020 if (field == NULL) {
2021 mailimf_sender_free(sender);
2022 res = MAIL_ERROR_MEMORY;
2023 goto free_list;
2024 }
2025
2026 r = clist_append(list, field);
2027 if (r != 0) {
2028 mailimf_field_free(field);
2029 res = MAIL_ERROR_MEMORY;
2030 goto free_list;
2031 }
2032 }
2033 }
2034
2035 if (env->env_reply_to != NULL) {
2036 if (env->env_reply_to->rt_list != NULL) {
2037 struct mailimf_address_list * addr_list;
2038 struct mailimf_reply_to * reply_to;
2039
2040 r = imap_mailbox_list_to_address_list(env->env_reply_to->rt_list,
2041 &addr_list);
2042
2043 if (r != MAIL_NO_ERROR) {
2044 res = r;
2045 goto free_list;
2046 }
2047
2048 reply_to = mailimf_reply_to_new(addr_list);
2049 if (reply_to == NULL) {
2050 mailimf_address_list_free(addr_list);
2051 res = MAIL_ERROR_MEMORY;
2052 goto free_list;
2053 }
2054
2055 field = mailimf_field_new(MAILIMF_FIELD_REPLY_TO,
2056 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2057 NULL, NULL, NULL,
2058 NULL, reply_to, NULL, NULL, NULL, NULL, NULL,
2059 NULL, NULL, NULL, NULL, NULL);
2060 if (field == NULL) {
2061 mailimf_reply_to_free(reply_to);
2062 res = MAIL_ERROR_MEMORY;
2063 goto free_list;
2064 }
2065
2066 r = clist_append(list, field);
2067 if (r != 0) {
2068 mailimf_field_free(field);
2069 res = MAIL_ERROR_MEMORY;
2070 goto free_list;
2071 }
2072 }
2073 }
2074
2075 if (env->env_to != NULL) {
2076 if (env->env_to->to_list != NULL) {
2077 struct mailimf_address_list * addr_list;
2078 struct mailimf_to * to;
2079
2080 r = imap_mailbox_list_to_address_list(env->env_to->to_list, &addr_list);
2081
2082 if (r != MAIL_NO_ERROR) {
2083 res = r;
2084 goto free_list;
2085 }
2086
2087 to = mailimf_to_new(addr_list);
2088 if (to == NULL) {
2089 mailimf_address_list_free(addr_list);
2090 res = MAIL_ERROR_MEMORY;
2091 goto free_list;
2092 }
2093
2094 field = mailimf_field_new(MAILIMF_FIELD_TO,
2095 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2096 NULL, NULL, NULL,
2097 NULL, NULL, to, NULL, NULL, NULL, NULL,
2098 NULL, NULL, NULL, NULL, NULL);
2099 if (field == NULL) {
2100 mailimf_to_free(to);
2101 res = MAIL_ERROR_MEMORY;
2102 goto free_list;
2103 }
2104
2105 r = clist_append(list, field);
2106 if (r != 0) {
2107 mailimf_field_free(field);
2108 res = MAIL_ERROR_MEMORY;
2109 goto free_list;
2110 }
2111 }
2112 }
2113
2114 if (env->env_cc != NULL) {
2115 if (env->env_cc->cc_list != NULL) {
2116 struct mailimf_address_list * addr_list;
2117 struct mailimf_cc * cc;
2118
2119 r = imap_mailbox_list_to_address_list(env->env_cc->cc_list, &addr_list);
2120
2121 if (r != MAIL_NO_ERROR) {
2122 res = r;
2123 goto free_list;
2124 }
2125
2126 cc = mailimf_cc_new(addr_list);
2127 if (cc == NULL) {
2128 mailimf_address_list_free(addr_list);
2129 res = MAIL_ERROR_MEMORY;
2130 goto free_list;
2131 }
2132
2133 field = mailimf_field_new(MAILIMF_FIELD_CC,
2134 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2135 NULL, NULL, NULL,
2136 NULL, NULL, NULL, cc, NULL, NULL, NULL,
2137 NULL, NULL, NULL, NULL, NULL);
2138 if (field == NULL) {
2139 mailimf_cc_free(cc);
2140 res = MAIL_ERROR_MEMORY;
2141 goto free_list;
2142 }
2143
2144 r = clist_append(list, field);
2145 if (r != 0) {
2146 mailimf_field_free(field);
2147 res = MAIL_ERROR_MEMORY;
2148 goto free_list;
2149 }
2150 }
2151 }
2152
2153 if (env->env_bcc != NULL) {
2154 if (env->env_bcc->bcc_list != NULL) {
2155 struct mailimf_address_list * addr_list;
2156 struct mailimf_bcc * bcc;
2157
2158 r = imap_mailbox_list_to_address_list(env->env_bcc->bcc_list,
2159 &addr_list);
2160
2161 if (r != MAIL_NO_ERROR) {
2162 res = r;
2163 goto free_list;
2164 }
2165
2166 bcc = mailimf_bcc_new(addr_list);
2167 if (bcc == NULL) {
2168 mailimf_address_list_free(addr_list);
2169 res = MAIL_ERROR_MEMORY;
2170 goto free_list;
2171 }
2172
2173 field = mailimf_field_new(MAILIMF_FIELD_BCC,
2174 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2175 NULL, NULL, NULL,
2176 NULL, NULL, NULL, NULL, bcc, NULL, NULL,
2177 NULL, NULL, NULL, NULL, NULL);
2178 if (field == NULL) {
2179 mailimf_bcc_free(bcc);
2180 res = MAIL_ERROR_MEMORY;
2181 goto free_list;
2182 }
2183
2184 r = clist_append(list, field);
2185 if (r != 0) {
2186 mailimf_field_free(field);
2187 res = MAIL_ERROR_MEMORY;
2188 goto free_list;
2189 }
2190 }
2191 }
2192
2193 if (env->env_in_reply_to != NULL) {
2194 struct mailimf_in_reply_to * in_reply_to;
2195 size_t cur_token;
2196 clist * msg_id_list;
2197
2198 cur_token = 0;
2199 r = mailimf_msg_id_list_parse(env->env_in_reply_to,
2200 strlen(env->env_in_reply_to), &cur_token, &msg_id_list);
2201
2202 switch (r) {
2203 case MAILIMF_NO_ERROR:
2204 in_reply_to = mailimf_in_reply_to_new(msg_id_list);
2205 if (in_reply_to == NULL) {
2206 clist_foreach(msg_id_list, (clist_func) mailimf_msg_id_free, NULL);
2207 clist_free(msg_id_list);
2208 res = MAIL_ERROR_MEMORY;
2209 goto free_list;
2210 }
2211
2212 field = mailimf_field_new(MAILIMF_FIELD_IN_REPLY_TO,
2213 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2214 NULL, NULL, NULL,
2215 NULL, NULL, NULL, NULL, NULL, NULL,
2216 in_reply_to,
2217 NULL, NULL, NULL, NULL, NULL);
2218 if (field == NULL) {
2219 mailimf_in_reply_to_free(in_reply_to);
2220 res = MAIL_ERROR_MEMORY;
2221 goto free_list;
2222 }
2223
2224 r = clist_append(list, field);
2225 if (r != 0) {
2226 mailimf_field_free(field);
2227 res = MAIL_ERROR_MEMORY;
2228 goto free_list;
2229 }
2230 break;
2231
2232 case MAILIMF_ERROR_PARSE:
2233 break;
2234
2235 default:
2236 res = maildriver_imf_error_to_mail_error(r);
2237 goto free_list;
2238 }
2239 }
2240
2241 if (env->env_message_id != NULL) {
2242 char * id;
2243 struct mailimf_message_id * msg_id;
2244 size_t cur_token;
2245
2246 cur_token = 0;
2247 r = mailimf_msg_id_parse(env->env_message_id, strlen(env->env_message_id),
2248 &cur_token, &id);
2249 switch (r) {
2250 case MAILIMF_NO_ERROR:
2251
2252 msg_id = mailimf_message_id_new(id);
2253 if (msg_id == NULL) {
2254 mailimf_msg_id_free(id);
2255 res = MAIL_ERROR_MEMORY;
2256 goto free_list;
2257 }
2258
2259 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
2260 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2261 NULL, NULL, NULL,
2262 NULL, NULL, NULL, NULL, NULL, msg_id, NULL,
2263 NULL, NULL, NULL, NULL, NULL);
2264 if (field == NULL) {
2265 mailimf_message_id_free(msg_id);
2266 res = MAIL_ERROR_MEMORY;
2267 goto free_list;
2268 }
2269
2270 r = clist_append(list, field);
2271 if (r != 0) {
2272 mailimf_field_free(field);
2273 res = MAIL_ERROR_MEMORY;
2274 goto free_list;
2275 }
2276 break;
2277
2278 case MAILIMF_ERROR_PARSE:
2279 break;
2280
2281 default:
2282 res = maildriver_imf_error_to_mail_error(r);
2283 goto free_list;
2284 }
2285 }
2286
2287 if (ref_str != NULL) {
2288 struct mailimf_references * references;
2289 size_t cur_token;
2290
2291 cur_token = 0;
2292 r = mailimf_references_parse(ref_str, ref_size,
2293 &cur_token, &references);
2294 switch (r) {
2295 case MAILIMF_NO_ERROR:
2296 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
2297 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2298 NULL, NULL, NULL,
2299 NULL, NULL, NULL, NULL, NULL, NULL,
2300 NULL,
2301 references, NULL, NULL, NULL, NULL);
2302 if (field == NULL) {
2303 mailimf_references_free(references);
2304 res = MAIL_ERROR_MEMORY;
2305 goto free_list;
2306 }
2307
2308 r = clist_append(list, field);
2309 if (r < 0) {
2310 mailimf_field_free(field);
2311 res = MAIL_ERROR_MEMORY;
2312 goto free_list;
2313 }
2314 break;
2315
2316 case MAILIMF_ERROR_PARSE:
2317 break;
2318
2319 default:
2320 res = maildriver_imf_error_to_mail_error(r);
2321 goto free_list;
2322 }
2323 }
2324
2325 fields = mailimf_fields_new(list);
2326 if (fields == NULL) {
2327 res = MAIL_ERROR_MEMORY;
2328 goto free_list;
2329 }
2330
2331 * result = fields;
2332
2333 return MAIL_NO_ERROR;
2334
2335 free_list:
2336 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
2337 clist_free(list);
2338 err:
2339 return res;
2340}
2341
2342int imap_get_msg_att_info(struct mailimap_msg_att * msg_att,
2343 uint32_t * puid,
2344 struct mailimap_envelope ** pimap_envelope,
2345 char ** preferences,
2346 size_t * pref_size,
2347 struct mailimap_msg_att_dynamic ** patt_dyn,
2348 struct mailimap_body ** pimap_body)
2349{
2350 clistiter * item_cur;
2351 uint32_t uid;
2352 struct mailimap_envelope * imap_envelope;
2353 char * references;
2354 size_t ref_size;
2355 struct mailimap_msg_att_dynamic * att_dyn;
2356 struct mailimap_body * imap_body;
2357
2358 uid = 0;
2359 imap_envelope = NULL;
2360 references = NULL;
2361 ref_size = 0;
2362 att_dyn = NULL;
2363 imap_body = NULL;
2364
2365 for(item_cur = clist_begin(msg_att->att_list) ; item_cur != NULL ;
2366 item_cur = clist_next(item_cur)) {
2367 struct mailimap_msg_att_item * item;
2368
2369 item = clist_content(item_cur);
2370
2371 switch (item->att_type) {
2372 case MAILIMAP_MSG_ATT_ITEM_STATIC:
2373 switch (item->att_data.att_static->att_type) {
2374 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
2375 if (imap_body == NULL)
2376 imap_body = item->att_data.att_static->att_data.att_bodystructure;
2377 break;
2378
2379 case MAILIMAP_MSG_ATT_ENVELOPE:
2380 if (imap_envelope == NULL) {
2381 imap_envelope = item->att_data.att_static->att_data.att_env;
2382 }
2383 break;
2384
2385 case MAILIMAP_MSG_ATT_UID:
2386 uid = item->att_data.att_static->att_data.att_uid;
2387 break;
2388
2389 case MAILIMAP_MSG_ATT_BODY_SECTION:
2390 if (references == NULL) {
2391 references = item->att_data.att_static->att_data.att_body_section->sec_body_part;
2392 ref_size = item->att_data.att_static->att_data.att_body_section->sec_length;
2393 }
2394 break;
2395 }
2396 break;
2397
2398 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
2399 if (att_dyn == NULL) {
2400 att_dyn = item->att_data.att_dyn;
2401 }
2402 break;
2403 }
2404 }
2405
2406 if (puid != NULL)
2407 * puid = uid;
2408 if (pimap_envelope != NULL)
2409 * pimap_envelope = imap_envelope;
2410 if (preferences != NULL)
2411 * preferences = references;
2412 if (pref_size != NULL)
2413 * pref_size = ref_size;
2414 if (patt_dyn != NULL)
2415 * patt_dyn = att_dyn;
2416 if (pimap_body != NULL)
2417 * pimap_body = imap_body;
2418
2419 return MAIL_NO_ERROR;
2420}
2421
2422int
2423imap_fetch_result_to_envelop_list(clist * fetch_result,
2424 struct mailmessage_list * env_list)
2425{
2426 clistiter * cur;
2427 int r;
2428 unsigned int i;
2429
2430 i = 0;
2431
2432 for(cur = clist_begin(fetch_result) ; cur != NULL ;
2433 cur = clist_next(cur)) {
2434 struct mailimap_msg_att * msg_att;
2435 uint32_t uid;
2436 struct mailimap_envelope * imap_envelope;
2437 struct mailimap_msg_att_dynamic * att_dyn;
2438 char * references;
2439 size_t ref_size;
2440
2441 msg_att = clist_content(cur);
2442
2443 r = imap_get_msg_att_info(msg_att, &uid, &imap_envelope,
2444 &references, &ref_size,
2445 &att_dyn,
2446 NULL);
2447
2448 if (r == MAIL_NO_ERROR) {
2449 if (uid != 0) {
2450 while (i < carray_count(env_list->msg_tab)) {
2451 mailmessage * msg;
2452
2453 msg = carray_get(env_list->msg_tab, i);
2454
2455 if (uid == msg->msg_index) {
2456 struct mailimf_fields * fields;
2457 struct mail_flags * flags;
2458
2459 if (imap_envelope != NULL) {
2460 r = imap_env_to_fields(imap_envelope,
2461 references, ref_size, &fields);
2462 if (r == MAIL_NO_ERROR) {
2463 msg->msg_fields = fields;
2464 }
2465 }
2466
2467 if (att_dyn != NULL) {
2468 r = imap_flags_to_flags(att_dyn, &flags);
2469
2470 if (r == MAIL_NO_ERROR) {
2471 msg->msg_flags = flags;
2472 }
2473 }
2474
2475 i ++;
2476 break;
2477 }
2478
2479 i ++;
2480 }
2481 }
2482 }
2483 }
2484
2485 return MAIL_NO_ERROR;
2486}
2487
2488
2489int mailimf_date_time_to_imap_date(struct mailimf_date_time * date,
2490 struct mailimap_date ** result)
2491{
2492 struct mailimap_date * imap_date;
2493
2494 imap_date = mailimap_date_new(date->dt_day, date->dt_month, date->dt_year);
2495 if (imap_date == NULL)
2496 return MAIL_ERROR_MEMORY;
2497
2498 * result = imap_date;
2499
2500 return MAIL_NO_ERROR;
2501}
2502
2503
2504#if 0
2505int mail_search_to_imap_search(struct mail_search_key * key,
2506 struct mailimap_search_key ** result)
2507{
2508 struct mailimap_search_key * imap_key;
2509
2510 char * bcc;
2511 struct mailimap_date * before;
2512 char * body;
2513 char * cc;
2514 char * from;
2515 struct mailimap_date * on;
2516 struct mailimap_date * since;
2517 char * subject;
2518 char * text;
2519 char * to;
2520 char * header_name;
2521 char * header_value;
2522 size_t larger;
2523 struct mailimap_search_key * not;
2524 struct mailimap_search_key * or1;
2525 struct mailimap_search_key * or2;
2526 size_t smaller;
2527 clist * multiple;
2528 int type;
2529 clistiter * cur;
2530 int r;
2531 int res;
2532
2533 bcc = NULL;
2534 before = NULL;
2535 body = NULL;
2536 cc = NULL;
2537 from = NULL;
2538 on = NULL;
2539 since = NULL;
2540 subject = NULL;
2541 text = NULL;
2542 to = NULL;
2543 header_name = NULL;
2544 header_value = NULL;
2545 not = NULL;
2546 or1 = NULL;
2547 or2 = NULL;
2548 multiple = NULL;
2549 larger = 0;
2550 smaller = 0;
2551
2552 switch (key->sk_type) {
2553 case MAIL_SEARCH_KEY_ALL:
2554 type = MAILIMAP_SEARCH_KEY_ALL;
2555 break;
2556
2557 case MAIL_SEARCH_KEY_ANSWERED:
2558 type = MAILIMAP_SEARCH_KEY_ANSWERED;
2559 break;
2560
2561 case MAIL_SEARCH_KEY_BCC:
2562 type = MAILIMAP_SEARCH_KEY_BCC;
2563 bcc = strdup(key->sk_bcc);
2564 if (bcc == NULL) {
2565 res = MAIL_ERROR_MEMORY;
2566 goto err;
2567 }
2568 break;
2569
2570 case MAIL_SEARCH_KEY_BEFORE:
2571 type = MAILIMAP_SEARCH_KEY_BEFORE;
2572 r = mailimf_date_time_to_imap_date(key->sk_before, &before);
2573 if (r != MAIL_NO_ERROR) {
2574 res = r;
2575 goto err;
2576 }
2577 break;
2578
2579 case MAIL_SEARCH_KEY_BODY:
2580 type = MAILIMAP_SEARCH_KEY_BODY;
2581 body = strdup(key->sk_body);
2582 if (body == NULL) {
2583 res = MAIL_ERROR_MEMORY;
2584 goto err;
2585 }
2586 break;
2587
2588 case MAIL_SEARCH_KEY_CC:
2589 type = MAILIMAP_SEARCH_KEY_CC;
2590 cc = strdup(key->sk_cc);
2591 if (cc == NULL) {
2592 res = MAIL_ERROR_MEMORY;
2593 goto err;
2594 }
2595 break;
2596
2597 case MAIL_SEARCH_KEY_DELETED:
2598 type = MAILIMAP_SEARCH_KEY_DELETED;
2599 break;
2600
2601 case MAIL_SEARCH_KEY_FLAGGED:
2602 type = MAILIMAP_SEARCH_KEY_FLAGGED;
2603 break;
2604
2605 case MAIL_SEARCH_KEY_FROM:
2606 type = MAILIMAP_SEARCH_KEY_FROM;
2607 from = strdup(key->sk_from);
2608 if (from == NULL) {
2609 res = MAIL_ERROR_MEMORY;
2610 goto err;
2611 }
2612 break;
2613
2614 case MAIL_SEARCH_KEY_NEW:
2615 type = MAILIMAP_SEARCH_KEY_NEW;
2616 break;
2617
2618 case MAIL_SEARCH_KEY_OLD:
2619 type = MAILIMAP_SEARCH_KEY_OLD;
2620 break;
2621
2622 case MAIL_SEARCH_KEY_ON:
2623 type = MAILIMAP_SEARCH_KEY_ON;
2624 r = mailimf_date_time_to_imap_date(key->sk_on, &on);
2625 if (r != MAIL_NO_ERROR) {
2626 res = r;
2627 goto err;
2628 }
2629 break;
2630
2631 case MAIL_SEARCH_KEY_RECENT:
2632 type = MAILIMAP_SEARCH_KEY_RECENT;
2633 break;
2634
2635 case MAIL_SEARCH_KEY_SEEN:
2636 type = MAILIMAP_SEARCH_KEY_SEEN;
2637 break;
2638
2639 case MAIL_SEARCH_KEY_SINCE:
2640 type = MAILIMAP_SEARCH_KEY_SINCE;
2641 r = mailimf_date_time_to_imap_date(key->sk_since, &since);
2642 if (r != MAIL_NO_ERROR) {
2643 res = r;
2644 goto err;
2645 }
2646 break;
2647
2648 case MAIL_SEARCH_KEY_SUBJECT:
2649 type = MAILIMAP_SEARCH_KEY_SUBJECT;
2650 subject = strdup(key->sk_subject);
2651 if (subject == NULL) {
2652 res = MAIL_ERROR_MEMORY;
2653 goto err;
2654 }
2655 break;
2656
2657 case MAIL_SEARCH_KEY_TEXT:
2658 type = MAILIMAP_SEARCH_KEY_TEXT;
2659 text = strdup(key->sk_text);
2660 if (text == NULL) {
2661 res = MAIL_ERROR_MEMORY;
2662 goto err;
2663 }
2664 break;
2665
2666 case MAIL_SEARCH_KEY_TO:
2667 type = MAILIMAP_SEARCH_KEY_TO;
2668 to = strdup(key->sk_to);
2669 if (to == NULL) {
2670 return MAIL_ERROR_MEMORY;
2671 goto err;
2672 }
2673 break;
2674
2675 case MAIL_SEARCH_KEY_UNANSWERED:
2676 type = MAILIMAP_SEARCH_KEY_UNANSWERED;
2677 break;
2678
2679 case MAIL_SEARCH_KEY_UNDELETED:
2680 type = MAILIMAP_SEARCH_KEY_UNFLAGGED;
2681 break;
2682
2683 case MAIL_SEARCH_KEY_UNFLAGGED:
2684 type = MAILIMAP_SEARCH_KEY_UNANSWERED;
2685 break;
2686
2687 case MAIL_SEARCH_KEY_UNSEEN:
2688 type = MAILIMAP_SEARCH_KEY_UNSEEN;
2689 break;
2690
2691 case MAIL_SEARCH_KEY_HEADER:
2692 type = MAILIMAP_SEARCH_KEY_HEADER;
2693 header_name = strdup(key->sk_header_name);
2694 if (header_name == NULL) {
2695 res = MAIL_ERROR_MEMORY;
2696 goto err;
2697 }
2698 header_value = strdup(key->sk_header_value);
2699 if (header_value == NULL) {
2700 free(header_name);
2701 res = MAIL_ERROR_MEMORY;
2702 goto err;
2703 }
2704 break;
2705
2706 case MAIL_SEARCH_KEY_LARGER:
2707 type = MAILIMAP_SEARCH_KEY_LARGER;
2708 larger = key->sk_larger;
2709 break;
2710
2711 case MAIL_SEARCH_KEY_NOT:
2712 type = MAILIMAP_SEARCH_KEY_NOT;
2713 r = mail_search_to_imap_search(key->sk_not, &not);
2714 if (r != MAIL_NO_ERROR) {
2715 res = r;
2716 goto err;
2717 }
2718 break;
2719
2720 case MAIL_SEARCH_KEY_OR:
2721 type = MAILIMAP_SEARCH_KEY_OR;
2722 r = mail_search_to_imap_search(key->sk_or1, &or1);
2723 if (r != MAIL_NO_ERROR) {
2724 res = r;
2725 goto err;
2726 }
2727 r = mail_search_to_imap_search(key->sk_or2, &or2);
2728 if (r != MAIL_NO_ERROR) {
2729 mailimap_search_key_free(or1);
2730 res = r;
2731 goto err;
2732 }
2733 break;
2734
2735 case MAIL_SEARCH_KEY_SMALLER:
2736 type = MAILIMAP_SEARCH_KEY_SMALLER;
2737 smaller = key->sk_smaller;
2738 break;
2739
2740 case MAIL_SEARCH_KEY_MULTIPLE:
2741 multiple = clist_new();
2742 if (multiple == NULL) {
2743 res = MAIL_ERROR_MEMORY;
2744 goto err;
2745 }
2746
2747 type = MAILIMAP_SEARCH_KEY_MULTIPLE;
2748 for(cur = clist_begin(key->sk_multiple) ; cur != NULL ;
2749 cur = clist_next(cur)) {
2750 struct mail_search_key * key_elt;
2751 struct mailimap_search_key * imap_key_elt;
2752
2753 key_elt = clist_content(cur);
2754 r = mail_search_to_imap_search(key_elt, &imap_key_elt);
2755 if (r != MAIL_NO_ERROR) {
2756 res = r;
2757 goto free_list;
2758 }
2759
2760 r = clist_append(multiple, imap_key_elt);
2761 if (r != 0) {
2762 mailimap_search_key_free(imap_key_elt);
2763 res = MAIL_ERROR_MEMORY;
2764 goto free_list;
2765 }
2766 }
2767 break;
2768
2769 free_list:
2770 clist_foreach(multiple, (clist_func) mailimap_search_key_free, NULL);
2771 clist_free(multiple);
2772 goto err;
2773
2774 default:
2775 return MAIL_ERROR_INVAL;
2776 }
2777
2778 imap_key = mailimap_search_key_new(type, bcc, before, body, cc, from,
2779 NULL, on, since, subject, text,
2780 to, NULL, header_name,
2781 header_value, larger, not, or1, or2,
2782 NULL, NULL, NULL, smaller, NULL,
2783 NULL, multiple);
2784 if (imap_key == NULL) {
2785 res = MAIL_ERROR_MEMORY;
2786 goto free;
2787 }
2788
2789 * result = imap_key;
2790
2791 return MAIL_NO_ERROR;
2792
2793 free:
2794 if (bcc != NULL)
2795 free(bcc);
2796 if (before != NULL)
2797 mailimap_date_free(before);
2798 if (body != NULL)
2799 free(body);
2800 if (cc != NULL)
2801 free(cc);
2802 if (from != NULL)
2803 free(from);
2804 if (on != NULL)
2805 mailimap_date_free(on);
2806 if (since != NULL)
2807 mailimap_date_free(since);
2808 if (subject != NULL)
2809 free(subject);
2810 if (text != NULL)
2811 free(text);
2812 if (to != NULL)
2813 free(to);
2814 if (header_name != NULL)
2815 free(header_name);
2816 if (header_value != NULL)
2817 free(header_value);
2818 if (not != NULL)
2819 mailimap_search_key_free(not);
2820 if (or1 != NULL)
2821 mailimap_search_key_free(or1);
2822 if (or2 != NULL)
2823 mailimap_search_key_free(or2);
2824 clist_foreach(multiple, (clist_func) mailimap_search_key_free, NULL);
2825 clist_free(multiple);
2826 err:
2827 return res;
2828}
2829#endif
2830
2831
2832int msg_list_to_imap_set(clist * msg_list,
2833 struct mailimap_set ** result)
2834{
2835 struct mailimap_set * imap_set;
2836 clistiter * cur;
2837 int previous_valid;
2838 uint32_t first_seq;
2839 uint32_t previous;
2840 int r;
2841 int res;
2842
2843 imap_set = mailimap_set_new_empty();
2844 if (imap_set == NULL) {
2845 res = MAIL_ERROR_MEMORY;
2846 goto err;
2847 }
2848
2849 cur = clist_begin(msg_list);
2850 previous_valid = FALSE;
2851 first_seq = 0;
2852 previous = 0;
2853 while (1) {
2854 uint32_t * pindex;
2855
2856 if ((cur == NULL) && (previous_valid)) {
2857 if (first_seq == previous) {
2858 r = mailimap_set_add_single(imap_set, first_seq);
2859 if (r != MAILIMAP_NO_ERROR) {
2860 res = r;
2861 goto free;
2862 }
2863 }
2864 else {
2865 r = mailimap_set_add_interval(imap_set, first_seq, previous);
2866 if (r != MAILIMAP_NO_ERROR) {
2867 res = r;
2868 goto free;
2869 }
2870 }
2871 break;
2872 }
2873
2874 pindex = clist_content(cur);
2875
2876 if (!previous_valid) {
2877 first_seq = * pindex;
2878 previous_valid = TRUE;
2879 previous = * pindex;
2880 cur = clist_next(cur);
2881 }
2882 else {
2883 if (* pindex != previous + 1) {
2884 if (first_seq == previous) {
2885 r = mailimap_set_add_single(imap_set, first_seq);
2886 if (r != MAILIMAP_NO_ERROR) {
2887 res = r;
2888 goto free;
2889 }
2890 }
2891 else {
2892 r = mailimap_set_add_interval(imap_set, first_seq, previous);
2893 if (r != MAILIMAP_NO_ERROR) {
2894 res = r;
2895 goto free;
2896 }
2897 }
2898 previous_valid = FALSE;
2899 }
2900 else {
2901 previous = * pindex;
2902 cur = clist_next(cur);
2903 }
2904 }
2905 }
2906
2907 * result = imap_set;
2908
2909 return MAIL_NO_ERROR;
2910
2911 free:
2912 mailimap_set_free(imap_set);
2913 err:
2914 return res;
2915}
2916
2917
2918static int
2919uid_list_to_env_list(clist * fetch_result,
2920 struct mailmessage_list ** result,
2921 mailsession * session, mailmessage_driver * driver)
2922{
2923 clistiter * cur;
2924 struct mailmessage_list * env_list;
2925 int r;
2926 int res;
2927 carray * tab;
2928 unsigned int i;
2929 mailmessage * msg;
2930
2931 tab = carray_new(128);
2932 if (tab == NULL) {
2933 res = MAIL_ERROR_MEMORY;
2934 goto err;
2935 }
2936
2937 for(cur = clist_begin(fetch_result) ; cur != NULL ;
2938 cur = clist_next(cur)) {
2939 struct mailimap_msg_att * msg_att;
2940 clistiter * item_cur;
2941 uint32_t uid;
2942 size_t size;
2943
2944 msg_att = clist_content(cur);
2945
2946 uid = 0;
2947 size = 0;
2948 for(item_cur = clist_begin(msg_att->att_list) ; item_cur != NULL ;
2949 item_cur = clist_next(item_cur)) {
2950 struct mailimap_msg_att_item * item;
2951
2952 item = clist_content(item_cur);
2953
2954 switch (item->att_type) {
2955 case MAILIMAP_MSG_ATT_ITEM_STATIC:
2956 switch (item->att_data.att_static->att_type) {
2957 case MAILIMAP_MSG_ATT_UID:
2958 uid = item->att_data.att_static->att_data.att_uid;
2959 break;
2960
2961 case MAILIMAP_MSG_ATT_RFC822_SIZE:
2962 size = item->att_data.att_static->att_data.att_rfc822_size;
2963 break;
2964 }
2965 break;
2966 }
2967 }
2968
2969 msg = mailmessage_new();
2970 if (msg == NULL) {
2971 res = MAIL_ERROR_MEMORY;
2972 goto free_list;
2973 }
2974
2975 r = mailmessage_init(msg, session, driver, uid, size);
2976 if (r != MAIL_NO_ERROR) {
2977 res = r;
2978 goto free_msg;
2979 }
2980
2981 r = carray_add(tab, msg, NULL);
2982 if (r < 0) {
2983 res = MAIL_ERROR_MEMORY;
2984 goto free_msg;
2985 }
2986 }
2987
2988 env_list = mailmessage_list_new(tab);
2989 if (env_list == NULL) {
2990 res = MAIL_ERROR_MEMORY;
2991 goto free_list;
2992 }
2993
2994 * result = env_list;
2995
2996 return MAIL_NO_ERROR;
2997
2998 free_msg:
2999 mailmessage_free(msg);
3000 free_list:
3001 for(i = 0 ; i < carray_count(tab) ; i++)
3002 mailmessage_free(carray_get(tab, i));
3003 err:
3004 return res;
3005}
3006
3007
3008/*
3009 MAILIMAP_FLAG_FETCH_RECENT,
3010 MAILIMAP_FLAG_FETCH_OTHER
3011
3012 MAILIMAP_FLAG_ANSWERED,
3013 MAILIMAP_FLAG_FLAGGED,
3014 MAILIMAP_FLAG_DELETED,
3015 MAILIMAP_FLAG_SEEN,
3016 MAILIMAP_FLAG_DRAFT,
3017 MAILIMAP_FLAG_KEYWORD,
3018 MAILIMAP_FLAG_EXTENSION
3019*/
3020
3021static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn,
3022 struct mail_flags ** result)
3023{
3024 struct mail_flags * flags;
3025 clist * flag_list;
3026 clistiter * cur;
3027
3028 flags = mail_flags_new_empty();
3029 if (flags == NULL)
3030 goto err;
3031 flags->fl_flags = 0;
3032
3033 flag_list = att_dyn->att_list;
3034 if (flag_list != NULL) {
3035 for(cur = clist_begin(flag_list) ; cur != NULL ;
3036 cur = clist_next(cur)) {
3037 struct mailimap_flag_fetch * flag_fetch;
3038
3039 flag_fetch = clist_content(cur);
3040 if (flag_fetch->fl_type == MAILIMAP_FLAG_FETCH_RECENT)
3041 flags->fl_flags |= MAIL_FLAG_NEW;
3042 else {
3043 char * keyword;
3044 int r;
3045
3046 switch (flag_fetch->fl_flag->fl_type) {
3047 case MAILIMAP_FLAG_ANSWERED:
3048 flags->fl_flags |= MAIL_FLAG_ANSWERED;
3049 break;
3050 case MAILIMAP_FLAG_FLAGGED:
3051 flags->fl_flags |= MAIL_FLAG_FLAGGED;
3052 break;
3053 case MAILIMAP_FLAG_DELETED:
3054 flags->fl_flags |= MAIL_FLAG_DELETED;
3055 break;
3056 case MAILIMAP_FLAG_SEEN:
3057 flags->fl_flags |= MAIL_FLAG_SEEN;
3058 break;
3059 case MAILIMAP_FLAG_DRAFT:
3060 keyword = strdup("Draft");
3061 if (keyword == NULL)
3062 goto free;
3063 r = clist_append(flags->fl_extension, keyword);
3064 if (r < 0) {
3065 free(keyword);
3066 goto free;
3067 }
3068 break;
3069 case MAILIMAP_FLAG_KEYWORD:
3070 if (strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword,
3071 "$Forwarded") == 0) {
3072 flags->fl_flags |= MAIL_FLAG_FORWARDED;
3073 }
3074 else {
3075 keyword = strdup(flag_fetch->fl_flag->fl_data.fl_keyword);
3076 if (keyword == NULL)
3077 goto free;
3078 r = clist_append(flags->fl_extension, keyword);
3079 if (r < 0) {
3080 free(keyword);
3081 goto free;
3082 }
3083 }
3084 break;
3085 case MAILIMAP_FLAG_EXTENSION:
3086 /* do nothing */
3087 break;
3088 }
3089 }
3090 }
3091 /*
3092 MAIL_FLAG_NEW was set for \Recent messages.
3093 Correct this flag for \Seen messages by unsetting it.
3094 */
3095 if ((flags->fl_flags & MAIL_FLAG_SEEN) && (flags->fl_flags & MAIL_FLAG_NEW)) {
3096 flags->fl_flags &= ~MAIL_FLAG_NEW;
3097 }
3098 }
3099
3100 * result = flags;
3101
3102 return MAIL_NO_ERROR;
3103
3104 free:
3105 mail_flags_free(flags);
3106 err:
3107 return MAIL_ERROR_MEMORY;
3108}
3109
3110static int flags_to_imap_flags(struct mail_flags * flags,
3111 struct mailimap_store_att_flags ** result)
3112{
3113 struct mailimap_flag * flag;
3114 struct mailimap_flag_list * flag_list;
3115 struct mailimap_store_att_flags * att_flags;
3116 int res;
3117 clistiter * cur;
3118 int r;
3119
3120 flag_list = mailimap_flag_list_new_empty();
3121 if (flag_list == NULL) {
3122 res = MAIL_ERROR_MEMORY;
3123 goto err;
3124 }
3125
3126 if ((flags->fl_flags & MAIL_FLAG_DELETED) != 0) {
3127 flag = mailimap_flag_new_deleted();
3128 if (flag == NULL) {
3129 res = MAIL_ERROR_MEMORY;
3130 goto free_flag_list;
3131 }
3132 r = mailimap_flag_list_add(flag_list, flag);
3133 if (r != MAILIMAP_NO_ERROR) {
3134 mailimap_flag_free(flag);
3135 res = MAIL_ERROR_MEMORY;
3136 goto free_flag_list;
3137 }
3138 }
3139
3140 if ((flags->fl_flags & MAIL_FLAG_FLAGGED) != 0) {
3141 flag = mailimap_flag_new_flagged();
3142 if (flag == NULL) {
3143 res = MAIL_ERROR_MEMORY;
3144 goto free_flag_list;
3145 }
3146 r = mailimap_flag_list_add(flag_list, flag);
3147 if (r != MAILIMAP_NO_ERROR) {
3148 mailimap_flag_free(flag);
3149 res = MAIL_ERROR_MEMORY;
3150 goto free_flag_list;
3151 }
3152 }
3153
3154 if ((flags->fl_flags & MAIL_FLAG_SEEN) != 0) {
3155 flag = mailimap_flag_new_seen();
3156 if (flag == NULL) {
3157 res = MAIL_ERROR_MEMORY;
3158 goto free_flag_list;
3159 }
3160 r = mailimap_flag_list_add(flag_list, flag);
3161 if (r != MAILIMAP_NO_ERROR) {
3162 res = MAIL_ERROR_MEMORY;
3163 goto free_flag_list;
3164 }
3165 }
3166
3167 if ((flags->fl_flags & MAIL_FLAG_ANSWERED) != 0) {
3168 flag = mailimap_flag_new_answered();
3169 if (flag == NULL) {
3170 res = MAIL_ERROR_MEMORY;
3171 goto free_flag_list;
3172 }
3173 r = mailimap_flag_list_add(flag_list, flag);
3174 if (r != MAILIMAP_NO_ERROR) {
3175 mailimap_flag_free(flag);
3176 res = MAIL_ERROR_MEMORY;
3177 goto free_flag_list;
3178 }
3179 }
3180
3181 if ((flags->fl_flags & MAIL_FLAG_FORWARDED) != 0) {
3182 char * flag_str;
3183
3184 flag_str = strdup("$Forwarded");
3185 if (flag_str == NULL) {
3186 res = MAIL_ERROR_MEMORY;
3187 goto free_flag_list;
3188 }
3189 flag = mailimap_flag_new_flag_keyword(flag_str);
3190 if (flag == NULL) {
3191 free(flag_str);
3192 res = MAIL_ERROR_MEMORY;
3193 goto free_flag_list;
3194 }
3195 r = mailimap_flag_list_add(flag_list, flag);
3196 if (r != MAILIMAP_NO_ERROR) {
3197 mailimap_flag_free(flag);
3198 res = MAIL_ERROR_MEMORY;
3199 goto free_flag_list;
3200 }
3201 }
3202
3203 for(cur = clist_begin(flags->fl_extension) ; cur != NULL ;
3204 cur = clist_next(cur)) {
3205 char * flag_str;
3206
3207 flag_str = clist_content(cur);
3208
3209 if (strcasecmp(flag_str, "Draft") == 0) {
3210 flag = mailimap_flag_new_draft();
3211 if (flag == NULL) {
3212 res = MAIL_ERROR_MEMORY;
3213 goto free_flag_list;
3214 }
3215 r = mailimap_flag_list_add(flag_list, flag);
3216 if (r != MAILIMAP_NO_ERROR) {
3217 mailimap_flag_free(flag);
3218 res = MAIL_ERROR_MEMORY;
3219 goto free_flag_list;
3220 }
3221 }
3222 else {
3223 flag_str = strdup(flag_str);
3224 if (flag_str == NULL) {
3225 res = MAIL_ERROR_MEMORY;
3226 goto free_flag_list;
3227 }
3228 flag = mailimap_flag_new_flag_keyword(flag_str);
3229 if (flag == NULL) {
3230 free(flag_str);
3231 res = MAIL_ERROR_MEMORY;
3232 goto free_flag_list;
3233 }
3234 r = mailimap_flag_list_add(flag_list, flag);
3235 if (r != MAILIMAP_NO_ERROR) {
3236 mailimap_flag_free(flag);
3237 res = MAIL_ERROR_MEMORY;
3238 goto free_flag_list;
3239 }
3240 }
3241 }
3242
3243 att_flags = mailimap_store_att_flags_new_set_flags_silent(flag_list);
3244 if (att_flags == NULL) {
3245 res = MAIL_ERROR_MEMORY;
3246 goto free_flag_list;
3247 }
3248
3249 * result = att_flags;
3250
3251 return MAIL_NO_ERROR;
3252
3253 free_flag_list:
3254 mailimap_flag_list_free(flag_list);
3255 err:
3256 return res;
3257}
3258
3259
3260static int
3261imap_fetch_result_to_flags(clist * fetch_result, uint32_t index,
3262 struct mail_flags ** result)
3263{
3264 clistiter * cur;
3265 int r;
3266
3267 for(cur = clist_begin(fetch_result) ; cur != NULL ;
3268 cur = clist_next(cur)) {
3269 struct mailimap_msg_att * msg_att;
3270 clistiter * item_cur;
3271 uint32_t uid;
3272 struct mailimap_msg_att_dynamic * att_dyn;
3273
3274 msg_att = clist_content(cur);
3275
3276 uid = 0;
3277 att_dyn = NULL;
3278
3279 for(item_cur = clist_begin(msg_att->att_list) ; item_cur != NULL ;
3280 item_cur = clist_next(item_cur)) {
3281 struct mailimap_msg_att_item * item;
3282
3283 item = clist_content(item_cur);
3284
3285 if (item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
3286 switch (item->att_data.att_static->att_type) {
3287 case MAILIMAP_MSG_ATT_UID:
3288 uid = item->att_data.att_static->att_data.att_uid;
3289 break;
3290 }
3291 }
3292 else if (item->att_type == MAILIMAP_MSG_ATT_ITEM_DYNAMIC) {
3293 if (att_dyn == NULL) {
3294 att_dyn = item->att_data.att_dyn;
3295 }
3296 }
3297 }
3298
3299 if (uid != 0) {
3300 if (uid == index) {
3301 struct mail_flags * flags;
3302
3303 if (att_dyn != NULL) {
3304 r = imap_flags_to_flags(att_dyn, &flags);
3305
3306 if (r == MAIL_NO_ERROR) {
3307 * result = flags;
3308 return MAIL_NO_ERROR;
3309 }
3310 }
3311 }
3312 }
3313 }
3314
3315 return MAIL_ERROR_MSG_NOT_FOUND;
3316}
3317
3318
3319int imap_fetch_flags(mailimap * imap,
3320 uint32_t index, struct mail_flags ** result)
3321{
3322 struct mailimap_fetch_att * fetch_att;
3323 struct mailimap_fetch_type * fetch_type;
3324 struct mailimap_set * set;
3325 int r;
3326 int res;
3327 clist * fetch_result;
3328 struct mail_flags * flags;
3329
3330 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
3331 if (fetch_type == NULL) {
3332 res = MAIL_ERROR_MEMORY;
3333 goto err;
3334 }
3335
3336 fetch_att = mailimap_fetch_att_new_uid();
3337 if (fetch_att == NULL) {
3338 res = MAIL_ERROR_MEMORY;
3339 goto free_fetch_type;
3340 }
3341
3342 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3343 if (r != MAILIMAP_NO_ERROR) {
3344 mailimap_fetch_att_free(fetch_att);
3345 res = MAIL_ERROR_MEMORY;
3346 goto free_fetch_type;
3347 }
3348
3349 fetch_att = mailimap_fetch_att_new_flags();
3350 if (fetch_att == NULL) {
3351 res = MAIL_ERROR_MEMORY;
3352 goto free_fetch_type;
3353 }
3354
3355 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3356 if (r != MAILIMAP_NO_ERROR) {
3357 mailimap_fetch_att_free(fetch_att);
3358 res = MAIL_ERROR_MEMORY;
3359 goto free_fetch_type;
3360 }
3361
3362 set = mailimap_set_new_single(index);
3363 if (set == NULL) {
3364 res = MAIL_ERROR_MEMORY;
3365 goto free_fetch_type;
3366 }
3367
3368 r = mailimap_uid_fetch(imap, set, fetch_type, &fetch_result);
3369
3370 mailimap_fetch_type_free(fetch_type);
3371 mailimap_set_free(set);
3372
3373 switch (r) {
3374 case MAILIMAP_NO_ERROR:
3375 break;
3376 default:
3377 return imap_error_to_mail_error(r);
3378 }
3379
3380 r = imap_fetch_result_to_flags(fetch_result, index, &flags);
3381 mailimap_fetch_list_free(fetch_result);
3382
3383 if (r != MAIL_NO_ERROR) {
3384 res = r;
3385 goto err;
3386 }
3387
3388 * result = flags;
3389
3390 return MAIL_NO_ERROR;
3391
3392 free_fetch_type:
3393 mailimap_fetch_type_free(fetch_type);
3394 err:
3395 return res;
3396}
3397
3398int imap_store_flags(mailimap * imap, uint32_t first, uint32_t last,
3399 struct mail_flags * flags)
3400{
3401 struct mailimap_store_att_flags * att_flags;
3402 struct mailimap_set * set;
3403 int r;
3404 int res;
3405
3406 set = mailimap_set_new_interval(first, last);
3407 if (set == NULL) {
3408 res = MAIL_ERROR_MEMORY;
3409 goto err;
3410 }
3411
3412 r = flags_to_imap_flags(flags, &att_flags);
3413 if (r != MAIL_NO_ERROR) {
3414 res = r;
3415 goto free_set;
3416 }
3417
3418 r = mailimap_uid_store(imap, set, att_flags);
3419 if (r != MAILIMAP_NO_ERROR) {
3420 res = imap_error_to_mail_error(r);
3421 goto free_flag;
3422 }
3423
3424 mailimap_store_att_flags_free(att_flags);
3425 mailimap_set_free(set);
3426
3427 return MAIL_NO_ERROR;
3428
3429 free_flag:
3430 mailimap_store_att_flags_free(att_flags);
3431 free_set:
3432 mailimap_set_free(set);
3433 err:
3434 return res;
3435}
3436
3437
3438
3439
3440int imap_get_messages_list(mailimap * imap,
3441 mailsession * session, mailmessage_driver * driver,
3442 uint32_t first_index,
3443 struct mailmessage_list ** result)
3444{
3445 struct mailmessage_list * env_list;
3446 int r;
3447 struct mailimap_fetch_att * fetch_att;
3448 struct mailimap_fetch_type * fetch_type;
3449 struct mailimap_set * set;
3450 clist * fetch_result;
3451 int res;
3452
3453 set = mailimap_set_new_interval(first_index, 0);
3454 if (set == NULL) {
3455 res = MAIL_ERROR_MEMORY;
3456 goto err;
3457 }
3458
3459 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
3460 if (fetch_type == NULL) {
3461 res = MAIL_ERROR_MEMORY;
3462 goto free_set;
3463 }
3464
3465 fetch_att = mailimap_fetch_att_new_uid();
3466 if (fetch_att == NULL) {
3467 res = MAIL_ERROR_MEMORY;
3468 goto free_fetch_type;
3469 }
3470
3471 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3472 if (r != MAILIMAP_NO_ERROR) {
3473 mailimap_fetch_att_free(fetch_att);
3474 res = MAIL_ERROR_MEMORY;
3475 goto free_fetch_type;
3476 }
3477
3478 fetch_att = mailimap_fetch_att_new_rfc822_size();
3479 if (fetch_att == NULL) {
3480 res = MAIL_ERROR_MEMORY;
3481 goto free_fetch_type;
3482 }
3483
3484 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3485 if (r != MAILIMAP_NO_ERROR) {
3486 mailimap_fetch_att_free(fetch_att);
3487 res = MAIL_ERROR_MEMORY;
3488 goto free_fetch_type;
3489 }
3490
3491 r = mailimap_uid_fetch(imap, set,
3492 fetch_type, &fetch_result);
3493
3494 mailimap_fetch_type_free(fetch_type);
3495 mailimap_set_free(set);
3496
3497 if (r != MAILIMAP_NO_ERROR) {
3498 res = imap_error_to_mail_error(r);
3499 goto err;
3500 }
3501
3502 r = uid_list_to_env_list(fetch_result, &env_list, session, driver);
3503 mailimap_fetch_list_free(fetch_result);
3504
3505 * result = env_list;
3506
3507 return MAIL_NO_ERROR;
3508
3509 free_fetch_type:
3510 mailimap_fetch_type_free(fetch_type);
3511 free_set:
3512 mailimap_set_free(set);
3513 err:
3514 return res;
3515}
3516
3517static void generate_key_from_message(char * key, size_t size,
3518 mailmessage * msg_info,
3519 int type)
3520{
3521 switch (type) {
3522 case MAILIMAP_MSG_ATT_RFC822:
3523 snprintf(key, size, "%s-rfc822", msg_info->msg_uid);
3524 break;
3525 case MAILIMAP_MSG_ATT_RFC822_HEADER:
3526 snprintf(key, size, "%s-rfc822-header", msg_info->msg_uid);
3527 break;
3528 case MAILIMAP_MSG_ATT_RFC822_TEXT:
3529 snprintf(key, size, "%s-rfc822-text", msg_info->msg_uid);
3530 break;
3531 case MAILIMAP_MSG_ATT_ENVELOPE:
3532 snprintf(key, size, "%s-envelope", msg_info->msg_uid);
3533 break;
3534 }
3535}
3536
3537int
3538imapdriver_get_cached_envelope(struct mail_cache_db * cache_db,
3539 MMAPString * mmapstr,
3540 mailsession * session, mailmessage * msg,
3541 struct mailimf_fields ** result)
3542{
3543#if 0
3544 mailsession * imap_session;
3545#endif
3546 mailimap * imap;
3547 int r;
3548 struct mailimf_fields * fields;
3549 int res;
3550 char keyname[PATH_MAX];
3551
3552#if 0
3553 imap_session = cached_session_get_ancestor(session);
3554 imap = ((struct imap_session_state_data *) (imap_session->data))->session;
3555#endif
3556 imap = cached_session_get_imap_session(session);
3557
3558 generate_key_from_message(keyname, PATH_MAX,
3559 msg, MAILIMAP_MSG_ATT_ENVELOPE);
3560
3561 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
3562 if (r != MAIL_NO_ERROR) {
3563 res = r;
3564 goto err;
3565 }
3566
3567 * result = fields;
3568
3569 return MAIL_NO_ERROR;
3570
3571err:
3572 return res;
3573}
3574
3575int
3576imapdriver_write_cached_envelope(struct mail_cache_db * cache_db,
3577 MMAPString * mmapstr,
3578 mailsession * session, mailmessage * msg,
3579 struct mailimf_fields * fields)
3580{
3581 char keyname[PATH_MAX];
3582 int r;
3583 int res;
3584
3585 generate_key_from_message(keyname, PATH_MAX,
3586 msg, MAILIMAP_MSG_ATT_ENVELOPE);
3587
3588 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
3589 if (r != MAIL_NO_ERROR) {
3590 res = r;
3591 goto err;
3592 }
3593
3594 return MAIL_NO_ERROR;
3595
3596err:
3597 return res;
3598}
3599
diff --git a/kmicromail/libetpan/generic/imapdriver_tools.h b/kmicromail/libetpan/generic/imapdriver_tools.h
new file mode 100644
index 0000000..6582a31
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_tools.h
@@ -0,0 +1,113 @@
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#ifndef IMAPDRIVER_TOOLS_H
37
38#define IMAPDRIVER_TOOLS_H
39
40#include "mailimap.h"
41#include "mailmime.h"
42#include "imapdriver_types.h"
43#include "mail_cache_db.h"
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49int imap_list_to_list(clist * imap_list, struct mail_list ** result);
50
51int
52section_to_imap_section(struct mailmime_section * section, int type,
53 struct mailimap_section ** result);
54
55int imap_get_msg_att_info(struct mailimap_msg_att * msg_att,
56 uint32_t * puid,
57 struct mailimap_envelope ** pimap_envelope,
58 char ** preferences,
59 size_t * pref_size,
60 struct mailimap_msg_att_dynamic ** patt_dyn,
61 struct mailimap_body ** pimap_body);
62
63int imap_add_envelope_fetch_att(struct mailimap_fetch_type * fetch_type);
64
65int imap_env_to_fields(struct mailimap_envelope * env,
66 char * ref_str, size_t ref_size,
67 struct mailimf_fields ** result);
68
69int
70imap_fetch_result_to_envelop_list(clist * fetch_result,
71 struct mailmessage_list * env_list);
72
73int imap_body_to_body(struct mailimap_body * imap_body,
74 struct mailmime ** result);
75
76#if 0
77int mail_search_to_imap_search(struct mail_search_key * key,
78 struct mailimap_search_key ** result);
79#endif
80
81int msg_list_to_imap_set(clist * msg_list,
82 struct mailimap_set ** result);
83
84int imap_error_to_mail_error(int error);
85
86int imap_store_flags(mailimap * imap, uint32_t first, uint32_t last,
87 struct mail_flags * flags);
88
89int imap_fetch_flags(mailimap * imap,
90 uint32_t index, struct mail_flags ** result);
91
92int imap_get_messages_list(mailimap * imap,
93 mailsession * session, mailmessage_driver * driver,
94 uint32_t first_index,
95 struct mailmessage_list ** result);
96
97int
98imapdriver_get_cached_envelope(struct mail_cache_db * cache_db,
99 MMAPString * mmapstr,
100 mailsession * session, mailmessage * msg,
101 struct mailimf_fields ** result);
102
103int
104imapdriver_write_cached_envelope(struct mail_cache_db * cache_db,
105 MMAPString * mmapstr,
106 mailsession * session, mailmessage * msg,
107 struct mailimf_fields * fields);
108
109#ifdef __cplusplus
110}
111#endif
112
113#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_types.h b/kmicromail/libetpan/generic/imapdriver_types.h
new file mode 100644
index 0000000..d4e216d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_types.h
@@ -0,0 +1,144 @@
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#ifndef IMAPDRIVER_TYPES_H
37
38#define IMAPDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/mailimap.h>
43#include <libetpan/maildriver_types.h>
44#include <libetpan/generic_cache_types.h>
45#include <libetpan/mailstorage_types.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
51/* IMAP driver for session */
52
53struct imap_session_state_data {
54 mailimap * imap_session;
55 char * imap_mailbox;
56 struct mail_flags_store * imap_flags_store;
57};
58
59enum {
60 IMAP_SECTION_MESSAGE,
61 IMAP_SECTION_HEADER,
62 IMAP_SECTION_MIME,
63 IMAP_SECTION_BODY
64};
65
66/* cached IMAP driver for session */
67
68enum {
69 IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
70};
71
72struct imap_cached_session_state_data {
73 mailsession * imap_ancestor;
74 char * imap_quoted_mb;
75 char imap_cache_directory[PATH_MAX];
76 carray * imap_uid_list;
77};
78
79
80/* IMAP storage */
81
82/*
83 imap_mailstorage is the state data specific to the IMAP4rev1 storage.
84
85 - servername this is the name of the IMAP4rev1 server
86
87 - port is the port to connect to, on the server.
88 you give 0 to use the default port.
89
90 - command, if non-NULL the command used to connect to the
91 server instead of allowing normal TCP connections to be used.
92
93 - connection_type is the type of socket layer to use.
94 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
95 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS or
96 CONNECTION_TYPE_COMMAND.
97
98 - auth_type is the authenticate mechanism to use.
99 The value can be IMAP_AUTH_TYPE_PLAIN.
100 Other values are not yet implemented.
101
102 - login is the login of the IMAP4rev1 account.
103
104 - password is the password of the IMAP4rev1 account.
105
106 - cached if this value is != 0, a persistant cache will be
107 stored on local system.
108
109 - cache_directory is the location of the cache
110*/
111
112struct imap_mailstorage {
113 char * imap_servername;
114 uint16_t imap_port;
115 char * imap_command;
116 int imap_connection_type;
117
118 int imap_auth_type;
119 char * imap_login;
120 char * imap_password;
121
122 int imap_cached;
123 char * imap_cache_directory;
124};
125
126/* this is the type of IMAP4rev1 authentication */
127
128enum {
129 IMAP_AUTH_TYPE_PLAIN, /* plain text authentication */
130 IMAP_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
131 IMAP_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
132 IMAP_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
133 IMAP_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
134 IMAP_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
135 IMAP_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
136 IMAP_AUTH_TYPE_SASL_DIGEST_MD5, /* SASL digest MD5 */
137};
138
139
140#ifdef __cplusplus
141}
142#endif
143
144#endif
diff --git a/kmicromail/libetpan/generic/imapstorage.c b/kmicromail/libetpan/generic/imapstorage.c
new file mode 100644
index 0000000..e8683d8
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapstorage.c
@@ -0,0 +1,297 @@
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 "imapstorage.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41#include "mail.h"
42#include "imapdriver.h"
43#include "imapdriver_cached.h"
44#include "mailstorage_tools.h"
45#include "maildriver.h"
46
47/* imap storage */
48
49#define IMAP_DEFAULT_PORT 143
50#define IMAPS_DEFAULT_PORT 993
51
52static int imap_mailstorage_connect(struct mailstorage * storage);
53static int
54imap_mailstorage_get_folder_session(struct mailstorage * storage,
55 char * pathname, mailsession ** result);
56static void imap_mailstorage_uninitialize(struct mailstorage * storage);
57
58static mailstorage_driver imap_mailstorage_driver = {
59 .sto_name = "imap",
60 .sto_connect = imap_mailstorage_connect,
61 .sto_get_folder_session = imap_mailstorage_get_folder_session,
62 .sto_uninitialize = imap_mailstorage_uninitialize,
63};
64
65int imap_mailstorage_init(struct mailstorage * storage,
66 char * imap_servername, uint16_t imap_port,
67 char * imap_command,
68 int imap_connection_type, int imap_auth_type,
69 char * imap_login, char * imap_password,
70 int imap_cached, char * imap_cache_directory)
71{
72 struct imap_mailstorage * imap_storage;
73
74 imap_storage = malloc(sizeof(struct imap_mailstorage));
75 if (imap_storage == NULL)
76 goto err;
77
78 imap_storage->imap_servername = strdup(imap_servername);
79 if (imap_storage->imap_servername == NULL)
80 goto free;
81
82 imap_storage->imap_connection_type = imap_connection_type;
83
84 if (imap_port == 0) {
85 switch (imap_connection_type) {
86 case CONNECTION_TYPE_PLAIN:
87 case CONNECTION_TYPE_TRY_STARTTLS:
88 case CONNECTION_TYPE_STARTTLS:
89 case CONNECTION_TYPE_COMMAND:
90 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
91 case CONNECTION_TYPE_COMMAND_STARTTLS:
92 imap_port = IMAP_DEFAULT_PORT;
93 break;
94
95 case CONNECTION_TYPE_TLS:
96 case CONNECTION_TYPE_COMMAND_TLS:
97 imap_port = IMAPS_DEFAULT_PORT;
98 break;
99 }
100 }
101
102 imap_storage->imap_port = imap_port;
103
104 if (imap_command != NULL) {
105 imap_storage->imap_command = strdup(imap_command);
106 if (imap_storage->imap_command == NULL)
107 goto free_servername;
108 }
109 else
110 imap_storage->imap_command = NULL;
111
112 imap_storage->imap_auth_type = imap_auth_type;
113
114 if (imap_login != NULL) {
115 imap_storage->imap_login = strdup(imap_login);
116 if (imap_storage->imap_login == NULL)
117 goto free_command;
118 }
119 else
120 imap_storage->imap_login = NULL;
121
122 if (imap_password != NULL) {
123 imap_storage->imap_password = strdup(imap_password);
124 if (imap_storage->imap_password == NULL)
125 goto free_login;
126 }
127 else
128 imap_storage->imap_password = NULL;
129
130 imap_storage->imap_cached = imap_cached;
131
132 if (imap_cached && (imap_cache_directory != NULL)) {
133 imap_storage->imap_cache_directory = strdup(imap_cache_directory);
134 if (imap_storage->imap_cache_directory == NULL)
135 goto free_password;
136 }
137 else {
138 imap_storage->imap_cached = FALSE;
139 imap_storage->imap_cache_directory = NULL;
140 }
141
142 storage->sto_data = imap_storage;
143 storage->sto_driver = &imap_mailstorage_driver;
144
145 return MAIL_NO_ERROR;
146
147 free_password:
148 free(imap_storage->imap_password);
149 free_login:
150 free(imap_storage->imap_login);
151 free_command:
152 free(imap_storage->imap_command);
153 free_servername:
154 free(imap_storage->imap_servername);
155 free:
156 free(imap_storage);
157 err:
158 return MAIL_ERROR_MEMORY;
159}
160
161static void imap_mailstorage_uninitialize(struct mailstorage * storage)
162{
163 struct imap_mailstorage * imap_storage;
164
165 imap_storage = storage->sto_data;
166
167 if (imap_storage->imap_cache_directory != NULL)
168 free(imap_storage->imap_cache_directory);
169 if (imap_storage->imap_password != NULL)
170 free(imap_storage->imap_password);
171 if (imap_storage->imap_login != NULL)
172 free(imap_storage->imap_login);
173 if (imap_storage->imap_command != NULL)
174 free(imap_storage->imap_command);
175 free(imap_storage->imap_servername);
176 free(imap_storage);
177
178 storage->sto_data = NULL;
179}
180
181static int imap_connect(struct mailstorage * storage,
182 mailsession ** result)
183{
184 struct imap_mailstorage * imap_storage;
185 mailsession_driver * driver;
186 int r;
187 int res;
188 mailsession * session;
189
190 imap_storage = storage->sto_data;
191
192 if (imap_storage->imap_cached)
193 driver = imap_cached_session_driver;
194 else
195 driver = imap_session_driver;
196
197 r = mailstorage_generic_connect(driver,
198 imap_storage->imap_servername,
199 imap_storage->imap_port,
200 imap_storage->imap_command,
201 imap_storage->imap_connection_type,
202 IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY,
203 imap_storage->imap_cache_directory,
204 0, NULL,
205 &session);
206 switch (r) {
207 case MAIL_NO_ERROR_NON_AUTHENTICATED:
208 case MAIL_NO_ERROR_AUTHENTICATED:
209 case MAIL_NO_ERROR:
210 break;
211 default:
212 res = r;
213 goto err;
214 }
215
216 r = mailstorage_generic_auth(session, r,
217 imap_storage->imap_connection_type,
218 imap_storage->imap_login,
219 imap_storage->imap_password);
220 if (r != MAIL_NO_ERROR) {
221 res = r;
222 goto free;
223 }
224
225 * result = session;
226
227 return MAIL_NO_ERROR;
228
229 free:
230 mailsession_free(session);
231 err:
232 return res;
233}
234
235static int imap_mailstorage_connect(struct mailstorage * storage)
236{
237 mailsession * session;
238 int r;
239 int res;
240
241 r = imap_connect(storage, &session);
242 if (r != MAIL_NO_ERROR) {
243 res = r;
244 goto err;
245 }
246
247 r = mailsession_select_folder(session, "INBOX");
248 if (r != MAIL_NO_ERROR) {
249 mailsession_logout(session);
250 res = r;
251 goto err;
252 }
253
254 storage->sto_session = session;
255 storage->sto_driver = &imap_mailstorage_driver;
256
257 return MAIL_NO_ERROR;
258
259 err:
260 return res;
261}
262
263static int
264imap_mailstorage_get_folder_session(struct mailstorage * storage,
265 char * pathname, mailsession ** result)
266{
267 mailsession * session;
268 int r;
269 int res;
270
271 if (strcasecmp(pathname, "INBOX") == 0) {
272 session = storage->sto_session;
273 }
274 else {
275 r = imap_connect(storage, &session);
276 if (r != MAIL_NO_ERROR) {
277 res = r;
278 goto err;
279 }
280
281 r = mailsession_select_folder(session, pathname);
282 if (r != MAIL_NO_ERROR) {
283 mailsession_logout(session);
284 res = r;
285 goto free;
286 }
287 }
288
289 * result = session;
290
291 return MAIL_NO_ERROR;
292
293 free:
294 mailsession_free(session);
295 err:
296 return res;
297}
diff --git a/kmicromail/libetpan/generic/imapstorage.h b/kmicromail/libetpan/generic/imapstorage.h
new file mode 100644
index 0000000..ebc42b0
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapstorage.h
@@ -0,0 +1,90 @@
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#ifndef IMAPSTORAGE_H
37
38#define IMAPSTORAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/imapdriver_types.h>
45
46/*
47 imap_mailstorage_init is the constructor for a IMAP4rev1 storage
48
49 @param storage this is the storage to initialize.
50
51 @param servername this is the name of the IMAP4rev1 server
52
53 @param port is the port to connect to, on the server.
54 you give 0 to use the default port.
55
56 @param command the command used to connect to the server instead of
57 allowing normal TCP connections to be used.
58
59 @param connection_type is the type of socket layer to use.
60 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
61 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
62 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
63 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
64
65 @param auth_type is the authenticate mechanism to use.
66 The value can be IMAP_AUTH_TYPE_PLAIN.
67 Other values are not yet implemented.
68
69 @param login is the login of the IMAP4rev1 account.
70
71 @param password is the password of the IMAP4rev1 account.
72
73 @param cached if this value is != 0, a persistant cache will be
74 stored on local system.
75
76 @param cache_directory is the location of the cache
77*/
78
79int imap_mailstorage_init(struct mailstorage * storage,
80 char * imap_servername, uint16_t imap_port,
81 char * imap_command,
82 int imap_connection_type, int imap_auth_type,
83 char * imap_login, char * imap_password,
84 int imap_cached, char * imap_cache_directory);
85
86#ifdef __cplusplus
87}
88#endif
89
90#endif
diff --git a/kmicromail/libetpan/generic/imfcache.c b/kmicromail/libetpan/generic/imfcache.c
new file mode 100644
index 0000000..64983f4
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imfcache.c
@@ -0,0 +1,1429 @@
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 "imfcache.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index,
42 struct mailimf_field * field);
43static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index,
44 struct mailimf_orig_date * date);
45static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index,
46 struct mailimf_date_time * date_time);
47static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index,
48 struct mailimf_from * from);
49static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index,
50 struct mailimf_sender * sender);
51static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index,
52 struct mailimf_reply_to * reply_to);
53static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index,
54 struct mailimf_to * to);
55static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index,
56 struct mailimf_cc * to);
57static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index,
58 struct mailimf_bcc * to);
59static int mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index,
60 struct mailimf_message_id * message_id);
61static int mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index,
62 clist * list);
63static int mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index,
64 struct mailimf_in_reply_to *
65 in_reply_to);
66static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index,
67 struct mailimf_references * references);
68static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index,
69 struct mailimf_subject * subject);
70static int mailimf_cache_address_list_write(MMAPString * mmapstr,
71 size_t * index,
72 struct mailimf_address_list *
73 addr_list);
74static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index,
75 struct mailimf_address * addr);
76static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index,
77 struct mailimf_group * group);
78static int mailimf_cache_mailbox_list_write(MMAPString * mmapstr,
79 size_t * index,
80 struct mailimf_mailbox_list * mb_list);
81static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index,
82 struct mailimf_mailbox * mb);
83
84
85static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index,
86 struct mailimf_field ** result);
87static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index,
88 struct mailimf_orig_date ** result);
89static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index,
90 struct mailimf_date_time ** result);
91static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index,
92 struct mailimf_from ** result);
93static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index,
94 struct mailimf_sender ** result);
95static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index,
96 struct mailimf_reply_to ** result);
97static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index,
98 struct mailimf_to ** result);
99static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index,
100 struct mailimf_cc ** result);
101static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index,
102 struct mailimf_bcc ** result);
103static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index,
104 struct mailimf_message_id ** result);
105static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index,
106 clist ** result);
107static int
108mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index,
109 struct mailimf_in_reply_to ** result);
110
111static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index,
112 struct mailimf_references ** result);
113static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index,
114 struct mailimf_subject ** result);
115static int mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index,
116 struct mailimf_address_list ** result);
117static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index,
118 struct mailimf_address ** result);
119static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index,
120 struct mailimf_group ** result);
121static int
122mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index,
123 struct mailimf_mailbox_list ** result);
124static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index,
125 struct mailimf_mailbox ** result);
126
127enum {
128 CACHE_NULL_POINTER = 0,
129 CACHE_NOT_NULL = 1,
130};
131
132int mail_serialize_clear(MMAPString * mmapstr, size_t * index)
133{
134 if (mmap_string_set_size(mmapstr, 0) == NULL)
135 return MAIL_ERROR_MEMORY;
136
137 * index = 0;
138
139 return MAIL_NO_ERROR;
140}
141
142int mail_serialize_write(MMAPString * mmapstr, size_t * index,
143 char * buf, size_t size)
144{
145 if (mmap_string_append_len(mmapstr, buf, size) == NULL)
146 return MAIL_ERROR_MEMORY;
147
148 * index = * index + size;
149
150 return MAIL_NO_ERROR;
151}
152
153int mail_serialize_read(MMAPString * mmapstr, size_t * index,
154 char * buf, size_t size)
155{
156 size_t cur_token;
157
158 cur_token = * index;
159
160 if (cur_token + size > mmapstr->len)
161 return MAIL_ERROR_STREAM;
162
163 memcpy(buf, mmapstr->str + cur_token, size);
164 * index = cur_token + size;
165
166 return MAIL_NO_ERROR;
167}
168
169int mailimf_cache_int_write(MMAPString * mmapstr, size_t * index,
170 uint32_t value)
171{
172 unsigned char ch;
173 int r;
174 int i;
175
176 for(i = 0 ; i < 4 ; i ++) {
177 ch = value % 256;
178
179 r = mail_serialize_write(mmapstr, index, &ch, 1);
180 if (r != MAIL_NO_ERROR)
181 return r;
182 value /= 256;
183 }
184
185 return MAIL_NO_ERROR;
186}
187
188int mailimf_cache_int_read(MMAPString * mmapstr, size_t * index,
189 uint32_t * result)
190{
191 unsigned char ch;
192 uint32_t value;
193 int i;
194 int r;
195
196 value = 0;
197 for(i = 0 ; i < 4 ; i ++) {
198 r = mail_serialize_read(mmapstr, index, &ch, 1);
199 if (r != MAIL_NO_ERROR)
200 return r;
201 value = value | ch << (i << 3);
202 }
203
204 * result = value;
205
206 return MAIL_NO_ERROR;
207}
208
209
210int mailimf_cache_string_write(MMAPString * mmapstr, size_t * index,
211 char * str, size_t length)
212{
213 int r;
214
215 if (str == NULL) {
216 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
217 if (r != MAIL_NO_ERROR)
218 return r;
219 }
220 else {
221 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
222 if (r != MAIL_NO_ERROR)
223 return r;
224
225 r = mailimf_cache_int_write(mmapstr, index, length);
226 if (r != MAIL_NO_ERROR)
227 return r;
228
229 if (length != 0) {
230 r = mail_serialize_write(mmapstr, index, str, length);
231 if (r != MAIL_NO_ERROR)
232 return MAIL_ERROR_FILE;
233 }
234 }
235
236 return MAIL_NO_ERROR;
237}
238
239int mailimf_cache_string_read(MMAPString * mmapstr, size_t * index,
240 char ** result)
241{
242 int r;
243 uint32_t length;
244 char * str;
245 uint32_t type;
246
247 r = mailimf_cache_int_read(mmapstr, index, &type);
248 if (r != MAIL_NO_ERROR)
249 return r;
250
251 if (type == CACHE_NULL_POINTER) {
252 str = NULL;
253 }
254 else {
255 r = mailimf_cache_int_read(mmapstr, index, &length);
256 if (r != MAIL_NO_ERROR)
257 return r;
258
259 str = malloc(length + 1);
260 if (str == NULL)
261 return MAIL_ERROR_MEMORY;
262
263 r = mail_serialize_read(mmapstr, index, str, length);
264 if (r != MAIL_NO_ERROR)
265 return MAIL_ERROR_FILE;
266
267 str[length] = 0;
268 }
269
270 * result = str;
271
272 return MAIL_NO_ERROR;
273}
274
275int mailimf_cache_fields_write(MMAPString * mmapstr, size_t * index,
276 struct mailimf_fields * fields)
277{
278 clistiter * cur;
279 int r;
280
281 r = mailimf_cache_int_write(mmapstr, index,
282 clist_count(fields->fld_list));
283 if (r != MAIL_NO_ERROR)
284 return r;
285
286 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
287 cur = clist_next(cur)) {
288 r = mailimf_cache_field_write(mmapstr, index, clist_content(cur));
289 if (r != MAIL_NO_ERROR)
290 return r;
291 }
292
293 return MAIL_NO_ERROR;
294}
295
296int mailimf_cache_fields_read(MMAPString * mmapstr, size_t * index,
297 struct mailimf_fields ** result)
298{
299 clist * list;
300 int r;
301 uint32_t count;
302 uint32_t i;
303 struct mailimf_fields * fields;
304 int res;
305
306 r = mailimf_cache_int_read(mmapstr, index, &count);
307 if (r != MAIL_NO_ERROR) {
308 res = r;
309 goto err;
310 }
311
312 list = clist_new();
313 if (list == NULL) {
314 res = MAIL_ERROR_MEMORY;
315 goto err;
316 }
317
318 for(i = 0 ; i < count ; i++) {
319 struct mailimf_field * field;
320
321 r = mailimf_cache_field_read(mmapstr, index, &field);
322 if (r != MAIL_NO_ERROR) {
323 res = r;
324 goto free_list;
325 }
326
327 r = clist_append(list, field);
328 if (r < 0) {
329 mailimf_field_free(field);
330 res = MAIL_ERROR_MEMORY;
331 goto free_list;
332 }
333 }
334
335 fields = mailimf_fields_new(list);
336 if (fields == NULL) {
337 res = MAIL_ERROR_MEMORY;
338 goto free_list;
339 }
340
341 * result = fields;
342
343 return MAIL_NO_ERROR;
344
345 free_list:
346 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
347 clist_free(list);
348 err:
349 return res;
350}
351
352
353static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index,
354 struct mailimf_field * field)
355{
356 int r;
357
358 r = mailimf_cache_int_write(mmapstr, index, field->fld_type);
359 if (r != MAIL_NO_ERROR)
360 return r;
361
362 switch (field->fld_type) {
363 case MAILIMF_FIELD_ORIG_DATE:
364 r = mailimf_cache_orig_date_write(mmapstr, index,
365 field->fld_data.fld_orig_date);
366 break;
367 case MAILIMF_FIELD_FROM:
368 r = mailimf_cache_from_write(mmapstr, index,
369 field->fld_data.fld_from);
370 break;
371 case MAILIMF_FIELD_SENDER:
372 r = mailimf_cache_sender_write(mmapstr, index,
373 field->fld_data.fld_sender);
374 break;
375 case MAILIMF_FIELD_REPLY_TO:
376 r = mailimf_cache_reply_to_write(mmapstr, index,
377 field->fld_data.fld_reply_to);
378 break;
379 case MAILIMF_FIELD_TO:
380 r = mailimf_cache_to_write(mmapstr, index,
381 field->fld_data.fld_to);
382 break;
383 case MAILIMF_FIELD_CC:
384 r = mailimf_cache_cc_write(mmapstr, index,
385 field->fld_data.fld_cc);
386 break;
387 case MAILIMF_FIELD_BCC:
388 r = mailimf_cache_bcc_write(mmapstr, index,
389 field->fld_data.fld_bcc);
390 break;
391 case MAILIMF_FIELD_MESSAGE_ID:
392 r = mailimf_cache_message_id_write(mmapstr, index,
393 field->fld_data.fld_message_id);
394 break;
395 case MAILIMF_FIELD_IN_REPLY_TO:
396 r = mailimf_cache_in_reply_to_write(mmapstr, index,
397 field->fld_data.fld_in_reply_to);
398 break;
399 case MAILIMF_FIELD_REFERENCES:
400 r = mailimf_cache_references_write(mmapstr, index,
401 field->fld_data.fld_references);
402 break;
403 case MAILIMF_FIELD_SUBJECT:
404 r = mailimf_cache_subject_write(mmapstr, index,
405 field->fld_data.fld_subject);
406 break;
407 default:
408 r = 0;
409 break;
410 }
411
412 if (r != MAIL_NO_ERROR)
413 return r;
414
415 return MAIL_NO_ERROR;
416}
417
418
419static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index,
420 struct mailimf_field ** result)
421{
422 int r;
423 uint32_t type;
424 struct mailimf_orig_date * orig_date;
425 struct mailimf_from * from;
426 struct mailimf_sender * sender;
427 struct mailimf_to * to;
428 struct mailimf_reply_to * reply_to;
429 struct mailimf_cc * cc;
430 struct mailimf_bcc * bcc;
431 struct mailimf_message_id * message_id;
432 struct mailimf_in_reply_to * in_reply_to;
433 struct mailimf_references * references;
434 struct mailimf_subject * subject;
435 struct mailimf_field * field;
436 int res;
437
438 orig_date = NULL;
439 from = NULL;
440 sender = NULL;
441 to = NULL;
442 reply_to = NULL;
443 cc = NULL;
444 bcc = NULL;
445 message_id = NULL;
446 in_reply_to = NULL;
447 references = NULL;
448 subject = NULL;
449 field = NULL;
450
451 r = mailimf_cache_int_read(mmapstr, index, &type);
452 if (r != MAIL_NO_ERROR) {
453 res = r;
454 goto err;
455 }
456
457 switch (type) {
458 case MAILIMF_FIELD_ORIG_DATE:
459 r = mailimf_cache_orig_date_read(mmapstr, index, &orig_date);
460 break;
461 case MAILIMF_FIELD_FROM:
462 r = mailimf_cache_from_read(mmapstr, index, &from);
463 break;
464 case MAILIMF_FIELD_SENDER:
465 r = mailimf_cache_sender_read(mmapstr, index, &sender);
466 break;
467 case MAILIMF_FIELD_REPLY_TO:
468 r = mailimf_cache_reply_to_read(mmapstr, index, &reply_to);
469 break;
470 case MAILIMF_FIELD_TO:
471 r = mailimf_cache_to_read(mmapstr, index, &to);
472 break;
473 case MAILIMF_FIELD_CC:
474 r = mailimf_cache_cc_read(mmapstr, index, &cc);
475 break;
476 case MAILIMF_FIELD_BCC:
477 r = mailimf_cache_bcc_read(mmapstr, index, &bcc);
478 break;
479 case MAILIMF_FIELD_MESSAGE_ID:
480 r = mailimf_cache_message_id_read(mmapstr, index, &message_id);
481 break;
482 case MAILIMF_FIELD_IN_REPLY_TO:
483 r = mailimf_cache_in_reply_to_read(mmapstr, index, &in_reply_to);
484 break;
485 case MAILIMF_FIELD_REFERENCES:
486 r = mailimf_cache_references_read(mmapstr, index, &references);
487 break;
488 case MAILIMF_FIELD_SUBJECT:
489 r = mailimf_cache_subject_read(mmapstr, index, &subject);
490 break;
491 default:
492 r = MAIL_ERROR_INVAL;
493 break;
494 }
495
496 if (r != MAIL_NO_ERROR) {
497 res = r;
498 goto free;
499 }
500
501 field = mailimf_field_new(type, NULL, NULL, NULL, NULL, NULL,
502 NULL, NULL, NULL, orig_date, from, sender, reply_to,
503 to, cc, bcc, message_id,
504 in_reply_to, references,
505 subject, NULL, NULL, NULL);
506 if (field == NULL) {
507 res = MAIL_ERROR_MEMORY;
508 goto free;
509 }
510
511 * result = field;
512
513 return MAIL_NO_ERROR;
514
515 free:
516 if (orig_date != NULL)
517 mailimf_orig_date_free(orig_date);
518 if (from != NULL)
519 mailimf_from_free(from);
520 if (sender != NULL)
521 mailimf_sender_free(sender);
522 if (reply_to != NULL)
523 mailimf_reply_to_free(reply_to);
524 if (to != NULL)
525 mailimf_to_free(to);
526 if (cc != NULL)
527 mailimf_cc_free(cc);
528 if (bcc != NULL)
529 mailimf_bcc_free(bcc);
530 if (message_id != NULL)
531 mailimf_message_id_free(message_id);
532 if (in_reply_to != NULL)
533 mailimf_in_reply_to_free(in_reply_to);
534 if (references != NULL)
535 mailimf_references_free(references);
536 if (subject != NULL)
537 mailimf_subject_free(subject);
538 err:
539 return res;
540}
541
542static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index,
543 struct mailimf_orig_date * date)
544{
545 return mailimf_cache_date_time_write(mmapstr, index, date->dt_date_time);
546}
547
548static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index,
549 struct mailimf_orig_date ** result)
550{
551 int r;
552 struct mailimf_date_time * date_time;
553 struct mailimf_orig_date * orig_date;
554
555 r = mailimf_cache_date_time_read(mmapstr, index, &date_time);
556 if (r != MAIL_NO_ERROR)
557 return r;
558
559 orig_date = mailimf_orig_date_new(date_time);
560 if (orig_date == NULL) {
561 mailimf_date_time_free(date_time);
562 return MAIL_ERROR_MEMORY;
563 }
564
565 * result = orig_date;
566
567 return MAIL_NO_ERROR;
568}
569
570static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index,
571 struct mailimf_date_time * date_time)
572{
573 int r;
574
575 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_day);
576 if (r != MAIL_NO_ERROR)
577 return r;
578
579 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_month);
580 if (r != MAIL_NO_ERROR)
581 return r;
582
583 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_year);
584 if (r != MAIL_NO_ERROR)
585 return r;
586
587 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_hour);
588 if (r != MAIL_NO_ERROR)
589 return r;
590
591 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_min);
592 if (r != MAIL_NO_ERROR)
593 return r;
594
595 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_sec);
596 if (r != MAIL_NO_ERROR)
597 return r;
598
599 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_zone);
600 if (r != MAIL_NO_ERROR)
601 return r;
602
603 return MAIL_NO_ERROR;
604}
605
606static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index,
607 struct mailimf_date_time ** result)
608{
609 int r;
610 uint32_t day;
611 uint32_t month;
612 uint32_t year;
613 uint32_t hour;
614 uint32_t min;
615 uint32_t sec;
616 uint32_t zone;
617 struct mailimf_date_time * date_time;
618
619 r = mailimf_cache_int_read(mmapstr, index, &day);
620 if (r != MAIL_NO_ERROR)
621 return r;
622
623 r = mailimf_cache_int_read(mmapstr, index, &month);
624 if (r != MAIL_NO_ERROR)
625 return r;
626
627 r = mailimf_cache_int_read(mmapstr, index, &year);
628 if (r != MAIL_NO_ERROR)
629 return r;
630
631 r = mailimf_cache_int_read(mmapstr, index, &hour);
632 if (r != MAIL_NO_ERROR)
633 return r;
634
635 r = mailimf_cache_int_read(mmapstr, index, &min);
636 if (r != MAIL_NO_ERROR)
637 return r;
638
639 r = mailimf_cache_int_read(mmapstr, index, &sec);
640 if (r != MAIL_NO_ERROR)
641 return r;
642
643 r = mailimf_cache_int_read(mmapstr, index, &zone);
644 if (r != MAIL_NO_ERROR)
645 return r;
646
647 date_time = mailimf_date_time_new(day, month, year, hour, min, sec, zone);
648 if (date_time == NULL)
649 return MAIL_ERROR_MEMORY;
650
651 * result = date_time;
652
653 return MAIL_NO_ERROR;
654
655}
656
657
658static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index,
659 struct mailimf_from * from)
660{
661 return mailimf_cache_mailbox_list_write(mmapstr, index, from->frm_mb_list);
662}
663
664static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index,
665 struct mailimf_from ** result)
666{
667 struct mailimf_mailbox_list * mb_list;
668 struct mailimf_from * from;
669 int r;
670
671 r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list);
672 if (r != MAIL_NO_ERROR)
673 return r;
674
675 from = mailimf_from_new(mb_list);
676 if (from == NULL) {
677 mailimf_mailbox_list_free(mb_list);
678 return MAIL_ERROR_MEMORY;
679 }
680
681 * result = from;
682
683 return MAIL_NO_ERROR;
684}
685
686static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index,
687 struct mailimf_sender * sender)
688{
689 return mailimf_cache_mailbox_write(mmapstr, index, sender->snd_mb);
690}
691
692static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index,
693 struct mailimf_sender ** result)
694{
695 int r;
696 struct mailimf_mailbox * mb;
697 struct mailimf_sender * sender;
698
699 r = mailimf_cache_mailbox_read(mmapstr, index, &mb);
700 if (r != MAIL_NO_ERROR)
701 return r;
702
703 sender = mailimf_sender_new(mb);
704 if (sender == NULL) {
705 mailimf_mailbox_free(mb);
706 return MAIL_ERROR_MEMORY;
707 }
708
709 * result = sender;
710
711 return MAIL_NO_ERROR;
712}
713
714static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index,
715 struct mailimf_reply_to * reply_to)
716{
717 return mailimf_cache_address_list_write(mmapstr, index,
718 reply_to->rt_addr_list);
719}
720
721static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index,
722 struct mailimf_reply_to ** result)
723{
724 int r;
725 struct mailimf_address_list * addr_list;
726 struct mailimf_reply_to * reply_to;
727
728 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
729 if (r != MAIL_NO_ERROR)
730 return r;
731
732 reply_to = mailimf_reply_to_new(addr_list);
733 if (reply_to == NULL) {
734 mailimf_address_list_free(addr_list);
735 return MAIL_ERROR_MEMORY;
736 }
737
738 * result = reply_to;
739
740 return MAIL_NO_ERROR;
741}
742
743static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index,
744 struct mailimf_to * to)
745{
746 return mailimf_cache_address_list_write(mmapstr, index, to->to_addr_list);
747}
748
749static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index,
750 struct mailimf_to ** result)
751{
752 int r;
753 struct mailimf_address_list * addr_list;
754 struct mailimf_to * to;
755
756 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
757 if (r != MAIL_NO_ERROR)
758 return r;
759
760 to = mailimf_to_new(addr_list);
761 if (to == NULL) {
762 mailimf_address_list_free(addr_list);
763 return MAIL_ERROR_MEMORY;
764 }
765
766 * result = to;
767
768 return MAIL_NO_ERROR;
769}
770
771static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index,
772 struct mailimf_cc * cc)
773{
774 return mailimf_cache_address_list_write(mmapstr, index, cc->cc_addr_list);
775}
776
777static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index,
778 struct mailimf_cc ** result)
779{
780 int r;
781 struct mailimf_address_list * addr_list;
782 struct mailimf_cc * cc;
783
784 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
785 if (r != MAIL_NO_ERROR)
786 return r;
787
788 cc = mailimf_cc_new(addr_list);
789 if (cc == NULL) {
790 mailimf_address_list_free(addr_list);
791 return MAIL_ERROR_MEMORY;
792 }
793
794 * result = cc;
795
796 return MAIL_NO_ERROR;
797}
798
799static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index,
800 struct mailimf_bcc * bcc)
801{
802 return mailimf_cache_address_list_write(mmapstr, index, bcc->bcc_addr_list);
803}
804
805static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index,
806 struct mailimf_bcc ** result)
807{
808 int r;
809 struct mailimf_address_list * addr_list;
810 struct mailimf_bcc * bcc;
811
812 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
813 if (r != MAIL_NO_ERROR)
814 return r;
815
816 bcc = mailimf_bcc_new(addr_list);
817 if (bcc == NULL) {
818 mailimf_address_list_free(addr_list);
819 return MAIL_ERROR_MEMORY;
820 }
821
822 * result = bcc;
823
824 return MAIL_NO_ERROR;
825}
826
827static int
828mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index,
829 struct mailimf_message_id * message_id)
830{
831 return mailimf_cache_string_write(mmapstr, index,
832 message_id->mid_value, strlen(message_id->mid_value));
833}
834
835static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index,
836 struct mailimf_message_id ** result)
837{
838 struct mailimf_message_id * message_id;
839 char * str;
840 int r;
841
842 r = mailimf_cache_string_read(mmapstr, index, &str);
843 if (r != MAIL_NO_ERROR)
844 return r;
845
846 message_id = mailimf_message_id_new(str);
847 if (message_id == NULL) {
848 free(str);
849 return MAIL_ERROR_MEMORY;
850 }
851
852 * result = message_id;
853
854 return MAIL_NO_ERROR;
855}
856
857static int
858mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index,
859 clist * list)
860{
861 clistiter * cur;
862 int r;
863
864 r = mailimf_cache_int_write(mmapstr, index, clist_count(list));
865 if (r != MAIL_NO_ERROR)
866 return r;
867
868 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
869 char * msgid;
870
871 msgid = clist_content(cur);
872
873 r = mailimf_cache_string_write(mmapstr, index, msgid, strlen(msgid));
874 if (r != MAIL_NO_ERROR)
875 return r;
876 }
877
878 return MAIL_NO_ERROR;
879}
880
881static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index,
882 clist ** result)
883{
884 clist * list;
885 int r;
886 uint32_t count;
887 uint32_t i;
888 int res;
889
890 r = mailimf_cache_int_read(mmapstr, index, &count);
891 if (r != MAIL_NO_ERROR) {
892 res = r;
893 goto err;
894 }
895
896 list = clist_new();
897 if (list == NULL) {
898 res = MAIL_ERROR_MEMORY;
899 goto err;
900 }
901
902 for(i = 0 ; i < count ; i++) {
903 char * msgid;
904
905 r = mailimf_cache_string_read(mmapstr, index, &msgid);
906 if (r != MAIL_NO_ERROR) {
907 res = r;
908 goto err;
909 }
910
911 r = clist_append(list, msgid);
912 if (r < 0) {
913 free(msgid);
914 res = MAIL_ERROR_MEMORY;
915 goto free_list;
916 }
917 }
918
919 * result = list;
920
921 return MAIL_NO_ERROR;
922
923 free_list:
924 clist_foreach(list, (clist_func) free, NULL);
925 clist_free(list);
926 err:
927 return res;
928}
929
930static int
931mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index,
932 struct mailimf_in_reply_to * in_reply_to)
933{
934 return mailimf_cache_msg_id_list_write(mmapstr, index,
935 in_reply_to->mid_list);
936}
937
938static int mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index,
939 struct mailimf_in_reply_to ** result)
940{
941 int r;
942 clist * msg_id_list;
943 struct mailimf_in_reply_to * in_reply_to;
944
945 r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list);
946 if (r != MAIL_NO_ERROR)
947 return r;
948
949 in_reply_to = mailimf_in_reply_to_new(msg_id_list);
950 if (in_reply_to == NULL) {
951 clist_foreach(msg_id_list, (clist_func) free, NULL);
952 clist_free(msg_id_list);
953 return MAIL_ERROR_MEMORY;
954 }
955
956 * result = in_reply_to;
957
958 return MAIL_NO_ERROR;
959}
960
961static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index,
962 struct mailimf_references * references)
963{
964 return mailimf_cache_msg_id_list_write(mmapstr, index,
965 references->mid_list);
966}
967
968static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index,
969 struct mailimf_references ** result)
970{
971 int r;
972 clist * msg_id_list;
973 struct mailimf_references * references;
974
975 r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list);
976 if (r != MAIL_NO_ERROR)
977 return r;
978
979 references = mailimf_references_new(msg_id_list);
980 if (references == NULL) {
981 clist_foreach(msg_id_list, (clist_func) free, NULL);
982 clist_free(msg_id_list);
983 return MAIL_ERROR_MEMORY;
984 }
985
986 * result = references;
987
988 return MAIL_NO_ERROR;
989}
990
991
992static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index,
993 struct mailimf_subject * subject)
994{
995 return mailimf_cache_string_write(mmapstr, index,
996 subject->sbj_value, strlen(subject->sbj_value));
997}
998
999static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index,
1000 struct mailimf_subject ** result)
1001{
1002 char * str;
1003 struct mailimf_subject * subject;
1004 int r;
1005
1006 r = mailimf_cache_string_read(mmapstr, index, &str);
1007 if (r != MAIL_NO_ERROR)
1008 return r;
1009
1010 if (str == NULL) {
1011 str = strdup("");
1012 if (str == NULL)
1013 return MAIL_ERROR_MEMORY;
1014 }
1015
1016 subject = mailimf_subject_new(str);
1017 if (subject == NULL) {
1018 free(str);
1019 return MAIL_ERROR_MEMORY;
1020 }
1021
1022 * result = subject;
1023
1024 return MAIL_NO_ERROR;
1025}
1026
1027
1028static int
1029mailimf_cache_address_list_write(MMAPString * mmapstr, size_t * index,
1030 struct mailimf_address_list * addr_list)
1031{
1032 clistiter * cur;
1033 int r;
1034
1035 if (addr_list == NULL) {
1036 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
1037 if (r != MAIL_NO_ERROR)
1038 return r;
1039 }
1040 else {
1041 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
1042 if (r != MAIL_NO_ERROR)
1043 return r;
1044
1045 r = mailimf_cache_int_write(mmapstr, index,
1046 clist_count(addr_list->ad_list));
1047 if (r != MAIL_NO_ERROR)
1048 return r;
1049
1050 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
1051 cur = clist_next(cur)) {
1052 struct mailimf_address * addr;
1053
1054 addr = clist_content(cur);
1055
1056 r = mailimf_cache_address_write(mmapstr, index, addr);
1057 if (r != MAIL_NO_ERROR)
1058 return r;
1059 }
1060 }
1061
1062 return MAIL_NO_ERROR;
1063}
1064
1065static int
1066mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index,
1067 struct mailimf_address_list ** result)
1068{
1069 struct mailimf_address_list * addr_list;
1070 uint32_t count;
1071 uint32_t i;
1072 int r;
1073 clist * list;
1074 int res;
1075 uint32_t type;
1076
1077 r = mailimf_cache_int_read(mmapstr, index, &type);
1078 if (r != MAIL_NO_ERROR) {
1079 res = r;
1080 goto err;
1081 }
1082
1083 if (type == CACHE_NULL_POINTER) {
1084 * result = NULL;
1085 return MAIL_NO_ERROR;
1086 }
1087
1088 r = mailimf_cache_int_read(mmapstr, index, &count);
1089 if (r != MAIL_NO_ERROR) {
1090 res = r;
1091 goto err;
1092 }
1093
1094 list = clist_new();
1095 if (list == NULL) {
1096 res = MAIL_ERROR_MEMORY;
1097 goto err;
1098 }
1099
1100 for(i = 0 ; i < count ; i++) {
1101 struct mailimf_address * addr;
1102
1103 r = mailimf_cache_address_read(mmapstr, index, &addr);
1104 if (r != MAIL_NO_ERROR) {
1105 res = r;
1106 goto free_list;
1107 }
1108
1109 r = clist_append(list, addr);
1110 if (r < 0) {
1111 mailimf_address_free(addr);
1112 res = MAIL_ERROR_MEMORY;
1113 goto free_list;
1114 }
1115 }
1116
1117 addr_list = mailimf_address_list_new(list);
1118 if (addr_list == NULL) {
1119 res = MAIL_ERROR_MEMORY;
1120 goto free_list;
1121 }
1122
1123 * result = addr_list;
1124
1125 return MAIL_NO_ERROR;
1126
1127 free_list:
1128 clist_foreach(list, (clist_func) mailimf_address_free, NULL);
1129 clist_free(list);
1130 err:
1131 return res;
1132}
1133
1134static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index,
1135 struct mailimf_address * addr)
1136{
1137 int r;
1138
1139 r = mailimf_cache_int_write(mmapstr, index, addr->ad_type);
1140 if (r != MAIL_NO_ERROR)
1141 return r;
1142
1143 switch(addr->ad_type) {
1144 case MAILIMF_ADDRESS_MAILBOX:
1145 r = mailimf_cache_mailbox_write(mmapstr, index, addr->ad_data.ad_mailbox);
1146 if (r != MAIL_NO_ERROR)
1147 return r;
1148
1149 break;
1150
1151 case MAILIMF_ADDRESS_GROUP:
1152 r = mailimf_cache_group_write(mmapstr, index, addr->ad_data.ad_group);
1153 if (r != MAIL_NO_ERROR)
1154 return r;
1155
1156 break;
1157 }
1158
1159 return MAIL_NO_ERROR;
1160}
1161
1162static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index,
1163 struct mailimf_address ** result)
1164{
1165 uint32_t type;
1166 int r;
1167 struct mailimf_mailbox * mailbox;
1168 struct mailimf_group * group;
1169 struct mailimf_address * addr;
1170
1171 r = mailimf_cache_int_read(mmapstr, index, &type);
1172 if (r != MAIL_NO_ERROR)
1173 return r;
1174
1175 mailbox = NULL;
1176 group = NULL;
1177
1178 switch (type) {
1179 case MAILIMF_ADDRESS_MAILBOX:
1180 r = mailimf_cache_mailbox_read(mmapstr, index, &mailbox);
1181 if (r != MAIL_NO_ERROR)
1182 return r;
1183
1184 break;
1185
1186 case MAILIMF_ADDRESS_GROUP:
1187 r = mailimf_cache_group_read(mmapstr, index, &group);
1188 if (r != MAIL_NO_ERROR)
1189 return r;
1190
1191 break;
1192 }
1193
1194 addr = mailimf_address_new(type, mailbox, group);
1195 if (addr == NULL)
1196 goto free;
1197
1198 * result = addr;
1199
1200 return MAIL_NO_ERROR;
1201
1202 free:
1203 if (mailbox != NULL)
1204 mailimf_mailbox_free(mailbox);
1205 if (group != NULL)
1206 mailimf_group_free(group);
1207 return MAIL_ERROR_MEMORY;
1208}
1209
1210static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index,
1211 struct mailimf_group * group)
1212{
1213 int r;
1214
1215 r = mailimf_cache_string_write(mmapstr, index, group->grp_display_name,
1216 strlen(group->grp_display_name));
1217 if (r != MAIL_NO_ERROR)
1218 return r;
1219
1220 r = mailimf_cache_mailbox_list_write(mmapstr, index, group->grp_mb_list);
1221 if (r != MAIL_NO_ERROR)
1222 return r;
1223
1224 return MAIL_NO_ERROR;
1225}
1226
1227static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index,
1228 struct mailimf_group ** result)
1229{
1230 int r;
1231 char * display_name;
1232 struct mailimf_mailbox_list * mb_list;
1233 struct mailimf_group * group;
1234 int res;
1235
1236 r = mailimf_cache_string_read(mmapstr, index, &display_name);
1237 if (r != MAIL_NO_ERROR) {
1238 res = r;
1239 goto err;
1240 }
1241
1242 r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list);
1243 if (r != MAIL_NO_ERROR) {
1244 res = r;
1245 goto free_dsp_name;
1246 }
1247
1248 group = mailimf_group_new(display_name, mb_list);
1249 if (group == NULL) {
1250 res = MAIL_ERROR_MEMORY;
1251 goto free_mb_list;
1252 }
1253
1254 * result = group;
1255
1256 return MAIL_NO_ERROR;
1257
1258 free_mb_list:
1259 mailimf_mailbox_list_free(mb_list);
1260 free_dsp_name:
1261 free(display_name);
1262 err:
1263 return res;
1264}
1265
1266static int
1267mailimf_cache_mailbox_list_write(MMAPString * mmapstr, size_t * index,
1268 struct mailimf_mailbox_list * mb_list)
1269{
1270 clistiter * cur;
1271 int r;
1272
1273 if (mb_list == NULL) {
1274 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
1275 if (r != MAIL_NO_ERROR)
1276 return r;
1277 }
1278 else {
1279 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
1280 if (r != MAIL_NO_ERROR)
1281 return r;
1282
1283 r = mailimf_cache_int_write(mmapstr, index,
1284 clist_count(mb_list->mb_list));
1285 if (r != MAIL_NO_ERROR)
1286 return r;
1287
1288 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
1289 cur = clist_next(cur)) {
1290 struct mailimf_mailbox * mb;
1291
1292 mb = clist_content(cur);
1293
1294 r = mailimf_cache_mailbox_write(mmapstr, index, mb);
1295 if (r != MAIL_NO_ERROR)
1296 return r;
1297 }
1298 }
1299
1300 return MAIL_NO_ERROR;
1301}
1302
1303static int
1304mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index,
1305 struct mailimf_mailbox_list ** result)
1306{
1307 clist * list;
1308 int r;
1309 uint32_t count;
1310 uint32_t i;
1311 struct mailimf_mailbox_list * mb_list;
1312 int res;
1313 uint32_t type;
1314
1315 r = mailimf_cache_int_read(mmapstr, index, &type);
1316 if (r != MAIL_NO_ERROR) {
1317 res = r;
1318 goto err;
1319 }
1320
1321 if (type == CACHE_NULL_POINTER) {
1322 * result = NULL;
1323 return MAIL_NO_ERROR;
1324 }
1325
1326 r = mailimf_cache_int_read(mmapstr, index, &count);
1327 if (r != MAIL_NO_ERROR) {
1328 res = r;
1329 goto err;
1330 }
1331
1332 list = clist_new();
1333 if (list == NULL) {
1334 res = MAIL_ERROR_MEMORY;
1335 goto err;
1336 }
1337
1338 for(i = 0 ; i < count ; i++) {
1339 struct mailimf_mailbox * mb;
1340
1341 r = mailimf_cache_mailbox_read(mmapstr, index, &mb);
1342 if (r != MAIL_NO_ERROR) {
1343 res = r;
1344 goto free_list;
1345 }
1346
1347 r = clist_append(list, mb);
1348 if (r < 0) {
1349 mailimf_mailbox_free(mb);
1350 res = MAIL_ERROR_MEMORY;
1351 goto free_list;
1352 }
1353 }
1354
1355 mb_list = mailimf_mailbox_list_new(list);
1356 if (mb_list == NULL) {
1357 res = MAIL_ERROR_MEMORY;
1358 goto free_list;
1359 }
1360
1361 * result = mb_list;
1362
1363 return MAIL_NO_ERROR;
1364
1365 free_list:
1366 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
1367 clist_free(list);
1368 err:
1369 return res;
1370}
1371
1372static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index,
1373 struct mailimf_mailbox * mb)
1374{
1375 int r;
1376
1377 if (mb->mb_display_name) {
1378 r = mailimf_cache_string_write(mmapstr, index,
1379 mb->mb_display_name, strlen(mb->mb_display_name));
1380 if (r != MAIL_NO_ERROR)
1381 return r;
1382 }
1383 else {
1384 r = mailimf_cache_string_write(mmapstr, index, NULL, 0);
1385 if (r != MAIL_NO_ERROR)
1386 return r;
1387 }
1388
1389 r = mailimf_cache_string_write(mmapstr, index,
1390 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
1391 if (r != MAIL_NO_ERROR)
1392 return r;
1393
1394 return MAIL_NO_ERROR;
1395}
1396
1397static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index,
1398 struct mailimf_mailbox ** result)
1399{
1400 int r;
1401 char * dsp_name;
1402 char * addr_spec;
1403 struct mailimf_mailbox * mb;
1404
1405 dsp_name = NULL;
1406
1407 r = mailimf_cache_string_read(mmapstr, index, &dsp_name);
1408 if (r != MAIL_NO_ERROR)
1409 return r;
1410
1411 r = mailimf_cache_string_read(mmapstr, index, &addr_spec);
1412 if (r != MAIL_NO_ERROR)
1413 goto free_dsp_name;
1414
1415 mb = mailimf_mailbox_new(dsp_name, addr_spec);
1416 if (mb == NULL)
1417 goto free_addr;
1418
1419 * result = mb;
1420
1421 return MAIL_NO_ERROR;
1422
1423 free_addr:
1424 free(addr_spec);
1425 free_dsp_name:
1426 if (dsp_name != NULL)
1427 free(dsp_name);
1428 return MAIL_ERROR_MEMORY;
1429}
diff --git a/kmicromail/libetpan/generic/imfcache.h b/kmicromail/libetpan/generic/imfcache.h
new file mode 100644
index 0000000..31c99c0
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imfcache.h
@@ -0,0 +1,75 @@
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#ifndef IMFCACHE_H
37
38#define IMFCACHE_H
39
40#include <stdio.h>
41#include "mailimf.h"
42#include "maildriver_types.h"
43#include "mmapstring.h"
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49int mail_serialize_clear(MMAPString * mmapstr, size_t * index);
50
51int mail_serialize_write(MMAPString * mmapstr, size_t * index,
52 char * buf, size_t size);
53
54int mail_serialize_read(MMAPString * mmapstr, size_t * index,
55 char * buf, size_t size);
56
57int mailimf_cache_int_write(MMAPString * mmapstr, size_t * index,
58 uint32_t value);
59int mailimf_cache_string_write(MMAPString * mmapstr, size_t * index,
60 char * str, size_t length);
61int mailimf_cache_int_read(MMAPString * mmapstr, size_t * index,
62 uint32_t * result);
63int mailimf_cache_string_read(MMAPString * mmapstr, size_t * index,
64 char ** result);
65
66int mailimf_cache_fields_write(MMAPString * mmapstr, size_t * index,
67 struct mailimf_fields * fields);
68int mailimf_cache_fields_read(MMAPString * mmapstr, size_t * index,
69 struct mailimf_fields ** result);
70
71#ifdef __cplusplus
72}
73#endif
74
75#endif
diff --git a/kmicromail/libetpan/generic/libetpan.h b/kmicromail/libetpan/generic/libetpan.h
new file mode 100644
index 0000000..3b4a107
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan.h
@@ -0,0 +1,104 @@
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#ifndef LIBETPAN_H
37
38#define LIBETPAN_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/libetpan_version.h>
45#include <libetpan/maildriver.h>
46#include <libetpan/mailmessage.h>
47#include <libetpan/mailstorage.h>
48#include <libetpan/mailthread.h>
49#include <libetpan/mailsmtp.h>
50#include <libetpan/charconv.h>
51
52/* mbox driver */
53#include <libetpan/mboxdriver.h>
54#include <libetpan/mboxdriver_message.h>
55#include <libetpan/mboxdriver_cached.h>
56#include <libetpan/mboxdriver_cached_message.h>
57#include <libetpan/mboxstorage.h>
58
59/* MH driver */
60#include <libetpan/mhdriver.h>
61#include <libetpan/mhdriver_message.h>
62#include <libetpan/mhdriver_cached.h>
63#include <libetpan/mhdriver_cached_message.h>
64#include <libetpan/mhstorage.h>
65
66/* IMAP4rev1 driver */
67#include <libetpan/imapdriver.h>
68#include <libetpan/imapdriver_message.h>
69#include <libetpan/imapdriver_cached.h>
70#include <libetpan/imapdriver_cached_message.h>
71#include <libetpan/imapstorage.h>
72
73/* POP3 driver */
74#include <libetpan/pop3driver.h>
75#include <libetpan/pop3driver_message.h>
76#include <libetpan/pop3driver_cached.h>
77#include <libetpan/pop3driver_cached_message.h>
78#include <libetpan/pop3storage.h>
79
80/* NNTP driver */
81#include <libetpan/nntpdriver.h>
82#include <libetpan/nntpdriver_message.h>
83#include <libetpan/nntpdriver_cached.h>
84#include <libetpan/nntpdriver_cached_message.h>
85#include <libetpan/nntpstorage.h>
86
87/* maildir driver */
88#include <libetpan/maildirdriver.h>
89#include <libetpan/maildirdriver_message.h>
90#include <libetpan/maildirdriver_cached.h>
91#include <libetpan/maildirdriver_cached_message.h>
92#include <libetpan/maildirstorage.h>
93
94/* message which content is given by a MIME structure */
95#include <libetpan/mime_message_driver.h>
96
97/* message which content given by a string */
98#include <libetpan/data_message_driver.h>
99
100#ifdef __cplusplus
101}
102#endif
103
104#endif
diff --git a/kmicromail/libetpan/generic/libetpan_version.c b/kmicromail/libetpan/generic/libetpan_version.c
new file mode 100644
index 0000000..d4ea6ec
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan_version.c
@@ -0,0 +1,18 @@
1#include "libetpan_version.h"
2
3#ifndef CONFIG_H
4#define CONFIG_H
5#include "config.h"
6#endif
7
8/* version of libEtPan! at runtime */
9
10int libetpan_get_version_major(void)
11{
12 return LIBETPAN_VERSION_MAJOR;
13}
14
15int libetpan_get_version_minor(void)
16{
17 return LIBETPAN_VERSION_MINOR;
18}
diff --git a/kmicromail/libetpan/generic/libetpan_version.h b/kmicromail/libetpan/generic/libetpan_version.h
new file mode 100644
index 0000000..5f9e5cf
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan_version.h
@@ -0,0 +1,51 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - 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#ifndef LIBETPAN_VERSION_H
37
38#define LIBETPAN_VERSION_H
39
40#ifndef LIBETPAN_VERSION_MAJOR
41#define LIBETPAN_VERSION_MAJOR 0
42#endif
43
44#ifndef LIBETPAN_VERSION_MINOR
45#define LIBETPAN_VERSION_MINOR 32
46#endif
47
48int libetpan_get_version_major(void);
49int libetpan_get_version_minor(void);
50
51#endif
diff --git a/kmicromail/libetpan/generic/libetpan_version.h.in b/kmicromail/libetpan/generic/libetpan_version.h.in
new file mode 100644
index 0000000..ce1deb2
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan_version.h.in
@@ -0,0 +1,51 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - 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#ifndef LIBETPAN_VERSION_H
37
38#define LIBETPAN_VERSION_H
39
40#ifndef LIBETPAN_VERSION_MAJOR
41#define LIBETPAN_VERSION_MAJOR @VERSION_MAJOR@
42#endif
43
44#ifndef LIBETPAN_VERSION_MINOR
45#define LIBETPAN_VERSION_MINOR @VERSION_MINOR@
46#endif
47
48int libetpan_get_version_major(void);
49int libetpan_get_version_minor(void);
50
51#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver.c b/kmicromail/libetpan/generic/maildirdriver.c
new file mode 100644
index 0000000..7830ceb
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver.c
@@ -0,0 +1,625 @@
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
37/*
38 flags directory MUST be kept so that we can have other flags
39 than standards
40*/
41
42#include "maildirdriver.h"
43
44#include <stdio.h>
45#include <sys/types.h>
46#include <dirent.h>
47#include <unistd.h>
48#include <sys/stat.h>
49#include <ctype.h>
50#include <fcntl.h>
51#include <sys/mman.h>
52#include <stdlib.h>
53#include <string.h>
54
55#include "maildir.h"
56#include "maildriver_tools.h"
57#include "maildirdriver_message.h"
58#include "maildirdriver_tools.h"
59#include "mailmessage.h"
60#include "generic_cache.h"
61
62static int initialize(mailsession * session);
63
64static void uninitialize(mailsession * session);
65
66static int connect_path(mailsession * session, char * path);
67
68static int logout(mailsession * session);
69
70static int expunge_folder(mailsession * session);
71
72static int status_folder(mailsession * session, char * mb,
73 uint32_t * result_messages, uint32_t * result_recent,
74 uint32_t * result_unseen);
75
76static int recent_number(mailsession * session, char * mb,
77 uint32_t * result);
78
79static int unseen_number(mailsession * session, char * mb,
80 uint32_t * result);
81
82static int messages_number(mailsession * session, char * mb,
83 uint32_t * result);
84
85static int append_message(mailsession * session,
86 char * message, size_t size);
87
88static int get_messages_list(mailsession * session,
89 struct mailmessage_list ** result);
90
91static int get_envelopes_list(mailsession * session,
92 struct mailmessage_list * env_list);
93
94static int check_folder(mailsession * session);
95
96static int get_message_by_uid(mailsession * session,
97 const char * uid, mailmessage ** result);
98
99static mailsession_driver local_maildir_session_driver = {
100 .sess_name = "maildir",
101
102 .sess_initialize = initialize,
103 .sess_uninitialize = uninitialize,
104
105 .sess_parameters = NULL,
106
107 .sess_connect_stream = NULL,
108 .sess_connect_path = connect_path,
109 .sess_starttls = NULL,
110 .sess_login = NULL,
111 .sess_logout = logout,
112 .sess_noop = NULL,
113
114 .sess_build_folder_name = NULL,
115 .sess_create_folder = NULL,
116 .sess_delete_folder = NULL,
117 .sess_rename_folder = NULL,
118 .sess_check_folder = check_folder,
119 .sess_examine_folder = NULL,
120 .sess_select_folder = NULL,
121 .sess_expunge_folder = expunge_folder,
122 .sess_status_folder = status_folder,
123 .sess_messages_number = messages_number,
124 .sess_recent_number = recent_number,
125 .sess_unseen_number = unseen_number,
126 .sess_list_folders = NULL,
127 .sess_lsub_folders = NULL,
128 .sess_subscribe_folder = NULL,
129 .sess_unsubscribe_folder = NULL,
130
131 .sess_append_message = append_message,
132 .sess_copy_message = NULL,
133 .sess_move_message = NULL,
134
135 .sess_get_messages_list = get_messages_list,
136 .sess_get_envelopes_list = get_envelopes_list,
137 .sess_remove_message = NULL,
138#if 0
139 .sess_search_messages = maildriver_generic_search_messages,
140#endif
141
142 .sess_get_message = NULL,
143 .sess_get_message_by_uid = get_message_by_uid,
144};
145
146mailsession_driver * maildir_session_driver = &local_maildir_session_driver;
147
148
149static int flags_store_process(struct maildir * md,
150 struct mail_flags_store * flags_store);
151
152
153static inline struct maildir_session_state_data * get_data(mailsession * session)
154{
155 return session->sess_data;
156}
157
158static struct maildir * get_maildir_session(mailsession * session)
159{
160 return get_data(session)->md_session;
161}
162
163static int initialize(mailsession * session)
164{
165 struct maildir_session_state_data * data;
166
167 data = malloc(sizeof(* data));
168 if (data == NULL)
169 goto err;
170
171 data->md_session = NULL;
172
173 data->md_flags_store = mail_flags_store_new();
174 if (data->md_flags_store == NULL)
175 goto free;
176
177 session->sess_data = data;
178
179 return MAIL_NO_ERROR;
180
181 free:
182 free(data);
183 err:
184 return MAIL_ERROR_MEMORY;
185}
186
187static void uninitialize(mailsession * session)
188{
189 struct maildir_session_state_data * data;
190
191 data = get_data(session);
192
193 if (data->md_session != NULL)
194 flags_store_process(data->md_session, data->md_flags_store);
195
196 mail_flags_store_free(data->md_flags_store);
197 if (data->md_session != NULL)
198 maildir_free(data->md_session);
199
200 free(data);
201
202 session->sess_data = NULL;
203}
204
205
206static int connect_path(mailsession * session, char * path)
207{
208 struct maildir * md;
209 int res;
210 int r;
211
212 if (get_maildir_session(session) != NULL) {
213 res = MAIL_ERROR_BAD_STATE;
214 goto err;
215 }
216
217 md = maildir_new(path);
218 if (md == NULL) {
219 res = MAIL_ERROR_MEMORY;
220 goto err;
221 }
222
223 r = maildir_update(md);
224 if (r != MAILDIR_NO_ERROR) {
225 res = maildirdriver_maildir_error_to_mail_error(r);
226 goto free;
227 }
228
229 get_data(session)->md_session = md;
230
231 return MAIL_NO_ERROR;
232
233 free:
234 maildir_free(md);
235 err:
236 return res;
237}
238
239static int logout(mailsession * session)
240{
241 struct maildir * md;
242
243 check_folder(session);
244
245 md = get_maildir_session(session);
246 if (md == NULL)
247 return MAIL_ERROR_BAD_STATE;
248
249 maildir_free(md);
250 get_data(session)->md_session = NULL;
251
252 return MAIL_NO_ERROR;
253}
254
255/* folders operations */
256
257static int status_folder(mailsession * session, char * mb,
258 uint32_t * result_messages, uint32_t * result_recent,
259 uint32_t * result_unseen)
260{
261 int r;
262 struct maildir * md;
263 unsigned int i;
264 uint32_t messages;
265 uint32_t recent;
266 uint32_t unseen;
267
268 check_folder(session);
269
270 md = get_maildir_session(session);
271 if (md == NULL)
272 return MAIL_ERROR_BAD_STATE;
273
274 r = maildir_update(md);
275 if (r != MAILDIR_NO_ERROR)
276 return maildirdriver_maildir_error_to_mail_error(r);
277
278 messages = 0;
279 recent = 0;
280 unseen = 0;
281 for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i ++) {
282 struct maildir_msg * msg;
283
284 msg = carray_get(md->mdir_msg_list, i);
285 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
286 recent ++;
287 if ((msg->msg_flags & MAILDIR_FLAG_SEEN) == 0)
288 unseen ++;
289 messages ++;
290 }
291
292 * result_messages = messages;
293 * result_recent = recent;
294 * result_unseen = unseen;
295
296 return MAIL_NO_ERROR;
297}
298
299static int messages_number(mailsession * session, char * mb,
300 uint32_t * result)
301{
302 struct maildir * md;
303 int r;
304
305 md = get_maildir_session(session);
306 if (md == NULL)
307 return MAIL_ERROR_BAD_STATE;
308
309 r = maildir_update(md);
310 if (r != MAILDIR_NO_ERROR)
311 return maildirdriver_maildir_error_to_mail_error(r);
312
313 * result = carray_count(md->mdir_msg_list);
314
315 return MAIL_NO_ERROR;
316}
317
318static int unseen_number(mailsession * session, char * mb,
319 uint32_t * result)
320{
321 uint32_t messages;
322 uint32_t recent;
323 uint32_t unseen;
324 int r;
325
326 r = status_folder(session, mb, &messages, &recent, &unseen);
327 if (r != MAIL_NO_ERROR)
328 return r;
329
330 * result = unseen;
331
332 return MAIL_NO_ERROR;
333}
334
335static int recent_number(mailsession * session, char * mb,
336 uint32_t * result)
337{
338 uint32_t messages;
339 uint32_t recent;
340 uint32_t unseen;
341 int r;
342
343 r = status_folder(session, mb, &messages, &recent, &unseen);
344 if (r != MAIL_NO_ERROR)
345 return r;
346
347 * result = recent;
348
349 return MAIL_NO_ERROR;
350}
351
352
353/* messages operations */
354
355static int append_message(mailsession * session,
356 char * message, size_t size)
357{
358 struct maildir * md;
359 int r;
360
361 md = get_maildir_session(session);
362 if (md == NULL)
363 return MAIL_ERROR_BAD_STATE;
364
365 r = maildir_message_add(md, message, size);
366 if (r != MAILDIR_NO_ERROR)
367 return maildirdriver_maildir_error_to_mail_error(r);
368
369 return MAIL_NO_ERROR;
370}
371
372static int get_messages_list(mailsession * session,
373 struct mailmessage_list ** result)
374{
375 struct maildir * md;
376 int r;
377 struct mailmessage_list * env_list;
378 int res;
379
380 md = get_maildir_session(session);
381 if (md == NULL)
382 return MAIL_ERROR_BAD_STATE;
383
384 r = maildir_update(md);
385 if (r != MAILDIR_NO_ERROR) {
386 res = maildirdriver_maildir_error_to_mail_error(r);
387 goto err;
388 }
389
390 r = maildir_get_messages_list(session, md,
391 maildir_message_driver, &env_list);
392 if (r != MAILDIR_NO_ERROR) {
393 res = r;
394 goto free_list;
395 }
396
397 * result = env_list;
398
399 return MAIL_NO_ERROR;
400
401 free_list:
402 mailmessage_list_free(env_list);
403 err:
404 return res;
405}
406
407static int get_envelopes_list(mailsession * session,
408 struct mailmessage_list * env_list)
409{
410 int r;
411 struct maildir * md;
412 unsigned int i;
413 int res;
414
415 check_folder(session);
416
417 md = get_maildir_session(session);
418 if (md == NULL) {
419 res = MAIL_ERROR_BAD_STATE;
420 goto err;
421 }
422
423 r = maildir_update(md);
424 if (r != MAILDIR_NO_ERROR) {
425 res = maildirdriver_maildir_error_to_mail_error(r);
426 goto err;
427 }
428
429 r = maildriver_generic_get_envelopes_list(session, env_list);
430 if (r != MAIL_NO_ERROR) {
431 res = r;
432 goto err;
433 }
434
435 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i++) {
436 struct maildir_msg * md_msg;
437 mailmessage * msg;
438 uint32_t driver_flags;
439 clist * ext;
440 chashdatum key;
441 chashdatum value;
442
443 msg = carray_get(env_list->msg_tab, i);
444
445 key.data = msg->msg_uid;
446 key.len = strlen(msg->msg_uid);
447 r = chash_get(md->mdir_msg_hash, &key, &value);
448 if (r < 0)
449 continue;
450
451 md_msg = value.data;
452
453 driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);
454
455 if (msg->msg_flags == NULL) {
456 ext = clist_new();
457 if (ext == NULL) {
458 res = MAIL_ERROR_MEMORY;
459 continue;
460 }
461
462 msg->msg_flags = mail_flags_new(driver_flags, ext);
463 if (msg->msg_flags == NULL) {
464 clist_free(ext);
465 res = MAIL_ERROR_MEMORY;
466 continue;
467 }
468
469 if ((md_msg->msg_flags & MAILDIR_FLAG_NEW) != 0) {
470 mail_flags_store_set(get_data(session)->md_flags_store, msg);
471 }
472 }
473 else {
474 msg->msg_flags->fl_flags &= MAIL_FLAG_FORWARDED;
475 msg->msg_flags->fl_flags |= driver_flags;
476 }
477 }
478
479 return MAIL_NO_ERROR;
480
481 err:
482 return res;
483}
484
485
486static int expunge_folder(mailsession * session)
487{
488 unsigned int i;
489 int r;
490 int res;
491 struct maildir * md;
492
493 check_folder(session);
494
495 md = get_maildir_session(session);
496 if (md == NULL)
497 return MAIL_ERROR_BAD_STATE;
498
499 r = maildir_update(md);
500 if (r != MAILDIR_NO_ERROR) {
501 res = maildirdriver_maildir_error_to_mail_error(r);
502 goto err;
503 }
504
505 for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i++) {
506 struct maildir_msg * md_msg;
507
508 md_msg = carray_get(md->mdir_msg_list, i);
509
510 if ((md_msg->msg_flags & MAILDIR_FLAG_TRASHED) != 0)
511 maildir_message_remove(md, md_msg->msg_uid);
512 }
513
514 return MAIL_NO_ERROR;
515
516 err:
517 return res;
518}
519
520
521static int flags_store_process(struct maildir * md,
522 struct mail_flags_store * flags_store)
523{
524 unsigned int i;
525
526 if (carray_count(flags_store->fls_tab) == 0)
527 return MAIL_NO_ERROR;
528
529 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
530 mailmessage * msg;
531 uint32_t md_flags;
532
533 msg = carray_get(flags_store->fls_tab, i);
534 md_flags = maildirdriver_flags_to_maildir_flags(msg->msg_flags->fl_flags);
535 md_flags &= ~MAILDIR_FLAG_NEW;
536
537 maildir_message_change_flags(md, msg->msg_uid, md_flags);
538 }
539
540 mail_flags_store_clear(flags_store);
541
542 return MAIL_NO_ERROR;
543}
544
545
546
547static int check_folder(mailsession * session)
548{
549 struct mail_flags_store * flags_store;
550 struct maildir_session_state_data * data;
551 struct maildir * md;
552
553 md = get_maildir_session(session);
554 if (md == NULL)
555 return MAIL_ERROR_BAD_STATE;
556
557 data = get_data(session);
558 flags_store = data->md_flags_store;
559
560 return flags_store_process(md, flags_store);
561}
562
563static int get_message_by_uid(mailsession * session,
564 const char * uid, mailmessage ** result)
565{
566 int r;
567 struct maildir * md;
568 int res;
569 mailmessage * msg;
570 char * msg_filename;
571 struct stat stat_info;
572
573 md = get_maildir_session(session);
574
575 /* update maildir data */
576
577 r = maildir_update(md);
578 if (r != MAILDIR_NO_ERROR) {
579 res = maildirdriver_maildir_error_to_mail_error(r);
580 goto err;
581 }
582
583 msg_filename = maildir_message_get(md, uid);
584 if (msg_filename == NULL) {
585 res = MAIL_ERROR_INVAL;
586 goto err;
587 }
588
589 r = stat(msg_filename, &stat_info);
590 free(msg_filename);
591 if (r < 0) {
592 res = MAIL_ERROR_INVAL;
593 goto err;
594 }
595
596 /* create message */
597
598 msg = mailmessage_new();
599 if (msg == NULL) {
600 res = MAIL_ERROR_MEMORY;
601 goto err;
602 }
603
604 r = mailmessage_init(msg, session, maildir_message_driver,
605 0, stat_info.st_size);
606 if (r != MAIL_NO_ERROR) {
607 mailmessage_free(msg);
608 res = r;
609 goto err;
610 }
611
612 msg->msg_uid = strdup(uid);
613 if (msg->msg_uid == NULL) {
614 mailmessage_free(msg);
615 res = r;
616 goto err;
617 }
618
619 * result = msg;
620
621 return MAIL_NO_ERROR;
622
623 err:
624 return res;
625}
diff --git a/kmicromail/libetpan/generic/maildirdriver.h b/kmicromail/libetpan/generic/maildirdriver.h
new file mode 100644
index 0000000..f59cf3e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver.h
@@ -0,0 +1,53 @@
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#ifndef MAILDIRDRIVER_H
37
38#define MAILDIRDRIVER_H
39
40#include <libetpan/maildriver.h>
41#include <libetpan/maildirdriver_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47extern mailsession_driver * maildir_session_driver;
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached.c b/kmicromail/libetpan/generic/maildirdriver_cached.c
new file mode 100644
index 0000000..503d1c9
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached.c
@@ -0,0 +1,1080 @@
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 "maildirdriver.h"
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <sys/stat.h>
43#include <ctype.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include "mail.h"
50#include "maildir.h"
51#include "maildriver_tools.h"
52#include "maildirdriver_tools.h"
53#include "maildirdriver_cached_message.h"
54#include "mailmessage.h"
55#include "generic_cache.h"
56#include "imfcache.h"
57#include "mail_cache_db.h"
58#include "libetpan-config.h"
59
60static int initialize(mailsession * session);
61
62static void uninitialize(mailsession * session);
63
64static int parameters(mailsession * session,
65 int id, void * value);
66
67static int connect_path(mailsession * session, char * path);
68
69static int logout(mailsession * session);
70
71static int expunge_folder(mailsession * session);
72
73static int status_folder(mailsession * session, char * mb,
74 uint32_t * result_messages, uint32_t * result_recent,
75 uint32_t * result_unseen);
76
77static int recent_number(mailsession * session, char * mb,
78 uint32_t * result);
79
80static int unseen_number(mailsession * session, char * mb,
81 uint32_t * result);
82
83static int messages_number(mailsession * session, char * mb,
84 uint32_t * result);
85
86static int append_message(mailsession * session,
87 char * message, size_t size);
88
89static int get_messages_list(mailsession * session,
90 struct mailmessage_list ** result);
91
92static int get_envelopes_list(mailsession * session,
93 struct mailmessage_list * env_list);
94
95static int check_folder(mailsession * session);
96
97static int get_message(mailsession * session,
98 uint32_t num, mailmessage ** result);
99
100static int get_message_by_uid(mailsession * session,
101 const char * uid, mailmessage ** result);
102
103static mailsession_driver local_maildir_cached_session_driver = {
104 .sess_name = "maildir-cached",
105
106 .sess_initialize = initialize,
107 .sess_uninitialize = uninitialize,
108
109 .sess_parameters = parameters,
110
111 .sess_connect_stream = NULL,
112 .sess_connect_path = connect_path,
113 .sess_starttls = NULL,
114 .sess_login = NULL,
115 .sess_logout = logout,
116 .sess_noop = NULL,
117
118 .sess_build_folder_name = NULL,
119 .sess_create_folder = NULL,
120 .sess_delete_folder = NULL,
121 .sess_rename_folder = NULL,
122 .sess_check_folder = check_folder,
123 .sess_examine_folder = NULL,
124 .sess_select_folder = NULL,
125 .sess_expunge_folder = expunge_folder,
126 .sess_status_folder = status_folder,
127 .sess_messages_number = messages_number,
128 .sess_recent_number = recent_number,
129 .sess_unseen_number = unseen_number,
130 .sess_list_folders = NULL,
131 .sess_lsub_folders = NULL,
132 .sess_subscribe_folder = NULL,
133 .sess_unsubscribe_folder = NULL,
134
135 .sess_append_message = append_message,
136 .sess_copy_message = NULL,
137 .sess_move_message = NULL,
138
139 .sess_get_messages_list = get_messages_list,
140 .sess_get_envelopes_list = get_envelopes_list,
141 .sess_remove_message = NULL,
142#if 0
143 .sess_search_messages = maildriver_generic_search_messages,
144#endif
145
146 .sess_get_message = get_message,
147 .sess_get_message_by_uid = get_message_by_uid,
148};
149
150mailsession_driver * maildir_cached_session_driver =
151&local_maildir_cached_session_driver;
152
153
154static inline struct maildir_cached_session_state_data *
155get_cached_data(mailsession * session)
156{
157 return session->sess_data;
158}
159
160static inline mailsession * get_ancestor(mailsession * session)
161{
162 return get_cached_data(session)->md_ancestor;
163}
164
165static inline struct maildir_session_state_data *
166get_ancestor_data(mailsession * session)
167{
168 return get_ancestor(session)->sess_data;
169}
170
171
172static struct maildir * get_maildir_session(mailsession * session)
173{
174 return get_ancestor_data(session)->md_session;
175}
176
177static int initialize(mailsession * session)
178{
179 struct maildir_cached_session_state_data * data;
180
181 data = malloc(sizeof(* data));
182 if (data == NULL)
183 goto err;
184
185 data->md_ancestor = mailsession_new(maildir_session_driver);
186 if (data->md_ancestor == NULL)
187 goto free;
188
189 data->md_flags_store = mail_flags_store_new();
190 if (data->md_flags_store == NULL)
191 goto free_session;
192
193 data->md_quoted_mb = NULL;
194 data->md_cache_directory[0] = '\0';
195 data->md_flags_directory[0] = '\0';
196
197 session->sess_data = data;
198
199 return MAIL_NO_ERROR;
200
201 free_session:
202 mailsession_free(data->md_ancestor);
203 free:
204 free(data);
205 err:
206 return MAIL_ERROR_MEMORY;
207}
208
209static void
210free_quoted_mb(struct maildir_cached_session_state_data * maildir_cached_data)
211{
212 if (maildir_cached_data->md_quoted_mb != NULL) {
213 free(maildir_cached_data->md_quoted_mb);
214 maildir_cached_data->md_quoted_mb = NULL;
215 }
216}
217
218static int
219write_cached_flags(struct mail_cache_db * cache_db,
220 MMAPString * mmapstr,
221 char * uid, struct mail_flags * flags);
222
223#define ENV_NAME "env.db"
224#define FLAGS_NAME "flags.db"
225
226static int flags_store_process(char * flags_directory, char * quoted_mb,
227 struct mail_flags_store * flags_store)
228{
229 char filename_flags[PATH_MAX];
230 struct mail_cache_db * cache_db_flags;
231 MMAPString * mmapstr;
232 unsigned int i;
233 int r;
234 int res;
235
236 if (carray_count(flags_store->fls_tab) == 0)
237 return MAIL_NO_ERROR;
238
239 if (quoted_mb == NULL)
240 return MAIL_NO_ERROR;
241
242 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
243 flags_directory, MAIL_DIR_SEPARATOR, quoted_mb,
244 MAIL_DIR_SEPARATOR, FLAGS_NAME);
245
246 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
247 if (r < 0) {
248 res = MAIL_ERROR_FILE;
249 goto err;
250 }
251
252 mmapstr = mmap_string_new("");
253 if (mmapstr == NULL) {
254 res = MAIL_ERROR_MEMORY;
255 goto close_db_flags;
256 }
257
258 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
259 mailmessage * msg;
260
261 msg = carray_get(flags_store->fls_tab, i);
262
263 r = write_cached_flags(cache_db_flags, mmapstr,
264 msg->msg_uid, msg->msg_flags);
265 if (r != MAIL_NO_ERROR) {
266 /* ignore errors */
267 }
268 }
269
270 mmap_string_free(mmapstr);
271 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
272
273 mail_flags_store_clear(flags_store);
274
275 return MAIL_NO_ERROR;
276
277 close_db_flags:
278 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
279 err:
280 return res;
281}
282
283static void uninitialize(mailsession * session)
284{
285 struct maildir_cached_session_state_data * data;
286
287 data = get_cached_data(session);
288
289 flags_store_process(data->md_flags_directory,
290 data->md_quoted_mb,
291 data->md_flags_store);
292
293 mail_flags_store_free(data->md_flags_store);
294 mailsession_free(data->md_ancestor);
295 free_quoted_mb(data);
296 free(data);
297
298 session->sess_data = data;
299}
300
301
302static int parameters(mailsession * session,
303 int id, void * value)
304{
305 struct maildir_cached_session_state_data * data;
306 int r;
307
308 data = get_cached_data(session);
309
310 switch (id) {
311 case MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY:
312 strncpy(data->md_cache_directory, value, PATH_MAX);
313 data->md_cache_directory[PATH_MAX - 1] = '\0';
314
315 r = generic_cache_create_dir(data->md_cache_directory);
316 if (r != MAIL_NO_ERROR)
317 return r;
318
319 return MAIL_NO_ERROR;
320
321 case MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY:
322 strncpy(data->md_flags_directory, value, PATH_MAX);
323 data->md_flags_directory[PATH_MAX - 1] = '\0';
324
325 r = generic_cache_create_dir(data->md_flags_directory);
326 if (r != MAIL_NO_ERROR)
327 return r;
328
329 return MAIL_NO_ERROR;
330
331 default:
332 return mailsession_parameters(data->md_ancestor, id, value);
333 }
334}
335
336
337static int get_cache_folder(mailsession * session, char ** result)
338{
339 struct maildir * md;
340 char * quoted_mb;
341 int res;
342 int r;
343 char key[PATH_MAX];
344 struct maildir_cached_session_state_data * data;
345
346 md = get_maildir_session(session);
347 data = get_cached_data(session);
348
349 quoted_mb = maildriver_quote_mailbox(md->mdir_path);
350 if (quoted_mb == NULL) {
351 res = MAIL_ERROR_MEMORY;
352 goto err;
353 }
354
355 snprintf(key, PATH_MAX, "%s/%s", data->md_cache_directory, quoted_mb);
356 r = generic_cache_create_dir(key);
357 if (r != MAIL_NO_ERROR) {
358 res = r;
359 goto free_quoted_mb;
360 }
361
362 snprintf(key, PATH_MAX, "%s/%s", data->md_flags_directory, quoted_mb);
363 r = generic_cache_create_dir(key);
364 if (r != MAIL_NO_ERROR) {
365 res = r;
366 goto free_quoted_mb;
367 }
368
369 * result = quoted_mb;
370
371 return MAIL_NO_ERROR;
372
373 free_quoted_mb:
374 free(quoted_mb);
375 err:
376 return res;
377}
378
379
380static int connect_path(mailsession * session, char * path)
381{
382 int r;
383 int res;
384 char * quoted_mb;
385
386 r = mailsession_connect_path(get_ancestor(session), path);
387 if (r != MAIL_NO_ERROR) {
388 res = r;
389 goto err;
390 }
391
392 r = get_cache_folder(session, &quoted_mb);
393 if (r != MAIL_NO_ERROR) {
394 res = r;
395 goto logout;
396 }
397
398 get_cached_data(session)->md_quoted_mb = quoted_mb;
399
400 return MAILDIR_NO_ERROR;
401
402 logout:
403 mailsession_logout(get_ancestor(session));
404 err:
405 return res;
406}
407
408static int logout(mailsession * session)
409{
410 struct maildir_cached_session_state_data * data;
411 int r;
412
413 data = get_cached_data(session);
414
415 flags_store_process(data->md_flags_directory,
416 data->md_quoted_mb, data->md_flags_store);
417
418 r = mailsession_logout(get_ancestor(session));
419 if (r != MAIL_NO_ERROR)
420 return r;
421
422 free_quoted_mb(get_cached_data(session));
423
424 return MAIL_NO_ERROR;
425}
426
427static int status_folder(mailsession * session, char * mb,
428 uint32_t * result_messages, uint32_t * result_recent,
429 uint32_t * result_unseen)
430{
431 return mailsession_status_folder(get_ancestor(session), mb,
432 result_messages, result_recent, result_unseen);
433}
434
435static int messages_number(mailsession * session, char * mb,
436 uint32_t * result)
437{
438 return mailsession_messages_number(get_ancestor(session), mb, result);
439}
440
441static int unseen_number(mailsession * session, char * mb,
442 uint32_t * result)
443{
444 return mailsession_unseen_number(get_ancestor(session), mb, result);
445}
446
447static int recent_number(mailsession * session, char * mb,
448 uint32_t * result)
449{
450 return mailsession_recent_number(get_ancestor(session), mb, result);
451}
452
453
454static int append_message(mailsession * session,
455 char * message, size_t size)
456{
457 return mailsession_append_message(get_ancestor(session), message, size);
458}
459
460
461#define UID_NAME "uid.db"
462
463static int uid_clean_up(struct mail_cache_db * uid_db,
464 struct mailmessage_list * env_list)
465{
466 chash * hash_exist;
467 int res;
468 int r;
469 unsigned int i;
470 chashdatum key;
471 chashdatum value;
472 char key_str[PATH_MAX];
473
474 /* flush cache */
475
476 hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
477 if (hash_exist == NULL) {
478 res = MAIL_ERROR_MEMORY;
479 goto err;
480 }
481
482 value.data = NULL;
483 value.len = 0;
484
485 key.data = "max-uid";
486 key.len = strlen("max-uid");
487 r = chash_set(hash_exist, &key, &value, NULL);
488
489 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
490 mailmessage * msg;
491
492 msg = carray_get(env_list->msg_tab, i);
493
494 value.data = NULL;
495 value.len = 0;
496
497 key.data = msg->msg_uid;
498 key.len = strlen(msg->msg_uid);
499 r = chash_set(hash_exist, &key, &value, NULL);
500 if (r < 0) {
501 res = MAIL_ERROR_MEMORY;
502 goto free;
503 }
504
505 snprintf(key_str, sizeof(key_str), "uid-%lu",
506 (unsigned long) msg->msg_index);
507 key.data = key_str;
508 key.len = strlen(key_str);
509 r = chash_set(hash_exist, &key, &value, NULL);
510 if (r < 0) {
511 res = MAIL_ERROR_MEMORY;
512 goto free;
513 }
514 }
515
516 mail_cache_db_clean_up(uid_db, hash_exist);
517
518 chash_free(hash_exist);
519
520 return MAIL_NO_ERROR;
521
522 free:
523 chash_free(hash_exist);
524 err:
525 return res;
526}
527
528static int get_messages_list(mailsession * session,
529 struct mailmessage_list ** result)
530{
531 struct maildir * md;
532 int r;
533 struct mailmessage_list * env_list;
534 int res;
535 uint32_t max_uid;
536 char filename[PATH_MAX];
537 struct mail_cache_db * uid_db;
538 void * value;
539 size_t value_len;
540 unsigned long i;
541 struct maildir_cached_session_state_data * data;
542 char key[PATH_MAX];
543
544 data = get_cached_data(session);
545
546 md = get_maildir_session(session);
547 if (md == NULL) {
548 res = MAIL_ERROR_BAD_STATE;
549 goto err;
550 }
551
552 check_folder(session);
553
554 r = maildir_update(md);
555 if (r != MAILDIR_NO_ERROR) {
556 res = maildirdriver_maildir_error_to_mail_error(r);
557 goto err;
558 }
559
560 r = maildir_get_messages_list(session, md,
561 maildir_cached_message_driver, &env_list);
562 if (r != MAILDIR_NO_ERROR) {
563 res = r;
564 goto err;
565 }
566
567 /* read/write DB */
568
569 snprintf(filename, sizeof(filename), "%s%c%s%c%s",
570 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
571 MAIL_DIR_SEPARATOR, UID_NAME);
572
573 r = mail_cache_db_open_lock(filename, &uid_db);
574 if (r < 0) {
575 res = MAIL_ERROR_MEMORY;
576 goto free_list;
577 }
578
579 max_uid = 0;
580 r = mail_cache_db_get(uid_db, "max-uid", sizeof("max-uid") - 1,
581 &value, &value_len);
582 if (r == 0) {
583 memcpy(&max_uid, value, sizeof(max_uid));
584 }
585
586 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
587 mailmessage * msg;
588 uint32_t index;
589
590 msg = carray_get(env_list->msg_tab, i);
591
592 r = mail_cache_db_get(uid_db, msg->msg_uid,
593 strlen(msg->msg_uid), &value, &value_len);
594 if (r < 0) {
595 max_uid ++;
596 msg->msg_index = max_uid;
597 mail_cache_db_put(uid_db, msg->msg_uid,
598 strlen(msg->msg_uid), &msg->msg_index, sizeof(msg->msg_index));
599
600 snprintf(key, sizeof(key), "uid-%lu", (unsigned long) msg->msg_index);
601 mail_cache_db_put(uid_db, key, strlen(key),
602 msg->msg_uid, strlen(msg->msg_uid));
603 }
604 else {
605 memcpy(&index, value, sizeof(index));
606 msg->msg_index = index;
607 }
608 }
609
610 mail_cache_db_put(uid_db, "max-uid", sizeof("max-uid") - 1,
611 &max_uid, sizeof(max_uid));
612
613 uid_clean_up(uid_db, env_list);
614
615 mail_cache_db_close_unlock(filename, uid_db);
616
617 * result = env_list;
618
619 return MAIL_NO_ERROR;
620
621 free_list:
622 mailmessage_list_free(env_list);
623 err:
624 return res;
625}
626
627static int
628get_cached_flags(struct mail_cache_db * cache_db,
629 MMAPString * mmapstr,
630 mailsession * session,
631 char * uid,
632 struct mail_flags ** result)
633{
634 int r;
635 char keyname[PATH_MAX];
636 struct mail_flags * flags;
637 int res;
638
639 snprintf(keyname, PATH_MAX, "%s-flags", uid);
640
641 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
642 if (r != MAIL_NO_ERROR) {
643 res = r;
644 goto err;
645 }
646
647 * result = flags;
648
649 return MAIL_NO_ERROR;
650
651 err:
652 return res;
653}
654
655static int
656get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
657 mailsession * session, char * uid,
658 struct mailimf_fields ** result)
659{
660 int r;
661 char keyname[PATH_MAX];
662 struct mailimf_fields * fields;
663 int res;
664
665 snprintf(keyname, PATH_MAX, "%s-envelope", uid);
666
667 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
668 if (r != MAIL_NO_ERROR) {
669 res = r;
670 goto err;
671 }
672
673 * result = fields;
674
675 return MAIL_NO_ERROR;
676
677 err:
678 return res;
679}
680
681static int
682write_cached_envelope(struct mail_cache_db * cache_db,
683 MMAPString * mmapstr,
684 mailsession * session, char * uid,
685 struct mailimf_fields * fields)
686{
687 int r;
688 char keyname[PATH_MAX];
689 int res;
690
691 snprintf(keyname, PATH_MAX, "%s-envelope", uid);
692
693 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
694 if (r != MAIL_NO_ERROR) {
695 res = r;
696 goto err;
697 }
698
699 return MAIL_NO_ERROR;
700
701 err:
702 return res;
703}
704
705static int
706write_cached_flags(struct mail_cache_db * cache_db,
707 MMAPString * mmapstr,
708 char * uid, struct mail_flags * flags)
709{
710 int r;
711 char keyname[PATH_MAX];
712 int res;
713
714 snprintf(keyname, PATH_MAX, "%s-flags", uid);
715
716 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
717 if (r != MAIL_NO_ERROR) {
718 res = r;
719 goto err;
720 }
721
722 return MAIL_NO_ERROR;
723
724 err:
725 return res;
726}
727
728
729static int get_envelopes_list(mailsession * session,
730 struct mailmessage_list * env_list)
731{
732 int r;
733 unsigned int i;
734 int res;
735 struct maildir_cached_session_state_data * data;
736 char filename_env[PATH_MAX];
737 char filename_flags[PATH_MAX];
738 struct mail_cache_db * cache_db_env;
739 struct mail_cache_db * cache_db_flags;
740 MMAPString * mmapstr;
741
742 data = get_cached_data(session);
743
744 flags_store_process(data->md_flags_directory,
745 data->md_quoted_mb, data->md_flags_store);
746
747 mmapstr = mmap_string_new("");
748 if (mmapstr == NULL) {
749 res = MAIL_ERROR_MEMORY;
750 goto err;
751 }
752
753 snprintf(filename_env, PATH_MAX, "%s%c%s%c%s",
754 data->md_cache_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
755 MAIL_DIR_SEPARATOR, ENV_NAME);
756
757 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
758 if (r < 0) {
759 res = MAIL_ERROR_MEMORY;
760 goto free_mmapstr;
761 }
762
763 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
764 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
765 MAIL_DIR_SEPARATOR, FLAGS_NAME);
766
767 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
768 if (r < 0) {
769 res = MAIL_ERROR_FILE;
770 goto close_db_env;
771 }
772
773 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i++) {
774 mailmessage * msg;
775 struct mailimf_fields * fields;
776 struct mail_flags * flags;
777
778 msg = carray_get(env_list->msg_tab, i);
779
780 if (msg->msg_fields == NULL) {
781 r = get_cached_envelope(cache_db_env, mmapstr, session,
782 msg->msg_uid, &fields);
783 if (r == MAIL_NO_ERROR) {
784 msg->msg_cached = TRUE;
785 msg->msg_fields = fields;
786 }
787 }
788
789 if (msg->msg_flags == NULL) {
790 r = get_cached_flags(cache_db_flags, mmapstr,
791 session, msg->msg_uid, &flags);
792 if (r == MAIL_NO_ERROR) {
793 msg->msg_flags = flags;
794 }
795 }
796 }
797
798 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
799 mail_cache_db_close_unlock(filename_env, cache_db_env);
800
801 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
802 if (r != MAIL_NO_ERROR) {
803 res = r;
804 goto free_mmapstr;
805 }
806
807 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
808 if (r < 0) {
809 res = MAIL_ERROR_MEMORY;
810 goto free_mmapstr;
811 }
812
813 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
814 if (r < 0) {
815 res = MAIL_ERROR_FILE;
816 goto close_db_env;
817 }
818
819 /* must write cache */
820
821 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
822 mailmessage * msg;
823
824 msg = carray_get(env_list->msg_tab, i);
825
826 if (msg->msg_fields != NULL) {
827 if (!msg->msg_cached) {
828 /* msg->index is the numerical UID of the message */
829 r = write_cached_envelope(cache_db_env, mmapstr,
830 session, msg->msg_uid, msg->msg_fields);
831 }
832 }
833
834 if (msg->msg_flags != NULL) {
835 r = write_cached_flags(cache_db_flags, mmapstr,
836 msg->msg_uid, msg->msg_flags);
837 }
838 }
839
840 /* flush cache */
841
842 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
843
844 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
845 mail_cache_db_close_unlock(filename_env, cache_db_env);
846
847 mmap_string_free(mmapstr);
848
849 return MAIL_NO_ERROR;
850
851 close_db_env:
852 mail_cache_db_close_unlock(filename_env, cache_db_env);
853 free_mmapstr:
854 mmap_string_free(mmapstr);
855 err:
856 return res;
857}
858
859static int expunge_folder(mailsession * session)
860{
861 return mailsession_expunge_folder(get_ancestor(session));
862}
863
864static int check_folder(mailsession * session)
865{
866 struct maildir_cached_session_state_data * data;
867
868 data = get_cached_data(session);
869
870 flags_store_process(data->md_flags_directory,
871 data->md_quoted_mb, data->md_flags_store);
872
873 return mailsession_check_folder(get_ancestor(session));
874}
875
876static int get_message(mailsession * session,
877 uint32_t num, mailmessage ** result)
878{
879 struct maildir * md;
880 int res;
881 mailmessage * msg;
882 char filename[PATH_MAX];
883 struct mail_cache_db * uid_db;
884 char * msg_filename;
885 struct stat stat_info;
886 char key_str[PATH_MAX];
887 void * value;
888 size_t value_len;
889 char uid[PATH_MAX];
890 struct maildir_cached_session_state_data * data;
891 int r;
892
893 data = get_cached_data(session);
894
895 md = get_maildir_session(session);
896
897 /* a get_messages_list() should have been done once before */
898
899 /* read DB */
900
901 snprintf(filename, sizeof(filename), "%s%c%s%c%s",
902 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
903 MAIL_DIR_SEPARATOR, UID_NAME);
904
905 r = mail_cache_db_open_lock(filename, &uid_db);
906 if (r < 0) {
907 res = MAIL_ERROR_MEMORY;
908 goto err;
909 }
910
911 snprintf(key_str, sizeof(key_str), "uid-%lu", (unsigned long) num);
912
913 r = mail_cache_db_get(uid_db, key_str, strlen(key_str), &value, &value_len);
914 if (r < 0) {
915 res = MAIL_ERROR_INVAL;
916 goto close_db;
917 }
918
919 if (value_len >= PATH_MAX) {
920 res = MAIL_ERROR_INVAL;
921 goto close_db;
922 }
923
924 memcpy(uid, value, value_len);
925 uid[value_len] = '\0';
926
927 mail_cache_db_close_unlock(filename, uid_db);
928
929 /* update maildir data */
930
931 r = maildir_update(md);
932 if (r != MAILDIR_NO_ERROR) {
933 res = maildirdriver_maildir_error_to_mail_error(r);
934 goto err;
935 }
936
937 msg_filename = maildir_message_get(md, uid);
938 if (msg_filename == NULL) {
939 res = MAIL_ERROR_INVAL;
940 goto err;
941 }
942
943 r = stat(msg_filename, &stat_info);
944 free(msg_filename);
945 if (r < 0) {
946 res = MAIL_ERROR_INVAL;
947 goto err;
948 }
949
950 /* create message */
951
952 msg = mailmessage_new();
953 if (msg == NULL) {
954 res = MAIL_ERROR_MEMORY;
955 goto err;
956 }
957
958 r = mailmessage_init(msg, session, maildir_cached_message_driver,
959 num, stat_info.st_size);
960 if (r != MAIL_NO_ERROR) {
961 mailmessage_free(msg);
962 res = r;
963 goto err;
964 }
965
966 msg->msg_uid = strdup(uid);
967 if (msg->msg_uid == NULL) {
968 mailmessage_free(msg);
969 res = r;
970 goto err;
971 }
972
973 * result = msg;
974
975 return MAIL_NO_ERROR;
976
977 close_db:
978 mail_cache_db_close_unlock(filename, uid_db);
979 err:
980 return res;
981}
982
983
984static int get_message_by_uid(mailsession * session,
985 const char * uid, mailmessage ** result)
986{
987 int r;
988 struct maildir * md;
989 int res;
990 mailmessage * msg;
991 char filename[PATH_MAX];
992 struct mail_cache_db * uid_db;
993 char * msg_filename;
994 struct stat stat_info;
995 void * value;
996 size_t value_len;
997 struct maildir_cached_session_state_data * data;
998 uint32_t index;
999
1000 data = get_cached_data(session);
1001
1002 md = get_maildir_session(session);
1003
1004 /* a get_messages_list() should have been done once before */
1005
1006 /* read DB */
1007
1008 snprintf(filename, sizeof(filename), "%s%c%s%c%s",
1009 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
1010 MAIL_DIR_SEPARATOR, UID_NAME);
1011
1012 r = mail_cache_db_open_lock(filename, &uid_db);
1013 if (r < 0) {
1014 res = MAIL_ERROR_MEMORY;
1015 goto err;
1016 }
1017
1018 r = mail_cache_db_get(uid_db, uid, strlen(uid), &value, &value_len);
1019 if (r < 0) {
1020 res = MAIL_ERROR_INVAL;
1021 goto close_db;
1022 }
1023
1024 memcpy(&index, value, sizeof(index));
1025
1026 mail_cache_db_close_unlock(filename, uid_db);
1027
1028 /* update maildir data */
1029
1030 r = maildir_update(md);
1031 if (r != MAILDIR_NO_ERROR) {
1032 res = maildirdriver_maildir_error_to_mail_error(r);
1033 goto err;
1034 }
1035
1036 msg_filename = maildir_message_get(md, uid);
1037 if (msg_filename == NULL) {
1038 res = MAIL_ERROR_INVAL;
1039 goto err;
1040 }
1041
1042 r = stat(msg_filename, &stat_info);
1043 free(msg_filename);
1044 if (r < 0) {
1045 res = MAIL_ERROR_INVAL;
1046 goto err;
1047 }
1048
1049 /* create message */
1050
1051 msg = mailmessage_new();
1052 if (msg == NULL) {
1053 res = MAIL_ERROR_MEMORY;
1054 goto err;
1055 }
1056
1057 r = mailmessage_init(msg, session, maildir_cached_message_driver,
1058 index, stat_info.st_size);
1059 if (r != MAIL_NO_ERROR) {
1060 mailmessage_free(msg);
1061 res = r;
1062 goto err;
1063 }
1064
1065 msg->msg_uid = strdup(uid);
1066 if (msg->msg_uid == NULL) {
1067 mailmessage_free(msg);
1068 res = r;
1069 goto err;
1070 }
1071
1072 * result = msg;
1073
1074 return MAIL_NO_ERROR;
1075
1076 close_db:
1077 mail_cache_db_close_unlock(filename, uid_db);
1078 err:
1079 return res;
1080}
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached.h b/kmicromail/libetpan/generic/maildirdriver_cached.h
new file mode 100644
index 0000000..81de3c3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached.h
@@ -0,0 +1,53 @@
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#ifndef MAILDIRDRIVER_CACHED_H
37
38#define MAILDIRDRIVER_CACHED_H
39
40#include <libetpan/maildriver.h>
41#include <libetpan/maildirdriver_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47extern mailsession_driver * maildir_cached_session_driver;
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached_message.c b/kmicromail/libetpan/generic/maildirdriver_cached_message.c
new file mode 100644
index 0000000..51866aa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached_message.c
@@ -0,0 +1,248 @@
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 "maildirdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "maildirdriver.h"
40#include "maildir.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 prefetch(mailmessage * msg_info);
52
53static void prefetch_free(struct generic_message_t * msg);
54
55static int initialize(mailmessage * msg_info);
56
57static void check(mailmessage * msg_info);
58
59static mailmessage_driver local_maildir_cached_message_driver = {
60 .msg_name = "maildir-cached",
61
62 .msg_initialize = initialize,
63 .msg_uninitialize = mailmessage_generic_uninitialize,
64
65 .msg_flush = mailmessage_generic_flush,
66 .msg_check = check,
67
68 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
69
70 .msg_fetch = mailmessage_generic_fetch,
71 .msg_fetch_header = mailmessage_generic_fetch_header,
72 .msg_fetch_body = mailmessage_generic_fetch_header,
73 .msg_fetch_size = NULL,
74 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
75 .msg_fetch_section = mailmessage_generic_fetch_section,
76 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
77 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
78 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
79 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
80
81 .msg_get_flags = NULL,
82};
83
84mailmessage_driver * maildir_cached_message_driver =
85&local_maildir_cached_message_driver;
86
87struct maildir_msg_data {
88 int fd;
89};
90
91#if 0
92static inline struct maildir_cached_session_state_data *
93get_cached_session_data(mailmessage * msg)
94{
95 return msg->session->data;
96}
97
98static inline mailsession * cached_session_get_ancestor(mailsession * session)
99{
100 return get_data(session)->session;
101}
102
103static inline struct maildir_session_state_data *
104cached_session_get_ancestor_data(mailsession * session)
105{
106 return get_ancestor(session)->data;
107}
108
109static struct maildir * get_maildir_session(mailmessage * msg)
110{
111 return cached_session_get_ancestor_data(msg->session)->session;
112}
113#endif
114static inline struct maildir_cached_session_state_data *
115get_cached_session_data(mailmessage * msg)
116{
117 return msg->msg_session->sess_data;
118}
119
120static inline struct maildir_cached_session_state_data *
121cached_session_get_data(mailsession * s)
122{
123 return s->sess_data;
124}
125
126static inline mailsession * cached_session_get_ancestor(mailsession * s)
127{
128 return cached_session_get_data(s)->md_ancestor;
129}
130
131static inline struct maildir_session_state_data *
132cached_session_get_ancestor_data(mailsession * s)
133{
134 return cached_session_get_ancestor(s)->sess_data;
135}
136
137static inline struct maildir_session_state_data *
138get_session_ancestor_data(mailmessage * msg)
139{
140 return cached_session_get_ancestor_data(msg->msg_session);
141}
142
143static inline struct maildir *
144cached_session_get_maildir_session(mailsession * session)
145{
146 return cached_session_get_ancestor_data(session)->md_session;
147}
148
149static inline struct maildir * get_maildir_session(mailmessage * msg)
150{
151 return cached_session_get_maildir_session(msg->msg_session);
152}
153
154static int prefetch(mailmessage * msg_info)
155{
156 struct generic_message_t * msg;
157 int res;
158 struct maildir_msg_data * data;
159 char * filename;
160 int fd;
161 char * mapping;
162 struct maildir * md;
163
164 md = get_maildir_session(msg_info);
165
166 filename = maildir_message_get(md, msg_info->msg_uid);
167 if (filename == NULL) {
168 res = MAIL_ERROR_MEMORY;
169 goto err;
170 }
171
172 fd = open(filename, O_RDONLY);
173 free(filename);
174 if (fd == -1) {
175 res = MAIL_ERROR_FILE;
176 goto err;
177 }
178
179 mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
180 if (mapping == MAP_FAILED) {
181 res = MAIL_ERROR_FILE;
182 goto close;
183 }
184
185 data = malloc(sizeof(* data));
186 if (data == NULL) {
187 res = MAIL_ERROR_MEMORY;
188 goto unmap;
189 }
190
191 data->fd = fd;
192
193 msg = msg_info->msg_data;
194
195 msg->msg_data = data;
196 msg->msg_message = mapping;
197 msg->msg_length = msg_info->msg_size;
198
199 return MAIL_NO_ERROR;
200
201 unmap:
202 munmap(mapping, msg_info->msg_size);
203 close:
204 close(fd);
205 err:
206 return res;
207}
208
209static void prefetch_free(struct generic_message_t * msg)
210{
211 if (msg->msg_message != NULL) {
212 struct maildir_msg_data * data;
213
214 munmap(msg->msg_message, msg->msg_length);
215 msg->msg_message = NULL;
216 data = msg->msg_data;
217 close(data->fd);
218 free(data);
219 }
220}
221
222static int initialize(mailmessage * msg_info)
223{
224 struct generic_message_t * msg;
225 int r;
226
227 r = mailmessage_generic_initialize(msg_info);
228 if (r != MAIL_NO_ERROR)
229 return r;
230
231 msg = msg_info->msg_data;
232 msg->msg_prefetch = prefetch;
233 msg->msg_prefetch_free = prefetch_free;
234
235 return MAIL_NO_ERROR;
236}
237
238static void check(mailmessage * msg_info)
239{
240 int r;
241
242 if (msg_info->msg_flags != NULL) {
243 r = mail_flags_store_set(get_session_ancestor_data(msg_info)->md_flags_store, msg_info);
244
245 r = mail_flags_store_set(get_cached_session_data(msg_info)->md_flags_store, msg_info);
246 /* ignore errors */
247 }
248}
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached_message.h b/kmicromail/libetpan/generic/maildirdriver_cached_message.h
new file mode 100644
index 0000000..399ecaa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached_message.h
@@ -0,0 +1,52 @@
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#ifndef MAILDIRDRIVER_CACHED_MESSAGE_H
37
38#define MAILDIRDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * maildir_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_message.c b/kmicromail/libetpan/generic/maildirdriver_message.c
new file mode 100644
index 0000000..7cf9dd1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_message.c
@@ -0,0 +1,199 @@
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 "maildirdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "maildirdriver.h"
40#include "maildir.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 prefetch(mailmessage * msg_info);
52
53static void prefetch_free(struct generic_message_t * msg);
54
55static int initialize(mailmessage * msg_info);
56
57static void check(mailmessage * msg_info);
58
59static mailmessage_driver local_maildir_message_driver = {
60 .msg_name = "maildir",
61
62 .msg_initialize = initialize,
63 .msg_uninitialize = mailmessage_generic_uninitialize,
64
65 .msg_flush = mailmessage_generic_flush,
66 .msg_check = check,
67
68 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
69
70 .msg_fetch = mailmessage_generic_fetch,
71 .msg_fetch_header = mailmessage_generic_fetch_header,
72 .msg_fetch_body = mailmessage_generic_fetch_header,
73 .msg_fetch_size = NULL,
74 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
75 .msg_fetch_section = mailmessage_generic_fetch_section,
76 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
77 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
78 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
79 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
80
81 .msg_get_flags = NULL,
82};
83
84mailmessage_driver * maildir_message_driver = &local_maildir_message_driver;
85
86struct maildir_msg_data {
87 int fd;
88};
89
90static inline struct maildir_session_state_data *
91get_session_data(mailmessage * msg)
92{
93 return msg->msg_session->sess_data;
94}
95
96static struct maildir * get_maildir_session(mailmessage * msg)
97{
98 return get_session_data(msg)->md_session;
99}
100
101static int prefetch(mailmessage * msg_info)
102{
103 struct generic_message_t * msg;
104 int res;
105 struct maildir_msg_data * data;
106 char * filename;
107 int fd;
108 char * mapping;
109 struct maildir * md;
110
111 md = get_maildir_session(msg_info);
112
113 if (msg_info->msg_uid == NULL) {
114 res = MAIL_ERROR_INVAL;
115 goto err;
116 }
117
118 filename = maildir_message_get(md, msg_info->msg_uid);
119 if (filename == NULL) {
120 res = MAIL_ERROR_MEMORY;
121 goto err;
122 }
123
124 fd = open(filename, O_RDONLY);
125 free(filename);
126 if (fd == -1) {
127 res = MAIL_ERROR_FILE;
128 goto err;
129 }
130
131 mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
132 if (mapping == MAP_FAILED) {
133 res = MAIL_ERROR_FILE;
134 goto close;
135 }
136
137 data = malloc(sizeof(* data));
138 if (data == NULL) {
139 res = MAIL_ERROR_MEMORY;
140 goto unmap;
141 }
142
143 data->fd = fd;
144
145 msg = msg_info->msg_data;
146
147 msg->msg_data = data;
148 msg->msg_message = mapping;
149 msg->msg_length = msg_info->msg_size;
150
151 return MAIL_NO_ERROR;
152
153 unmap:
154 munmap(mapping, msg_info->msg_size);
155 close:
156 close(fd);
157 err:
158 return res;
159}
160
161static void prefetch_free(struct generic_message_t * msg)
162{
163 if (msg->msg_message != NULL) {
164 struct maildir_msg_data * data;
165
166 munmap(msg->msg_message, msg->msg_length);
167 msg->msg_message = NULL;
168 data = msg->msg_data;
169 close(data->fd);
170 free(data);
171 }
172}
173
174static int initialize(mailmessage * msg_info)
175{
176 struct generic_message_t * msg;
177 int r;
178
179 r = mailmessage_generic_initialize(msg_info);
180 if (r != MAIL_NO_ERROR)
181 return r;
182
183 msg = msg_info->msg_data;
184 msg->msg_prefetch = prefetch;
185 msg->msg_prefetch_free = prefetch_free;
186
187 return MAIL_NO_ERROR;
188}
189
190static void check(mailmessage * msg_info)
191{
192 int r;
193
194 if (msg_info->msg_flags != NULL) {
195 r = mail_flags_store_set(get_session_data(msg_info)->md_flags_store,
196 msg_info);
197 /* ignore errors */
198 }
199}
diff --git a/kmicromail/libetpan/generic/maildirdriver_message.h b/kmicromail/libetpan/generic/maildirdriver_message.h
new file mode 100644
index 0000000..cb378bc
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_message.h
@@ -0,0 +1,52 @@
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#ifndef MAILDIRDRIVER_MESSAGE_H
37
38#define MAILDIRDRIVER_MESSAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * maildir_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_tools.c b/kmicromail/libetpan/generic/maildirdriver_tools.c
new file mode 100644
index 0000000..f3e21e4
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_tools.c
@@ -0,0 +1,195 @@
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 "mailmessage.h"
37#include "maildirdriver_tools.h"
38#include "maildir.h"
39#include "generic_cache.h"
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <stdlib.h>
43#include <string.h>
44
45int maildirdriver_maildir_error_to_mail_error(int error)
46{
47 switch (error) {
48 case MAILDIR_NO_ERROR:
49 return MAIL_NO_ERROR;
50
51 case MAILDIR_ERROR_CREATE:
52 return MAIL_ERROR_FILE;
53
54 case MAILDIR_ERROR_DIRECTORY:
55 return MAIL_ERROR_FILE;
56
57 case MAILDIR_ERROR_MEMORY:
58 return MAIL_ERROR_MEMORY;
59
60 case MAILDIR_ERROR_FILE:
61 return MAIL_ERROR_FILE;
62
63 case MAILDIR_ERROR_NOT_FOUND:
64 return MAIL_ERROR_MSG_NOT_FOUND;
65
66 default:
67 return MAIL_ERROR_INVAL;
68 }
69}
70
71
72
73uint32_t maildirdriver_maildir_flags_to_flags(uint32_t md_flags)
74{
75 uint32_t flags;
76
77 flags = 0;
78 if ((md_flags & MAILDIR_FLAG_NEW) != 0)
79 flags |= MAIL_FLAG_NEW;
80
81 if ((md_flags & MAILDIR_FLAG_SEEN) != 0)
82 flags |= MAIL_FLAG_SEEN;
83
84 if ((md_flags & MAILDIR_FLAG_REPLIED) != 0)
85 flags |= MAIL_FLAG_ANSWERED;
86
87 if ((md_flags & MAILDIR_FLAG_FLAGGED) != 0)
88 flags |= MAIL_FLAG_FLAGGED;
89
90 if ((md_flags & MAILDIR_FLAG_TRASHED) != 0)
91 flags |= MAIL_FLAG_DELETED;
92
93 return flags;
94}
95
96uint32_t maildirdriver_flags_to_maildir_flags(uint32_t flags)
97{
98 uint32_t md_flags;
99
100 md_flags = 0;
101 if ((flags & MAIL_FLAG_NEW) != 0)
102 md_flags |= MAILDIR_FLAG_NEW;
103
104 if ((flags & MAIL_FLAG_SEEN) != 0)
105 md_flags |= MAILDIR_FLAG_SEEN;
106
107 if ((flags & MAIL_FLAG_ANSWERED) != 0)
108 md_flags |= MAILDIR_FLAG_REPLIED;
109
110 if ((flags & MAIL_FLAG_FLAGGED) != 0)
111 md_flags |= MAILDIR_FLAG_FLAGGED;
112
113 if ((flags & MAIL_FLAG_DELETED) != 0)
114 md_flags |= MAILDIR_FLAG_TRASHED;
115
116 return md_flags;
117}
118
119
120int maildir_get_messages_list(mailsession * session, struct maildir * md,
121 mailmessage_driver * message_driver,
122 struct mailmessage_list ** result)
123{
124 unsigned int i;
125 struct mailmessage_list * env_list;
126 int r;
127 carray * tab;
128 int res;
129
130 tab = carray_new(128);
131 if (tab == NULL) {
132 res = MAIL_ERROR_MEMORY;
133 goto err;
134 }
135
136 for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i++) {
137 struct maildir_msg * md_msg;
138 mailmessage * msg;
139 char * filename;
140 struct stat stat_info;
141
142 md_msg = carray_get(md->mdir_msg_list, i);
143
144 filename = maildir_message_get(md, md_msg->msg_uid);
145 r = stat(filename, &stat_info);
146 free(filename);
147 if (r < 0)
148 continue;
149
150 msg = mailmessage_new();
151 if (msg == NULL) {
152 res = MAIL_ERROR_MEMORY;
153 goto free_list;
154 }
155
156 r = mailmessage_init(msg, session, message_driver,
157 i + 1, stat_info.st_size);
158 if (r != MAIL_NO_ERROR) {
159 mailmessage_free(msg);
160 res = r;
161 goto free_list;
162 }
163
164 msg->msg_uid = strdup(md_msg->msg_uid);
165 if (msg->msg_uid == NULL) {
166 mailmessage_free(msg);
167 res = MAIL_ERROR_MEMORY;
168 goto free_list;
169 }
170
171 r = carray_add(tab, msg, NULL);
172 if (r < 0) {
173 mailmessage_free(msg);
174 res = MAIL_ERROR_MEMORY;
175 goto free_list;
176 }
177 }
178
179 env_list = mailmessage_list_new(tab);
180 if (env_list == NULL) {
181 res = MAIL_ERROR_MEMORY;
182 goto free_list;
183 }
184
185 * result = env_list;
186
187 return MAIL_NO_ERROR;
188
189 free_list:
190 for(i = 0 ; i < carray_count(tab) ; i ++)
191 mailmessage_free(carray_get(tab, i));
192 carray_free(tab);
193 err:
194 return res;
195}
diff --git a/kmicromail/libetpan/generic/maildirdriver_tools.h b/kmicromail/libetpan/generic/maildirdriver_tools.h
new file mode 100644
index 0000000..3c8931f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_tools.h
@@ -0,0 +1,53 @@
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#ifndef MAILDIRDRIVER_TOOLS_H
37
38#define MAILDIRDRIVER_TOOLS_H
39
40#include "maildriver_types.h"
41#include "maildir.h"
42
43int maildirdriver_maildir_error_to_mail_error(int error);
44
45uint32_t maildirdriver_maildir_flags_to_flags(uint32_t md_flags);
46
47uint32_t maildirdriver_flags_to_maildir_flags(uint32_t flags);
48
49int maildir_get_messages_list(mailsession * session, struct maildir * md,
50 mailmessage_driver * message_driver,
51 struct mailmessage_list ** result);
52
53#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_types.h b/kmicromail/libetpan/generic/maildirdriver_types.h
new file mode 100644
index 0000000..cb3661f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_types.h
@@ -0,0 +1,96 @@
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#ifndef MAILDIRDRIVER_TYPES_H
37
38#define MAILDIRDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/maildir.h>
44#include <libetpan/generic_cache_types.h>
45#include <libetpan/mailstorage_types.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
51struct maildir_session_state_data {
52 struct maildir * md_session;
53 struct mail_flags_store * md_flags_store;
54};
55
56enum {
57 MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
58 MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY,
59};
60
61struct maildir_cached_session_state_data {
62 mailsession * md_ancestor;
63 char * md_quoted_mb;
64 struct mail_flags_store * md_flags_store;
65 char md_cache_directory[PATH_MAX];
66 char md_flags_directory[PATH_MAX];
67};
68
69/* maildir storage */
70
71/*
72 maildir_mailstorage is the state data specific to the maildir storage.
73
74 - pathname is the path of the maildir storage.
75
76 - cached if this value is != 0, a persistant cache will be
77 stored on local system.
78
79 - cache_directory is the location of the cache.
80
81 - flags_directory is the location of the flags.
82*/
83
84struct maildir_mailstorage {
85 char * md_pathname;
86
87 int md_cached;
88 char * md_cache_directory;
89 char * md_flags_directory;
90};
91
92#ifdef __cplusplus
93}
94#endif
95
96#endif
diff --git a/kmicromail/libetpan/generic/maildirstorage.c b/kmicromail/libetpan/generic/maildirstorage.c
new file mode 100644
index 0000000..7e6b461
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirstorage.c
@@ -0,0 +1,192 @@
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 "mailstorage.h"
37
38#include "mail.h"
39#include "mailmessage.h"
40#include "maildirdriver.h"
41#include "maildirdriver_cached.h"
42#include "maildriver.h"
43
44#include <stdlib.h>
45#include <string.h>
46
47/* maildir storage */
48
49static int maildir_mailstorage_connect(struct mailstorage * storage);
50static int
51maildir_mailstorage_get_folder_session(struct mailstorage * storage,
52 char * pathname, mailsession ** result);
53static void maildir_mailstorage_uninitialize(struct mailstorage * storage);
54
55static mailstorage_driver maildir_mailstorage_driver = {
56 .sto_name = "maildir",
57 .sto_connect = maildir_mailstorage_connect,
58 .sto_get_folder_session = maildir_mailstorage_get_folder_session,
59 .sto_uninitialize = maildir_mailstorage_uninitialize,
60};
61
62int maildir_mailstorage_init(struct mailstorage * storage,
63 char * md_pathname, int md_cached,
64 char * md_cache_directory, char * md_flags_directory)
65{
66 struct maildir_mailstorage * maildir_storage;
67
68 maildir_storage = malloc(sizeof(struct maildir_mailstorage));
69 if (maildir_storage == NULL)
70 goto err;
71
72 maildir_storage->md_pathname = strdup(md_pathname);
73 if (maildir_storage->md_pathname == NULL)
74 goto free;
75
76 maildir_storage->md_cached = md_cached;
77
78 if (md_cached && (md_cache_directory != NULL) &&
79 (md_flags_directory != NULL)) {
80 maildir_storage->md_cache_directory = strdup(md_cache_directory);
81 if (maildir_storage->md_cache_directory == NULL)
82 goto free_pathname;
83
84 maildir_storage->md_flags_directory = strdup(md_flags_directory);
85 if (maildir_storage->md_flags_directory == NULL)
86 goto free_cache_directory;
87 }
88 else {
89 maildir_storage->md_cached = FALSE;
90 maildir_storage->md_cache_directory = NULL;
91 maildir_storage->md_flags_directory = NULL;
92 }
93
94 storage->sto_data = maildir_storage;
95 storage->sto_driver = &maildir_mailstorage_driver;
96
97 return MAIL_NO_ERROR;
98
99 free_cache_directory:
100 free(maildir_storage->md_cache_directory);
101 free_pathname:
102 free(maildir_storage->md_pathname);
103 free:
104 free(maildir_storage);
105 err:
106 return MAIL_ERROR_MEMORY;
107}
108
109static void maildir_mailstorage_uninitialize(struct mailstorage * storage)
110{
111 struct maildir_mailstorage * maildir_storage;
112
113 maildir_storage = storage->sto_data;
114 if (maildir_storage->md_flags_directory != NULL)
115 free(maildir_storage->md_flags_directory);
116 if (maildir_storage->md_cache_directory != NULL)
117 free(maildir_storage->md_cache_directory);
118 free(maildir_storage->md_pathname);
119 free(maildir_storage);
120
121 storage->sto_data = NULL;
122}
123
124static int maildir_mailstorage_connect(struct mailstorage * storage)
125{
126 struct maildir_mailstorage * maildir_storage;
127 mailsession_driver * driver;
128 int r;
129 int res;
130 mailsession * session;
131
132 maildir_storage = storage->sto_data;
133
134 if (maildir_storage->md_cached)
135 driver = maildir_cached_session_driver;
136 else
137 driver = maildir_session_driver;
138
139 session = mailsession_new(driver);
140 if (session == NULL) {
141 res = MAIL_ERROR_MEMORY;
142 goto err;
143 }
144
145 if (maildir_storage->md_cached) {
146 r = mailsession_parameters(session,
147 MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY,
148 maildir_storage->md_cache_directory);
149 if (r != MAIL_NO_ERROR) {
150 res = r;
151 goto free;
152 }
153
154 r = mailsession_parameters(session,
155 MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY,
156 maildir_storage->md_flags_directory);
157 if (r != MAIL_NO_ERROR) {
158 res = r;
159 goto free;
160 }
161 }
162
163 r = mailsession_connect_path(session, maildir_storage->md_pathname);
164 switch (r) {
165 case MAIL_NO_ERROR_NON_AUTHENTICATED:
166 case MAIL_NO_ERROR_AUTHENTICATED:
167 case MAIL_NO_ERROR:
168 break;
169 default:
170 res = r;
171 goto free;
172 }
173
174 storage->sto_session = session;
175
176 return MAIL_NO_ERROR;
177
178 free:
179 mailsession_free(session);
180 err:
181 return res;
182}
183
184static int
185maildir_mailstorage_get_folder_session(struct mailstorage * storage,
186 char * pathname, mailsession ** result)
187{
188 * result = storage->sto_session;
189
190 return MAIL_NO_ERROR;
191}
192
diff --git a/kmicromail/libetpan/generic/maildirstorage.h b/kmicromail/libetpan/generic/maildirstorage.h
new file mode 100644
index 0000000..d17ea2c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirstorage.h
@@ -0,0 +1,69 @@
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#ifndef MAILDIRSTORAGE_H
37
38#define MAILDIRSTORAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 maildir_mailstorage_init is the constructor for a mbox storage.
48
49 @param storage this is the storage to initialize.
50
51 @param pathname is the directory that contains the mailbox.
52
53 @param cached if this value is != 0, a persistant cache will be
54 stored on local system.
55
56 @param cache_directory is the location of the cache
57
58 @param flags_directory is the location of the flags
59*/
60
61int maildir_mailstorage_init(struct mailstorage * storage,
62 char * md_pathname, int md_cached,
63 char * md_cache_directory, char * md_flags_directory);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/generic/maildriver.c b/kmicromail/libetpan/generic/maildriver.c
new file mode 100644
index 0000000..01e3e34
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver.c
@@ -0,0 +1,373 @@
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 "maildriver.h"
37#include <ctype.h>
38#include <string.h>
39#include <stdlib.h>
40
41/* *********************************************************************** */
42/* mail session */
43
44mailsession * mailsession_new(mailsession_driver * sess_driver)
45{
46 mailsession * session;
47 int r;
48
49 session = malloc(sizeof(* session));
50
51 session->sess_data = NULL;
52
53 if (sess_driver->sess_initialize != NULL) {
54 r = sess_driver->sess_initialize(session);
55 if (r != MAIL_NO_ERROR)
56 goto free;
57 }
58
59 session->sess_driver = sess_driver;
60
61 return session;
62
63 free:
64 free(session);
65 return NULL;
66}
67
68void mailsession_free(mailsession * session)
69{
70 if (session->sess_driver->sess_uninitialize != NULL)
71 session->sess_driver->sess_uninitialize(session);
72 free(session);
73}
74
75int mailsession_parameters(mailsession * session,
76 int id, void * value)
77{
78 if (session->sess_driver->sess_parameters == NULL)
79 return MAIL_ERROR_NOT_IMPLEMENTED;
80
81 return session->sess_driver->sess_parameters(session, id, value);
82}
83
84int mailsession_connect_stream(mailsession * session, mailstream * s)
85{
86 if (session->sess_driver->sess_connect_stream == NULL)
87 return MAIL_ERROR_NOT_IMPLEMENTED;
88
89 return session->sess_driver->sess_connect_stream(session, s);
90}
91
92int mailsession_connect_path(mailsession * session, char * path)
93{
94 if (session->sess_driver->sess_connect_path == NULL)
95 return MAIL_ERROR_NOT_IMPLEMENTED;
96
97 return session->sess_driver->sess_connect_path(session, path);
98}
99
100int mailsession_starttls(mailsession * session)
101{
102 if (session->sess_driver->sess_starttls == NULL)
103 return MAIL_ERROR_NOT_IMPLEMENTED;
104
105 return session->sess_driver->sess_starttls(session);
106}
107
108int mailsession_login(mailsession * session,
109 char * userid, char * password)
110{
111 if (session->sess_driver->sess_login == NULL)
112 return MAIL_ERROR_NOT_IMPLEMENTED;
113
114 return session->sess_driver->sess_login(session, userid, password);
115}
116
117int mailsession_logout(mailsession * session)
118{
119 if (session->sess_driver->sess_logout == NULL)
120 return MAIL_ERROR_NOT_IMPLEMENTED;
121
122 return session->sess_driver->sess_logout(session);
123}
124
125int mailsession_noop(mailsession * session)
126{
127 if (session->sess_driver->sess_noop == NULL)
128 return MAIL_ERROR_NOT_IMPLEMENTED;
129
130 return session->sess_driver->sess_noop(session);
131}
132
133/* folders operations */
134
135int mailsession_build_folder_name(mailsession * session, char * mb,
136 char * name, char ** result)
137{
138 if (session->sess_driver->sess_build_folder_name == NULL)
139 return MAIL_ERROR_NOT_IMPLEMENTED;
140
141 return session->sess_driver->sess_build_folder_name(session,
142 mb, name, result);
143}
144
145int mailsession_create_folder(mailsession * session, char * mb)
146{
147 if (session->sess_driver->sess_create_folder == NULL)
148 return MAIL_ERROR_NOT_IMPLEMENTED;
149
150 return session->sess_driver->sess_create_folder(session, mb);
151}
152
153int mailsession_delete_folder(mailsession * session, char * mb)
154{
155 if (session->sess_driver->sess_delete_folder == NULL)
156 return MAIL_ERROR_NOT_IMPLEMENTED;
157
158 return session->sess_driver->sess_delete_folder(session, mb);
159}
160
161int mailsession_rename_folder(mailsession * session,
162 char * mb, char * new_name)
163{
164 if (session->sess_driver->sess_rename_folder == NULL)
165 return MAIL_ERROR_NOT_IMPLEMENTED;
166
167 return session->sess_driver->sess_rename_folder(session, mb, new_name);
168}
169
170int mailsession_check_folder(mailsession * session)
171{
172 if (session->sess_driver->sess_check_folder == NULL)
173 return MAIL_ERROR_NOT_IMPLEMENTED;
174
175 return session->sess_driver->sess_check_folder(session);
176}
177
178int mailsession_examine_folder(mailsession * session, char * mb)
179{
180 if (session->sess_driver->sess_examine_folder == NULL)
181 return MAIL_ERROR_NOT_IMPLEMENTED;
182
183 return session->sess_driver->sess_examine_folder(session, mb);
184}
185
186int mailsession_select_folder(mailsession * session, char * mb)
187{
188 if (session->sess_driver->sess_select_folder == NULL)
189 return MAIL_ERROR_NOT_IMPLEMENTED;
190
191 return session->sess_driver->sess_select_folder(session, mb);
192}
193
194int mailsession_expunge_folder(mailsession * session)
195{
196 if (session->sess_driver->sess_expunge_folder == NULL)
197 return MAIL_ERROR_NOT_IMPLEMENTED;
198
199 return session->sess_driver->sess_expunge_folder(session);
200}
201
202int mailsession_status_folder(mailsession * session, char * mb,
203 uint32_t * result_messages, uint32_t * result_recent,
204 uint32_t * result_unseen)
205{
206 if (session->sess_driver->sess_status_folder == NULL)
207 return MAIL_ERROR_NOT_IMPLEMENTED;
208
209 return session->sess_driver->sess_status_folder(session, mb,
210 result_messages, result_recent, result_unseen);
211}
212
213int mailsession_messages_number(mailsession * session, char * mb,
214 uint32_t * result)
215{
216 if (session->sess_driver->sess_messages_number == NULL)
217 return MAIL_ERROR_NOT_IMPLEMENTED;
218
219 return session->sess_driver->sess_messages_number(session, mb, result);
220}
221
222int mailsession_recent_number(mailsession * session, char * mb,
223 uint32_t * result)
224{
225 if (session->sess_driver->sess_recent_number == NULL)
226 return MAIL_ERROR_NOT_IMPLEMENTED;
227
228 return session->sess_driver->sess_recent_number(session, mb, result);
229}
230
231int mailsession_unseen_number(mailsession * session, char * mb,
232 uint32_t * result)
233{
234 if (session->sess_driver->sess_unseen_number == NULL)
235 return MAIL_ERROR_NOT_IMPLEMENTED;
236
237 return session->sess_driver->sess_recent_number(session, mb, result);
238}
239
240int mailsession_list_folders(mailsession * session, char * mb,
241 struct mail_list ** result)
242{
243 if (session->sess_driver->sess_list_folders == NULL)
244 return MAIL_ERROR_NOT_IMPLEMENTED;
245
246 return session->sess_driver->sess_list_folders(session, mb, result);
247}
248
249int mailsession_lsub_folders(mailsession * session, char * mb,
250 struct mail_list ** result)
251{
252 if (session->sess_driver->sess_lsub_folders == NULL)
253 return MAIL_ERROR_NOT_IMPLEMENTED;
254
255 return session->sess_driver->sess_lsub_folders(session, mb, result);
256}
257
258int mailsession_subscribe_folder(mailsession * session, char * mb)
259{
260 if (session->sess_driver->sess_subscribe_folder == NULL)
261 return MAIL_ERROR_NOT_IMPLEMENTED;
262
263 return session->sess_driver->sess_subscribe_folder(session, mb);
264}
265
266int mailsession_unsubscribe_folder(mailsession * session, char * mb)
267{
268 if (session->sess_driver->sess_unsubscribe_folder == NULL)
269 return MAIL_ERROR_NOT_IMPLEMENTED;
270
271 return session->sess_driver->sess_unsubscribe_folder(session, mb);
272}
273
274/* message */
275
276int mailsession_append_message(mailsession * session,
277 char * message, size_t size)
278{
279 if (session->sess_driver->sess_append_message == NULL)
280 return MAIL_ERROR_NOT_IMPLEMENTED;
281
282 return session->sess_driver->sess_append_message(session, message, size);
283}
284
285int mailsession_copy_message(mailsession * session,
286 uint32_t num, char * mb)
287{
288 if (session->sess_driver->sess_copy_message == NULL)
289 return MAIL_ERROR_NOT_IMPLEMENTED;
290
291 return session->sess_driver->sess_copy_message(session, num, mb);
292}
293
294int mailsession_move_message(mailsession * session,
295 uint32_t num, char * mb)
296{
297 if (session->sess_driver->sess_move_message == NULL) {
298 int r;
299
300 if ((session->sess_driver->sess_copy_message == NULL) &&
301 (session->sess_driver->sess_remove_message == NULL))
302 return MAIL_ERROR_NOT_IMPLEMENTED;
303
304 r = mailsession_copy_message(session, num, mb);
305 if (r != MAIL_NO_ERROR)
306 return r;
307
308 r = mailsession_remove_message(session, num);
309 if (r != MAIL_NO_ERROR)
310 return r;
311
312 return MAIL_NO_ERROR;
313 }
314
315 return session->sess_driver->sess_move_message(session, num, mb);
316}
317
318int mailsession_get_envelopes_list(mailsession * session,
319 struct mailmessage_list * env_list)
320{
321 if (session->sess_driver->sess_get_envelopes_list == NULL)
322 return MAIL_ERROR_NOT_IMPLEMENTED;
323
324 return session->sess_driver->sess_get_envelopes_list(session, env_list);
325}
326
327int mailsession_get_messages_list(mailsession * session,
328 struct mailmessage_list ** result)
329{
330 if (session->sess_driver->sess_get_messages_list == NULL)
331 return MAIL_ERROR_NOT_IMPLEMENTED;
332
333 return session->sess_driver->sess_get_messages_list(session, result);
334}
335
336int mailsession_remove_message(mailsession * session, uint32_t num)
337{
338 if (session->sess_driver->sess_remove_message == NULL)
339 return MAIL_ERROR_NOT_IMPLEMENTED;
340
341 return session->sess_driver->sess_remove_message(session, num);
342}
343
344#if 0
345int mailsession_search_messages(mailsession * session, char * charset,
346 struct mail_search_key * key,
347 struct mail_search_result ** result)
348{
349 if (session->sess_driver->sess_search_messages == NULL)
350 return MAIL_ERROR_NOT_IMPLEMENTED;
351
352 return session->sess_driver->sess_search_messages(session,
353 charset, key, result);
354}
355#endif
356
357int mailsession_get_message(mailsession * session,
358 uint32_t num, mailmessage ** result)
359{
360 if (session->sess_driver->sess_get_message == NULL)
361 return MAIL_ERROR_NOT_IMPLEMENTED;
362
363 return session->sess_driver->sess_get_message(session, num, result);
364}
365
366int mailsession_get_message_by_uid(mailsession * session,
367 const char * uid, mailmessage ** result)
368{
369 if (session->sess_driver->sess_get_message_by_uid == NULL)
370 return MAIL_ERROR_NOT_IMPLEMENTED;
371
372 return session->sess_driver->sess_get_message_by_uid(session, uid, result);
373}
diff --git a/kmicromail/libetpan/generic/maildriver.h b/kmicromail/libetpan/generic/maildriver.h
new file mode 100644
index 0000000..7da9aea
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver.h
@@ -0,0 +1,543 @@
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#ifndef MAILDRIVER_H
37
38#define MAILDRIVER_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/maildriver_types_helper.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* mailsession */
48
49/*
50 mailsession_new creates a new session, using the given driver
51
52 @return the created session is returned
53*/
54
55mailsession * mailsession_new(mailsession_driver * sess_driver);
56
57/*
58 mailsession_free release the memory used by the session
59*/
60
61void mailsession_free(mailsession * session);
62
63/*
64 mailsession_parameters is used to make calls specific to the driver
65
66 @param id is the command to send to the driver,
67 usually, commands can be found in the header of the driver
68
69 @param value is the parameter of the specific call
70
71 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
72 on error
73*/
74
75int mailsession_parameters(mailsession * session,
76 int id, void * value);
77
78/*
79 There are drivers of two kinds : stream drivers (driver that connects
80 to servers through TCP or other means of connection) and file drivers
81 (driver that are based on filesystem)
82
83 The following function can only be used by stream drivers.
84 mailsession_connect_stream connects a stream to the session
85
86 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
87 on error
88*/
89
90int mailsession_connect_stream(mailsession * session, mailstream * s);
91
92/*
93 The following function can only be used by file drivers.
94 mailsession_connect_path selects the main path of the session
95
96 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
97 on error
98*/
99
100int mailsession_connect_path(mailsession * session, char * path);
101
102/*
103 NOTE: works only on stream drivers
104
105 mailsession_starttls switches the current connection to TLS (secure layer)
106
107 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
108 on error
109*/
110
111int mailsession_starttls(mailsession * session);
112
113/*
114 mailsession_login notifies the login and the password to authenticate
115 to the session
116
117 @param userid the given string is only needed at this function call
118 (it will be duplicated if necessary)
119 @param password the given string is only needed at this function call
120 (it will be duplicated if necessary)
121
122 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
123 on error
124*/
125
126int mailsession_login(mailsession * session,
127 char * userid, char * password);
128
129/*
130 NOTE: this function doesn't often work on filsystem drivers
131
132 mailsession_logout deconnects the session and closes the stream.
133
134 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
135 on error
136*/
137
138int mailsession_logout(mailsession * session);
139
140/*
141 mailsession_noop does no operation on the session, but it can be
142 used to poll for the status of the connection.
143
144 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
145 on error
146*/
147
148int mailsession_noop(mailsession * session);
149
150/*
151 NOTE: driver's specific should be used
152
153 mailsession_build_folder_name will return an allocated string with
154 that contains the complete path of the folder to create
155
156 @param session the sesion
157 @param mb is the parent mailbox
158 @param name is the name of the folder to create
159 @param result the complete path of the folder to create will be
160 stored in (* result), this name have to be freed with free()
161
162 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
163 on error
164*/
165
166int mailsession_build_folder_name(mailsession * session, char * mb,
167 char * name, char ** result);
168
169/*
170 NOTE: driver's specific should be used
171
172 mailsession_create_folder creates the folder that corresponds to the
173 given name
174
175 @param session the session
176 @param mb is the name of the mailbox
177
178 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
179 on error
180*/
181
182int mailsession_create_folder(mailsession * session, char * mb);
183
184
185/*
186 NOTE: driver's specific should be used
187
188 mailsession_delete_folder deletes the folder that corresponds to the
189 given name
190
191 @param session the session
192 @param mb is the name of the mailbox
193
194 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
195 on error
196*/
197
198int mailsession_delete_folder(mailsession * session, char * mb);
199
200
201/*
202 mailsession_rename_folder changes the name of the folder
203
204 @param session the session
205 @param mb is the name of the mailbox whose name has to be changed
206 @param new_name is the destination name (the parent
207 of the new folder folder can be other)
208
209 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
210 on error
211*/
212
213int mailsession_rename_folder(mailsession * session,
214 char * mb, char * new_name);
215
216/*
217 mailsession_check_folder makes a checkpoint of the session
218
219 @param session the session
220
221 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
222 on error
223*/
224
225int mailsession_check_folder(mailsession * session);
226
227
228/*
229 NOTE: this function is not implemented in most drivers
230
231 mailsession_examine_folder selects a mailbox as readonly
232
233 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
234 on error
235*/
236
237int mailsession_examine_folder(mailsession * session, char * mb);
238
239
240/*
241 mailsession_select_folder selects a mailbox
242
243 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
244 on error
245*/
246
247int mailsession_select_folder(mailsession * session, char * mb);
248
249
250/*
251 mailsession_expunge_folder deletes all messages marked \Deleted
252
253 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
254 on error
255*/
256
257int mailsession_expunge_folder(mailsession * session);
258
259
260/*
261 mailsession_status_folder queries the status of the folder
262 (number of messages, number of recent messages, number of unseen messages)
263
264 @param session the session
265 @param mb mailbox to query
266 @param result_messages the number of messages is stored
267 in (* result_messages)
268 @param result_recent the number of messages is stored
269 in (* result_recent)
270 @param result_unseen the number of messages is stored
271 in (* result_unseen)
272
273 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
274 on error
275*/
276
277int mailsession_status_folder(mailsession * session, char * mb,
278 uint32_t * result_messages, uint32_t * result_recent,
279 uint32_t * result_unseen);
280
281
282/*
283 mailsession_messages_number queries the number of messages in the folder
284
285 @param session the session
286 @param mb mailbox to query
287 @param result the number of messages is stored in (* result)
288
289 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
290 on error
291*/
292
293int mailsession_messages_number(mailsession * session, char * mb,
294 uint32_t * result);
295
296/*
297 mailsession_recent_number queries the number of recent messages in the folder
298
299 @param session the session
300 @param mb mailbox to query
301 @param result the number of recent messages is stored in (* result)
302
303 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
304 on error
305*/
306
307int mailsession_recent_number(mailsession * session,
308 char * mb, uint32_t * result);
309
310/*
311 mailsession_unseen_number queries the number of unseen messages in the folder
312
313 @param session the session
314 @param mb mailbox to query
315 @param result the number of unseen messages is stored in (* result)
316
317 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
318 on error
319*/
320
321int mailsession_unseen_number(mailsession * session, char * mb,
322 uint32_t * result);
323
324/*
325 NOTE: driver's specific should be used
326
327 mailsession_list_folders returns the list of all sub-mailboxes
328 of the given mailbox
329
330 @param session the session
331 @param mb the mailbox
332 @param result list of mailboxes if stored in (* result),
333 this structure have to be freed with mail_list_free()
334
335 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
336 on error
337*/
338
339int mailsession_list_folders(mailsession * session, char * mb,
340 struct mail_list ** result);
341
342/*
343 NOTE: driver's specific should be used
344
345 mailsession_lsub_folders returns the list of subscribed
346 sub-mailboxes of the given mailbox
347
348 @param session the session
349 @param mb the mailbox
350 @param result list of mailboxes if stored in (* result),
351 this structure have to be freed with mail_list_free()
352
353 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
354 on error
355*/
356
357int mailsession_lsub_folders(mailsession * session, char * mb,
358 struct mail_list ** result);
359
360/*
361 NOTE: driver's specific should be used
362
363 mailsession_subscribe_folder subscribes to the given mailbox
364
365 @param session the session
366 @param mb the mailbox
367
368 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
369 on error
370*/
371
372int mailsession_subscribe_folder(mailsession * session, char * mb);
373
374/*
375 NOTE: driver's specific should be used
376
377 mailsession_unsubscribe_folder unsubscribes to the given mailbox
378
379 @param session the session
380 @param mb the mailbox
381
382 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
383 on error
384*/
385
386int mailsession_unsubscribe_folder(mailsession * session, char * mb);
387
388/*
389 mailsession_append_message adds a RFC 2822 message to the current
390 given mailbox
391
392 @param session the session
393 @param message is a string that contains the RFC 2822 message
394 @param size this is the size of the message
395
396 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
397 on error
398*/
399
400int mailsession_append_message(mailsession * session,
401 char * message, size_t size);
402
403/*
404 NOTE: some drivers does not implement this
405
406 mailsession_copy_message copies a message whose number is given to
407 a given mailbox. The mailbox must be accessible from the same session.
408
409 @param session the session
410 @param num the message number
411 @param mb the destination mailbox
412
413 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
414 on error
415*/
416
417int mailsession_copy_message(mailsession * session,
418 uint32_t num, char * mb);
419
420/*
421 NOTE: some drivers does not implement this
422
423 mailsession_move_message copies a message whose number is given to
424 a given mailbox. The mailbox must be accessible from the same session.
425
426 @param session the session
427 @param num the message number
428 @param mb the destination mailbox
429
430 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
431 on error
432*/
433
434int mailsession_move_message(mailsession * session,
435 uint32_t num, char * mb);
436
437/*
438 mailsession_get_messages_list returns the list of message numbers
439 of the current mailbox.
440
441 @param session the session
442 @param result the list of message numbers will be stored in (* result),
443 this structure have to be freed with mailmessage_list_free()
444
445 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
446 on error
447*/
448
449int mailsession_get_messages_list(mailsession * session,
450 struct mailmessage_list ** result);
451
452/*
453 mailsession_get_envelopes_list fills the parsed fields in the
454 mailmessage structures of the mailmessage_list.
455
456 @param session the session
457 @param result this is the list of mailmessage structures
458
459 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
460 on error
461*/
462
463int mailsession_get_envelopes_list(mailsession * session,
464 struct mailmessage_list * result);
465
466/*
467 NOTE: some drivers does not implement this
468
469 mailsession_remove_message removes the given message from the mailbox.
470 The message is permanently deleted.
471
472 @param session the session
473 @param num is the message number
474
475 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
476 on error
477*/
478
479int mailsession_remove_message(mailsession * session, uint32_t num);
480
481
482/*
483 NOTE: this function is not implemented in most drivers
484
485 mailsession_search_message returns a list of message numbers that
486 corresponds to the given criteria.
487
488 @param session the session
489 @param charset is the charset to use (it can be NULL)
490 @param key is the list of criteria
491 @param result the search result is stored in (* result),
492 this structure have to be freed with mail_search_result_free()
493
494 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
495 on error
496*/
497
498#if 0
499int mailsession_search_messages(mailsession * session, char * charset,
500 struct mail_search_key * key,
501 struct mail_search_result ** result);
502#endif
503
504/*
505 mailsession_get_message returns a mailmessage structure that corresponds
506 to the given message number.
507 * WARNING * mailsession_get_message_by_uid() should be used instead.
508
509 @param session the session
510 @param num the message number
511 @param result the allocated mailmessage structure will be stored
512 in (* result), this structure have to be freed with mailmessage_free()
513
514 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
515 on error
516*/
517
518int mailsession_get_message(mailsession * session,
519 uint32_t num, mailmessage ** result);
520
521/*
522 mailsession_get_message_by_uid returns a mailmessage structure
523 that corresponds to the given message unique identifier.
524 This is currently implemented only for cached drivers.
525 * WARNING * That will deprecates the use of mailsession_get_message()
526
527 @param session the session
528 @param uid the message unique identifier
529 @param result the allocated mailmessage structure will be stored
530 in (* result), this structure have to be freed with mailmessage_free()
531
532 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
533 on error
534*/
535
536int mailsession_get_message_by_uid(mailsession * session,
537 const char * uid, mailmessage ** result);
538
539#ifdef __cplusplus
540}
541#endif
542
543#endif
diff --git a/kmicromail/libetpan/generic/maildriver_errors.h b/kmicromail/libetpan/generic/maildriver_errors.h
new file mode 100644
index 0000000..118b259
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_errors.h
@@ -0,0 +1,99 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - 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#ifndef MAILDRIVER_ERRORS_H
37
38#define MAILDRIVER_ERRORS_H
39
40enum {
41 MAIL_NO_ERROR = 0,
42 MAIL_NO_ERROR_AUTHENTICATED,
43 MAIL_NO_ERROR_NON_AUTHENTICATED,
44 MAIL_ERROR_NOT_IMPLEMENTED,
45 MAIL_ERROR_UNKNOWN,
46 MAIL_ERROR_CONNECT,
47 MAIL_ERROR_BAD_STATE,
48 MAIL_ERROR_FILE,
49 MAIL_ERROR_STREAM,
50 MAIL_ERROR_LOGIN,
51 MAIL_ERROR_CREATE, /* 10 */
52 MAIL_ERROR_DELETE,
53 MAIL_ERROR_LOGOUT,
54 MAIL_ERROR_NOOP,
55 MAIL_ERROR_RENAME,
56 MAIL_ERROR_CHECK,
57 MAIL_ERROR_EXAMINE,
58 MAIL_ERROR_SELECT,
59 MAIL_ERROR_MEMORY,
60 MAIL_ERROR_STATUS,
61 MAIL_ERROR_SUBSCRIBE, /* 20 */
62 MAIL_ERROR_UNSUBSCRIBE,
63 MAIL_ERROR_LIST,
64 MAIL_ERROR_LSUB,
65 MAIL_ERROR_APPEND,
66 MAIL_ERROR_COPY,
67 MAIL_ERROR_FETCH,
68 MAIL_ERROR_STORE,
69 MAIL_ERROR_SEARCH,
70 MAIL_ERROR_DISKSPACE,
71 MAIL_ERROR_MSG_NOT_FOUND, /* 30 */
72 MAIL_ERROR_PARSE,
73 MAIL_ERROR_INVAL,
74 MAIL_ERROR_PART_NOT_FOUND,
75 MAIL_ERROR_REMOVE,
76 MAIL_ERROR_FOLDER_NOT_FOUND,
77 MAIL_ERROR_MOVE,
78 MAIL_ERROR_STARTTLS,
79 MAIL_ERROR_CACHE_MISS,
80 MAIL_ERROR_NO_TLS,
81 MAIL_ERROR_EXPUNGE,
82 /* misc errors */
83 MAIL_ERROR_MISC,
84 MAIL_ERROR_PROTOCOL,
85 MAIL_ERROR_CAPABILITY,
86 MAIL_ERROR_CLOSE,
87 MAIL_ERROR_FATAL,
88 MAIL_ERROR_READONLY,
89 MAIL_ERROR_NO_APOP,
90 MAIL_ERROR_COMMAND_NOT_SUPPORTED,
91 MAIL_ERROR_NO_PERMISSION,
92 MAIL_ERROR_PROGRAM_ERROR,
93 MAIL_ERROR_SUBJECT_NOT_FOUND,
94 MAIL_ERROR_CHAR_ENCODING_FAILED,
95 MAIL_ERROR_SEND,
96 MAIL_ERROR_COMMAND,
97};
98
99#endif
diff --git a/kmicromail/libetpan/generic/maildriver_tools.c b/kmicromail/libetpan/generic/maildriver_tools.c
new file mode 100644
index 0000000..105fd9f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_tools.c
@@ -0,0 +1,841 @@
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 "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}
diff --git a/kmicromail/libetpan/generic/maildriver_tools.h b/kmicromail/libetpan/generic/maildriver_tools.h
new file mode 100644
index 0000000..eaddc5d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_tools.h
@@ -0,0 +1,81 @@
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#ifndef MAILDRIVER_TOOLS_H
37
38#define MAILDRIVER_TOOLS_H
39
40#include "maildriver_types.h"
41#include "mail_cache_db_types.h"
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47int
48maildriver_generic_get_envelopes_list(mailsession * session,
49 struct mailmessage_list * env_list);
50
51#if 0
52int maildriver_generic_search_messages(mailsession * session, char * charset,
53 struct mail_search_key * key,
54 struct mail_search_result ** result);
55#endif
56
57int
58maildriver_env_list_to_msg_list(struct mailmessage_list * env_list,
59 clist ** result);
60
61int maildriver_imf_error_to_mail_error(int error);
62
63char * maildriver_quote_mailbox(char * mb);
64
65int
66maildriver_env_list_to_msg_list_no_flags(struct mailmessage_list * env_list,
67 clist ** result);
68
69int maildriver_cache_clean_up(struct mail_cache_db * cache_db_env,
70 struct mail_cache_db * cache_db_flags,
71 struct mailmessage_list * env_list);
72
73int maildriver_message_cache_clean_up(char * cache_dir,
74 struct mailmessage_list * env_list,
75 void (* get_uid_from_filename)(char *));
76
77#ifdef __cplusplus
78}
79#endif
80
81#endif
diff --git a/kmicromail/libetpan/generic/maildriver_types.c b/kmicromail/libetpan/generic/maildriver_types.c
new file mode 100644
index 0000000..7b3b348
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types.c
@@ -0,0 +1,340 @@
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 "maildriver_types.h"
37#include <time.h>
38#include <stdlib.h>
39#include "mailmessage.h"
40
41struct mailmessage_list * mailmessage_list_new(carray * msg_tab)
42{
43 struct mailmessage_list * env_list;
44
45 env_list = malloc(sizeof(* env_list));
46 if (env_list == NULL)
47 return NULL;
48
49 env_list->msg_tab = msg_tab;
50
51 return env_list;
52}
53
54void mailmessage_list_free(struct mailmessage_list * env_list)
55{
56 unsigned int i;
57
58 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
59 mailmessage * msg;
60
61 msg = carray_get(env_list->msg_tab, i);
62 if (msg != NULL)
63 mailmessage_free(msg);
64 }
65 carray_free(env_list->msg_tab);
66 free(env_list);
67}
68
69struct mail_list * mail_list_new(clist * list)
70{
71 struct mail_list * resp;
72
73 resp = malloc(sizeof(* resp));
74 if (resp == NULL)
75 return NULL;
76 resp->mb_list = list;
77
78 return resp;
79}
80
81void mail_list_free(struct mail_list * resp)
82{
83 clist_foreach(resp->mb_list, (clist_func) free, NULL);
84 clist_free(resp->mb_list);
85 free(resp);
86}
87
88static int32_t mailimf_date_time_to_int(struct mailimf_date_time * date)
89{
90 return date->dt_year * 12 * 30 * 24 * 60 * 60 +
91 date->dt_month * 30 * 24 * 60 * 60 + date->dt_day * 24 * 60 * 60 +
92 (date->dt_hour - date->dt_zone) * 60 * 60 +
93 date->dt_min * 60 + date->dt_sec;
94}
95
96int32_t mailimf_date_time_comp(struct mailimf_date_time * date1,
97 struct mailimf_date_time * date2)
98{
99 return mailimf_date_time_to_int(date1) - mailimf_date_time_to_int(date2);
100}
101
102
103
104
105
106
107
108#if 0
109struct mail_search_key *
110mail_search_key_new(int sk_type,
111 char * sk_bcc,
112 struct mailimf_date_time * sk_before,
113 char * sk_body,
114 char * sk_cc,
115 char * sk_from,
116 struct mailimf_date_time * sk_on,
117 struct mailimf_date_time * sk_since,
118 char * sk_subject,
119 char * sk_text,
120 char * sk_to,
121 char * sk_header_name,
122 char * sk_header_value,
123 size_t sk_larger,
124 struct mail_search_key * sk_not,
125 struct mail_search_key * sk_or1,
126 struct mail_search_key * sk_or2,
127 size_t sk_smaller,
128 clist * sk_multiple)
129{
130 struct mail_search_key * key;
131
132 key = malloc(sizeof(* key));
133 if (key == NULL)
134 return NULL;
135
136 key->sk_type = sk_type;
137 key->sk_bcc = sk_bcc;
138 key->sk_before = sk_before;
139 key->sk_body = sk_body;
140 key->sk_cc = sk_cc;
141 key->sk_from = sk_from;
142 key->sk_on = sk_on;
143 key->sk_since = sk_since;
144 key->sk_subject = sk_subject;
145 key->sk_text = sk_text;
146 key->sk_to = sk_to;
147 key->sk_header_name = sk_header_name;
148 key->sk_header_value = sk_header_value;
149 key->sk_larger = sk_larger;
150 key->sk_not = sk_not;
151 key->sk_or1 = sk_or1;
152 key->sk_or2 = sk_or2;
153 key->sk_smaller = sk_smaller;
154 key->sk_multiple = sk_multiple;
155
156 return key;
157}
158
159
160void mail_search_key_free(struct mail_search_key * key)
161{
162 if (key->sk_bcc)
163 free(key->sk_bcc);
164 if (key->sk_before)
165 mailimf_date_time_free(key->sk_before);
166 if (key->sk_body)
167 free(key->sk_body);
168 if (key->sk_cc)
169 free(key->sk_cc);
170 if (key->sk_from)
171 free(key->sk_from);
172 if (key->sk_on)
173 mailimf_date_time_free(key->sk_on);
174 if (key->sk_since)
175 mailimf_date_time_free(key->sk_since);
176 if (key->sk_subject)
177 free(key->sk_subject);
178 if (key->sk_text)
179 free(key->sk_text);
180 if (key->sk_to)
181 free(key->sk_to);
182 if (key->sk_header_name)
183 free(key->sk_header_name);
184 if (key->sk_header_value)
185 free(key->sk_header_value);
186 if (key->sk_not)
187 mail_search_key_free(key->sk_not);
188 if (key->sk_or1)
189 mail_search_key_free(key->sk_or1);
190 if (key->sk_or2)
191 mail_search_key_free(key->sk_or2);
192 if (key->sk_multiple) {
193 clist_foreach(key->sk_multiple, (clist_func) mail_search_key_free, NULL);
194 clist_free(key->sk_multiple);
195 }
196
197 free(key);
198}
199
200
201struct mail_search_result * mail_search_result_new(clist * list)
202{
203 struct mail_search_result * search_result;
204
205 search_result = malloc(sizeof(* search_result));
206 if (search_result == NULL)
207 return NULL;
208 search_result->list = list;
209
210 return search_result;
211}
212
213void mail_search_result_free(struct mail_search_result * search_result)
214{
215 clist_foreach(search_result->list, (clist_func) free, NULL);
216 clist_free(search_result->list);
217 free(search_result);
218}
219#endif
220
221struct error_message {
222 int code;
223 char * message;
224};
225
226static struct error_message message_tab[] = {
227{ MAIL_NO_ERROR, "no error" },
228{ MAIL_NO_ERROR_AUTHENTICATED, "no error - authenticated" },
229{ MAIL_NO_ERROR_NON_AUTHENTICATED, "no error - not authenticated" },
230{ MAIL_ERROR_NOT_IMPLEMENTED, "not implemented" },
231{ MAIL_ERROR_UNKNOWN, "unknown"},
232{ MAIL_ERROR_CONNECT, "connect"},
233{ MAIL_ERROR_BAD_STATE, "bad state"},
234{ MAIL_ERROR_FILE, "file error - file could not be accessed" },
235{ MAIL_ERROR_STREAM, "stream error - socket could not be read or written" },
236{ MAIL_ERROR_LOGIN, "login error" },
237{ MAIL_ERROR_CREATE, "create error" },
238{ MAIL_ERROR_DELETE, /* 10 */ "delete error" },
239{ MAIL_ERROR_LOGOUT, "logout error" },
240{ MAIL_ERROR_NOOP, "noop error" },
241{ MAIL_ERROR_RENAME, "rename error" },
242{ MAIL_ERROR_CHECK, "check error" },
243{ MAIL_ERROR_EXAMINE, "examine error" },
244{ MAIL_ERROR_SELECT, "select error - folder does not exist" },
245{ MAIL_ERROR_MEMORY, "not enough memory" },
246{ MAIL_ERROR_STATUS, "status error" },
247{ MAIL_ERROR_SUBSCRIBE, "subscribe error" },
248{ MAIL_ERROR_UNSUBSCRIBE, /* 20 */ "unsubscribe error" },
249{ MAIL_ERROR_LIST, "list error" },
250{ MAIL_ERROR_LSUB, "lsub error" },
251{ MAIL_ERROR_APPEND, "append error - mail could not be appended" },
252{ MAIL_ERROR_COPY, "copy error" },
253{ MAIL_ERROR_FETCH, "fetch error" },
254{ MAIL_ERROR_STORE, "store error" },
255{ MAIL_ERROR_SEARCH, "search error" },
256{ MAIL_ERROR_DISKSPACE, " error: not enough diskspace" },
257{ MAIL_ERROR_MSG_NOT_FOUND, "message not found" },
258{ MAIL_ERROR_PARSE, /* 30 */ "parse error" },
259{ MAIL_ERROR_INVAL, "invalid parameter for the function" },
260{ MAIL_ERROR_PART_NOT_FOUND, "mime part of the message is not found" },
261{ MAIL_ERROR_REMOVE, "remove error - the message did not exist" },
262{ MAIL_ERROR_FOLDER_NOT_FOUND, "folder not found" },
263{ MAIL_ERROR_MOVE, "move error" },
264{ MAIL_ERROR_STARTTLS, "starttls error" },
265{ MAIL_ERROR_CACHE_MISS, "mail cache missed" },
266{ MAIL_ERROR_NO_TLS, "no starttls" },
267{ MAIL_ERROR_EXPUNGE, "expunge error" },
268{ MAIL_ERROR_PROTOCOL, "protocol error - server did not respect the protocol" },
269{ MAIL_ERROR_CAPABILITY, "capability error" },
270{ MAIL_ERROR_CLOSE, "close error" },
271{ MAIL_ERROR_FATAL, "fatal error" },
272{ MAIL_ERROR_READONLY, "mailbox is readonly" },
273{ MAIL_ERROR_NO_APOP, "pop3 error - no apop" },
274{ MAIL_ERROR_COMMAND_NOT_SUPPORTED, "nntp error - command not supported" },
275{ MAIL_ERROR_NO_PERMISSION, "nntp error - no permission" },
276{ MAIL_ERROR_PROGRAM_ERROR, "nntp error - program error" },
277{ MAIL_ERROR_SUBJECT_NOT_FOUND, "internal threading error - subject not found" }};
278
279const char * maildriver_strerror(int err)
280{
281 int count;
282 int i;
283
284 count = sizeof(message_tab) / sizeof(struct error_message);
285
286 for(i = 0 ; i < count ; i++) {
287 if (message_tab[i].code == err) {
288 return message_tab[i].message;
289 }
290 }
291
292 return "unknown error";
293}
294
295
296struct mail_flags * mail_flags_new_empty(void)
297{
298 struct mail_flags * flags;
299
300 flags = malloc(sizeof(* flags));
301 if (flags == NULL)
302 goto err;
303
304 flags->fl_flags = MAIL_FLAG_NEW;
305 flags->fl_extension = clist_new();
306 if (flags->fl_extension == NULL)
307 goto free;
308
309 return flags;
310
311 free:
312 free(flags);
313 err:
314 return NULL;
315}
316
317struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_extension)
318{
319 struct mail_flags * flags;
320
321 flags = malloc(sizeof(* flags));
322 if (flags == NULL)
323 goto err;
324
325 flags->fl_flags = fl_flags;
326 flags->fl_extension = fl_extension;
327
328 return flags;
329
330err:
331 return NULL;
332}
333
334void mail_flags_free(struct mail_flags * flags)
335{
336 clist_foreach(flags->fl_extension, (clist_func) free, NULL);
337 clist_free(flags->fl_extension);
338 free(flags);
339}
340
diff --git a/kmicromail/libetpan/generic/maildriver_types.h b/kmicromail/libetpan/generic/maildriver_types.h
new file mode 100644
index 0000000..3ff9440
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types.h
@@ -0,0 +1,793 @@
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#ifndef MAILDRIVER_TYPES_H
37
38#define MAILDRIVER_TYPES_H
39
40#include <inttypes.h>
41#include <sys/types.h>
42
43#include <libetpan/mailstream.h>
44#include <libetpan/mailimf.h>
45#include <libetpan/mailmime.h>
46#include <libetpan/carray.h>
47
48#include <libetpan/mailthread_types.h>
49#include <libetpan/maildriver_errors.h>
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55typedef struct mailsession_driver mailsession_driver;
56
57typedef struct mailsession mailsession;
58
59typedef struct mailmessage_driver mailmessage_driver;
60
61typedef struct mailmessage mailmessage;
62
63
64/*
65 mailmessage_list is a list of mailmessage
66
67 - tab is an array of mailmessage structures
68*/
69
70struct mailmessage_list {
71 carray * msg_tab; /* elements are (mailmessage *) */
72};
73
74struct mailmessage_list * mailmessage_list_new(carray * msg_tab);
75void mailmessage_list_free(struct mailmessage_list * env_list);
76
77/*
78 mail_list is a list of mailbox names
79
80 - list is a list of mailbox names
81*/
82
83struct mail_list {
84 clist * mb_list; /* elements are (char *) */
85};
86
87struct mail_list * mail_list_new(clist * mb_list);
88void mail_list_free(struct mail_list * resp);
89
90/*
91 This is a flag value.
92 Flags can be combined with OR operation
93*/
94
95enum {
96 MAIL_FLAG_NEW = 1 << 0,
97 MAIL_FLAG_SEEN = 1 << 1,
98 MAIL_FLAG_FLAGGED = 1 << 2,
99 MAIL_FLAG_DELETED = 1 << 3,
100 MAIL_FLAG_ANSWERED = 1 << 4,
101 MAIL_FLAG_FORWARDED = 1 << 5,
102 MAIL_FLAG_CANCELLED = 1 << 6,
103};
104
105/*
106 mail_flags is the value of a flag related to a message.
107
108 - flags is the standard flags value
109
110 - extension is a list of unknown flags for libEtPan!
111*/
112
113struct mail_flags {
114 uint32_t fl_flags;
115 clist * fl_extension; /* elements are (char *) */
116};
117
118struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_ext);
119void mail_flags_free(struct mail_flags * flags);
120
121/*
122 This function creates a flag for a new message
123*/
124
125struct mail_flags * mail_flags_new_empty(void);
126
127
128/*
129 mailimf_date_time_comp compares two dates
130
131
132*/
133
134int32_t mailimf_date_time_comp(struct mailimf_date_time * date1,
135 struct mailimf_date_time * date2);
136
137/*
138 this is type type of the search criteria
139*/
140
141enum {
142 MAIL_SEARCH_KEY_ALL, /* all messages correspond */
143 MAIL_SEARCH_KEY_ANSWERED, /* messages with flag \Answered */
144 MAIL_SEARCH_KEY_BCC, /* messages which Bcc field contains
145 a given string */
146 MAIL_SEARCH_KEY_BEFORE, /* messages which internal date is earlier
147 than the specified date */
148 MAIL_SEARCH_KEY_BODY, /* message that contains the given string
149 (in header and text parts) */
150 MAIL_SEARCH_KEY_CC, /* messages whose Cc field contains the
151 given string */
152 MAIL_SEARCH_KEY_DELETED, /* messages with the flag \Deleted */
153 MAIL_SEARCH_KEY_FLAGGED, /* messages with the flag \Flagged */
154 MAIL_SEARCH_KEY_FROM, /* messages whose From field contains the
155 given string */
156 MAIL_SEARCH_KEY_NEW, /* messages with the flag \Recent and not
157 the \Seen flag */
158 MAIL_SEARCH_KEY_OLD, /* messages that do not have the
159 \Recent flag set */
160 MAIL_SEARCH_KEY_ON, /* messages whose internal date is the
161 specified date */
162 MAIL_SEARCH_KEY_RECENT, /* messages with the flag \Recent */
163 MAIL_SEARCH_KEY_SEEN, /* messages with the flag \Seen */
164 MAIL_SEARCH_KEY_SINCE, /* messages whose internal date is later
165 than specified date */
166 MAIL_SEARCH_KEY_SUBJECT, /* messages whose Subject field contains the
167 given string */
168 MAIL_SEARCH_KEY_TEXT, /* messages whose text part contains the
169 given string */
170 MAIL_SEARCH_KEY_TO, /* messages whose To field contains the
171 given string */
172 MAIL_SEARCH_KEY_UNANSWERED, /* messages with no flag \Answered */
173 MAIL_SEARCH_KEY_UNDELETED, /* messages with no flag \Deleted */
174 MAIL_SEARCH_KEY_UNFLAGGED, /* messages with no flag \Flagged */
175 MAIL_SEARCH_KEY_UNSEEN, /* messages with no flag \Seen */
176 MAIL_SEARCH_KEY_HEADER, /* messages whose given field
177 contains the given string */
178 MAIL_SEARCH_KEY_LARGER, /* messages whose size is larger then
179 the given size */
180 MAIL_SEARCH_KEY_NOT, /* not operation of the condition */
181 MAIL_SEARCH_KEY_OR, /* or operation between two conditions */
182 MAIL_SEARCH_KEY_SMALLER, /* messages whose size is smaller than
183 the given size */
184 MAIL_SEARCH_KEY_MULTIPLE /* the boolean operator between the
185 conditions is AND */
186};
187
188/*
189 mail_search_key is the condition on the messages to return
190
191 - type is the type of the condition
192
193 - bcc is the text to search in the Bcc field when type is
194 MAIL_SEARCH_KEY_BCC, should be allocated with malloc()
195
196 - before is a date when type is MAIL_SEARCH_KEY_BEFORE
197
198 - body is the text to search in the message when type is
199 MAIL_SEARCH_KEY_BODY, should be allocated with malloc()
200
201 - cc is the text to search in the Cc field when type is
202 MAIL_SEARCH_KEY_CC, should be allocated with malloc()
203
204 - from is the text to search in the From field when type is
205 MAIL_SEARCH_KEY_FROM, should be allocated with malloc()
206
207 - on is a date when type is MAIL_SEARCH_KEY_ON
208
209 - since is a date when type is MAIL_SEARCH_KEY_SINCE
210
211 - subject is the text to search in the Subject field when type is
212 MAILIMAP_SEARCH_KEY_SUBJECT, should be allocated with malloc()
213
214 - text is the text to search in the text part of the message when
215 type is MAILIMAP_SEARCH_KEY_TEXT, should be allocated with malloc()
216
217 - to is the text to search in the To field when type is
218 MAILIMAP_SEARCH_KEY_TO, should be allocated with malloc()
219
220 - header_name is the header name when type is MAILIMAP_SEARCH_KEY_HEADER,
221 should be allocated with malloc()
222
223 - header_value is the text to search in the given header when type is
224 MAILIMAP_SEARCH_KEY_HEADER, should be allocated with malloc()
225
226 - larger is a size when type is MAILIMAP_SEARCH_KEY_LARGER
227
228 - not is a condition when type is MAILIMAP_SEARCH_KEY_NOT
229
230 - or1 is a condition when type is MAILIMAP_SEARCH_KEY_OR
231
232 - or2 is a condition when type is MAILIMAP_SEARCH_KEY_OR
233
234 - sentbefore is a date when type is MAILIMAP_SEARCH_KEY_SENTBEFORE
235
236 - senton is a date when type is MAILIMAP_SEARCH_KEY_SENTON
237
238 - sentsince is a date when type is MAILIMAP_SEARCH_KEY_SENTSINCE
239
240 - smaller is a size when type is MAILIMAP_SEARCH_KEY_SMALLER
241
242 - multiple is a set of message when type is MAILIMAP_SEARCH_KEY_MULTIPLE
243*/
244
245#if 0
246struct mail_search_key {
247 int sk_type;
248 union {
249 char * sk_bcc;
250 struct mailimf_date_time * sk_before;
251 char * sk_body;
252 char * sk_cc;
253 char * sk_from;
254 struct mailimf_date_time * sk_on;
255 struct mailimf_date_time * sk_since;
256 char * sk_subject;
257 char * sk_text;
258 char * sk_to;
259 char * sk_header_name;
260 char * sk_header_value;
261 size_t sk_larger;
262 struct mail_search_key * sk_not;
263 struct mail_search_key * sk_or1;
264 struct mail_search_key * sk_or2;
265 size_t sk_smaller;
266 clist * sk_multiple; /* list of (struct mailimap_search_key *) */
267 } sk_data;
268};
269
270
271struct mail_search_key *
272mail_search_key_new(int sk_type,
273 char * sk_bcc, struct mailimf_date_time * sk_before,
274 char * sk_body, char * sk_cc, char * sk_from,
275 struct mailimf_date_time * sk_on, struct mailimf_date_time * sk_since,
276 char * sk_subject, char * sk_text, char * sk_to,
277 char * sk_header_name, char * sk_header_value, size_t sk_larger,
278 struct mail_search_key * sk_not, struct mail_search_key * sk_or1,
279 struct mail_search_key * sk_or2, size_t sk_smaller,
280 clist * sk_multiple);
281
282void mail_search_key_free(struct mail_search_key * key);
283#endif
284
285/*
286 mail_search_result is a list of message numbers that is returned
287 by the mailsession_search_messages function()
288*/
289
290#if 0
291struct mail_search_result {
292 clist * sr_list; /* list of (uint32_t *) */
293};
294
295struct mail_search_result * mail_search_result_new(clist * sr_list);
296
297void mail_search_result_free(struct mail_search_result * search_result);
298#endif
299
300
301/*
302 There is three kinds of identities :
303 - storage
304 - folders
305 - session
306
307 A storage (struct mailstorage) represents whether a server or
308 a main path,
309
310 A storage can be an IMAP server, the root path of a MH or a mbox file.
311
312 Folders (struct mailfolder) are the mailboxes we can
313 choose in the server or as sub-folder of the main path.
314
315 Folders for IMAP are the IMAP mailboxes, for MH this is one of the
316 folder of the MH storage, for mbox, there is only one folder, the
317 mbox file content;
318
319 A mail session (struct mailsession) is whether a connection to a server
320 or a path that is open. It is the abstraction lower folders and storage.
321 It allow us to send commands.
322
323 We have a session driver for mail session for each kind of storage.
324
325 From a session, we can get a message (struct mailmessage) to read.
326 We have a message driver for each kind of storage.
327*/
328
329/*
330 maildriver is the driver structure for mail sessions
331
332 - name is the name of the driver
333
334 - initialize() is the function that will initializes a data structure
335 specific to the driver, it returns a value that will be stored
336 in the field data of the session.
337 The field data of the session is the state of the session,
338 the internal data structure used by the driver.
339 It is called when creating the mailsession structure with
340 mailsession_new().
341
342 - uninitialize() frees the structure created with initialize()
343
344 - parameters() implements functions specific to the given mail access
345
346 - connect_stream() connects a stream to the session
347
348 - connect_path() notify a main path to the session
349
350 - starttls() changes the current stream to a TLS stream
351
352 - login() notifies the user and the password to authenticate to the
353 session
354
355 - logout() exits the session and closes the stream
356
357 - noop() does no operation on the session, but it can be
358 used to poll for the status of the connection.
359
360 - build_folder_name() will return an allocated string with
361 that contains the complete path of the folder to create
362
363 - create_folder() creates the folder that corresponds to the
364 given name
365
366 - delete_folder() deletes the folder that corresponds to the
367 given name
368
369 - rename_folder() change the name of the folder
370
371 - check_folder() makes a checkpoint of the session
372
373 - examine_folder() selects a mailbox as readonly
374
375 - select_folder() selects a mailbox
376
377 - expunge_folder() deletes all messages marked \Deleted
378
379 - status_folder() queries the status of the folder
380 (number of messages, number of recent messages, number of
381 unseen messages)
382
383 - messages_number() queries the number of messages in the folder
384
385 - recent_number() queries the number of recent messages in the folder
386
387 - unseen_number() queries the number of unseen messages in the folder
388
389 - list_folders() returns the list of all sub-mailboxes
390 of the given mailbox
391
392 - lsub_folders() returns the list of subscribed
393 sub-mailboxes of the given mailbox
394
395 - subscribe_folder() subscribes to the given mailbox
396
397 - unsubscribe_folder() unsubscribes to the given mailbox
398
399 - append_message() adds a RFC 2822 message to the current
400 given mailbox
401
402 - copy_message() copies a message whose number is given to
403 a given mailbox. The mailbox must be accessible from
404 the same session.
405
406 - move_message() copies a message whose number is given to
407 a given mailbox. The mailbox must be accessible from the
408 same session.
409
410 - get_messages_list() returns the list of message numbers
411 of the current mailbox.
412
413 - get_envelopes_list() fills the parsed fields in the
414 mailmessage structures of the mailmessage_list.
415
416 - remove_message() removes the given message from the mailbox.
417 The message is permanently deleted.
418
419 - search_message() returns a list of message numbers that
420 corresponds to the given criteria.
421
422 - get_message returns a mailmessage structure that corresponds
423 to the given message number.
424
425 - get_message_by_uid returns a mailmessage structure that corresponds
426 to the given message unique identifier.
427
428 * mandatory functions are the following :
429
430 - connect_stream() of connect_path()
431 - logout()
432 - get_messages_list()
433 - get_envelopes_list()
434
435 * we advise you to implement these functions :
436
437 - select_folder() (in case a session can access several folders)
438 - noop() (to check if the server is responding)
439 - check_folder() (to make a checkpoint of the session)
440 - status_folder(), messages_number(), recent_number(), unseen_number()
441 (to get stat of the folder)
442 - append_message() (but can't be done in the case of POP3 at least)
443 - login() in a case of an authenticated driver.
444 - starttls() in a case of a stream driver, if the procotol supports
445 STARTTLS.
446 - get_message_by_uid() so that the application can remember the message
447 by UID and build its own list of messages.
448
449 * drivers' specific :
450
451 Everything that is specific to the driver will be implemented in this
452 function :
453
454 - parameters()
455*/
456
457struct mailsession_driver {
458 char * sess_name;
459
460 int (* sess_initialize)(mailsession * session);
461 void (* sess_uninitialize)(mailsession * session);
462
463 int (* sess_parameters)(mailsession * session,
464 int id, void * value);
465
466 int (* sess_connect_stream)(mailsession * session, mailstream * s);
467 int (* sess_connect_path)(mailsession * session, char * path);
468
469 int (* sess_starttls)(mailsession * session);
470
471 int (* sess_login)(mailsession * session, char * userid, char * password);
472 int (* sess_logout)(mailsession * session);
473 int (* sess_noop)(mailsession * session);
474
475 /* folders operations */
476
477 int (* sess_build_folder_name)(mailsession * session, char * mb,
478 char * name, char ** result);
479
480 int (* sess_create_folder)(mailsession * session, char * mb);
481 int (* sess_delete_folder)(mailsession * session, char * mb);
482 int (* sess_rename_folder)(mailsession * session, char * mb,
483 char * new_name);
484 int (* sess_check_folder)(mailsession * session);
485 int (* sess_examine_folder)(mailsession * session, char * mb);
486 int (* sess_select_folder)(mailsession * session, char * mb);
487 int (* sess_expunge_folder)(mailsession * session);
488 int (* sess_status_folder)(mailsession * session, char * mb,
489 uint32_t * result_num, uint32_t * result_recent,
490 uint32_t * result_unseen);
491 int (* sess_messages_number)(mailsession * session, char * mb,
492 uint32_t * result);
493 int (* sess_recent_number)(mailsession * session, char * mb,
494 uint32_t * result);
495 int (* sess_unseen_number)(mailsession * session, char * mb,
496 uint32_t * result);
497
498 int (* sess_list_folders)(mailsession * session, char * mb,
499 struct mail_list ** result);
500 int (* sess_lsub_folders)(mailsession * session, char * mb,
501 struct mail_list ** result);
502
503 int (* sess_subscribe_folder)(mailsession * session, char * mb);
504 int (* sess_unsubscribe_folder)(mailsession * session, char * mb);
505
506 /* messages operations */
507
508 int (* sess_append_message)(mailsession * session,
509 char * message, size_t size);
510 int (* sess_copy_message)(mailsession * session,
511 uint32_t num, char * mb);
512 int (* sess_move_message)(mailsession * session,
513 uint32_t num, char * mb);
514
515 int (* sess_get_message)(mailsession * session,
516 uint32_t num, mailmessage ** result);
517
518 int (* sess_get_message_by_uid)(mailsession * session,
519 const char * uid, mailmessage ** result);
520
521 int (* sess_get_messages_list)(mailsession * session,
522 struct mailmessage_list ** result);
523 int (* sess_get_envelopes_list)(mailsession * session,
524 struct mailmessage_list * env_list);
525 int (* sess_remove_message)(mailsession * session, uint32_t num);
526#if 0
527 int (* sess_search_messages)(mailsession * session, char * charset,
528 struct mail_search_key * key,
529 struct mail_search_result ** result);
530#endif
531};
532
533
534/*
535 session is the data structure for a mail session.
536
537 - data is the internal data structure used by the driver
538 It is called when initializing the mailsession structure.
539
540 - driver is the driver used for the session
541*/
542
543struct mailsession {
544 void * sess_data;
545 mailsession_driver * sess_driver;
546};
547
548
549
550
551/*
552 mailmessage_driver is the driver structure to get information from messages.
553
554 - name is the name of the driver
555
556 - initialize() is the function that will initializes a data structure
557 specific to the driver, it returns a value that will be stored
558 in the field data of the mailsession.
559 The field data of the session is the state of the session,
560 the internal data structure used by the driver.
561 It is called when initializing the mailmessage structure with
562 mailmessage_init().
563
564 - uninitialize() frees the structure created with initialize().
565 It will be called by mailmessage_free().
566
567 - flush() will free from memory all temporary structures of the message
568 (for example, the MIME structure of the message).
569
570 - fetch_result_free() will free all strings resulted by fetch() or
571 any fetch_xxx() functions that returns a string.
572
573 - fetch() returns the content of the message (headers and text).
574
575 - fetch_header() returns the content of the headers.
576
577 - fetch_body() returns the message text (message content without headers)
578
579 - fetch_size() returns the size of the message content.
580
581 - get_bodystructure() returns the MIME structure of the message.
582
583 - fetch_section() returns the content of a given MIME part
584
585 - fetch_section_header() returns the header of the message
586 contained by the given MIME part.
587
588 - fetch_section_mime() returns the MIME headers of the
589 given MIME part.
590
591 - fetch_section_body() returns the text (if this is a message, this is the
592 message content without headers) of the given MIME part.
593
594 - fetch_envelope() returns a mailimf_fields structure, with a list of
595 fields chosen by the driver.
596
597 - get_flags() returns a the flags related to the message.
598 When you want to get flags of a message, you have to make sure to
599 call get_flags() at least once before using directly message->flags.
600*/
601
602#define LIBETPAN_MAIL_MESSAGE_CHECK
603
604struct mailmessage_driver {
605 char * msg_name;
606
607 int (* msg_initialize)(mailmessage * msg_info);
608
609 void (* msg_uninitialize)(mailmessage * msg_info);
610
611 void (* msg_flush)(mailmessage * msg_info);
612
613 void (* msg_check)(mailmessage * msg_info);
614
615 void (* msg_fetch_result_free)(mailmessage * msg_info,
616 char * msg);
617
618 int (* msg_fetch)(mailmessage * msg_info,
619 char ** result,
620 size_t * result_len);
621
622 int (* msg_fetch_header)(mailmessage * msg_info,
623 char ** result,
624 size_t * result_len);
625
626 int (* msg_fetch_body)(mailmessage * msg_info,
627 char ** result, size_t * result_len);
628
629 int (* msg_fetch_size)(mailmessage * msg_info,
630 size_t * result);
631
632 int (* msg_get_bodystructure)(mailmessage * msg_info,
633 struct mailmime ** result);
634
635 int (* msg_fetch_section)(mailmessage * msg_info,
636 struct mailmime * mime,
637 char ** result, size_t * result_len);
638
639 int (* msg_fetch_section_header)(mailmessage * msg_info,
640 struct mailmime * mime,
641 char ** result,
642 size_t * result_len);
643
644 int (* msg_fetch_section_mime)(mailmessage * msg_info,
645 struct mailmime * mime,
646 char ** result,
647 size_t * result_len);
648
649 int (* msg_fetch_section_body)(mailmessage * msg_info,
650 struct mailmime * mime,
651 char ** result,
652 size_t * result_len);
653
654 int (* msg_fetch_envelope)(mailmessage * msg_info,
655 struct mailimf_fields ** result);
656
657 int (* msg_get_flags)(mailmessage * msg_info,
658 struct mail_flags ** result);
659};
660
661
662/*
663 mailmessage is a data structure to get information from messages
664
665 - session is the session linked to the given message, it can be NULL
666
667 - driver is the message driver
668
669 - index is the message number
670
671 - uid, when it is not NULL, it means that the folder
672 the folder has persistant message numbers, the string is
673 the unique message number in the folder.
674 uid should be implemented if possible.
675 for drivers where we cannot generate real uid,
676 a suggestion is "AAAA-IIII" where AAAA is some
677 random session number and IIII the content of index field.
678
679 - size, when it is not 0, is the size of the message content.
680
681 - fields, when it is not NULL, are the header fields of the message.
682
683 - flags, when it is not NULL, are the flags related to the message.
684
685 - single_fields, when resolved != 0, is filled with the data of fields.
686
687 - mime, when it is not NULL
688
689 - cached is != 0 when the header fields were read from the cache.
690
691 - data is data specific to the driver, this is internal data structure,
692 some state of the message.
693*/
694
695struct mailmessage {
696 mailsession * msg_session;
697 mailmessage_driver * msg_driver;
698 uint32_t msg_index;
699 char * msg_uid;
700
701 size_t msg_size;
702 struct mailimf_fields * msg_fields;
703 struct mail_flags * msg_flags;
704
705 int msg_resolved;
706 struct mailimf_single_fields msg_single_fields;
707 struct mailmime * msg_mime;
708
709 /* internal data */
710
711 int msg_cached;
712 void * msg_data;
713
714 /*
715 msg_folder field :
716 used to reference the mailfolder, this is a workaround due
717 to the problem with initial conception, where folder notion
718 did not exist.
719 */
720 void * msg_folder;
721 /* user data */
722 void * msg_user_data;
723};
724
725
726/*
727 mailmessage_tree is a node in the messages tree (thread)
728
729 - parent is the parent of the message, it is NULL if the message
730 is the root of the message tree.
731
732 - date is the date of the message in number of second elapsed
733 since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
734
735 - msg is the message structure that is stored referenced by the node.
736 is msg is NULL, this is a dummy node.
737
738 - children is an array that contains all the children of the node.
739 children are mailmessage_tree structures.
740
741 - is_reply is != 0 when the message is a reply or a forward
742
743 - base_subject is the extracted subject of the message.
744
745 - index is the message number.
746*/
747
748struct mailmessage_tree {
749 struct mailmessage_tree * node_parent;
750 char * node_msgid;
751 time_t node_date;
752 mailmessage * node_msg;
753 carray * node_children; /* array of (struct mailmessage_tree *) */
754
755 /* private, used for threading */
756 int node_is_reply;
757 char * node_base_subject;
758};
759
760
761struct mailmessage_tree *
762mailmessage_tree_new(char * node_msgid, time_t node_date,
763 mailmessage * node_msg);
764
765void mailmessage_tree_free(struct mailmessage_tree * tree);
766
767/*
768 mailmessage_tree_free_recursive
769
770 if you want to release memory of the given tree and all the sub-trees,
771 you can use this function.
772*/
773
774void mailmessage_tree_free_recursive(struct mailmessage_tree * tree);
775
776
777struct generic_message_t {
778 int (* msg_prefetch)(mailmessage * msg_info);
779 void (* msg_prefetch_free)(struct generic_message_t * msg);
780 int msg_fetched;
781 char * msg_message;
782 size_t msg_length;
783 void * msg_data;
784};
785
786
787const char * maildriver_strerror(int err);
788
789#ifdef __cplusplus
790}
791#endif
792
793#endif
diff --git a/kmicromail/libetpan/generic/maildriver_types_helper.c b/kmicromail/libetpan/generic/maildriver_types_helper.c
new file mode 100644
index 0000000..580af7d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types_helper.c
@@ -0,0 +1,104 @@
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 "maildriver_types_helper.h"
37
38#include "mail.h"
39
40#include "clist.h"
41#include <string.h>
42#include <stdlib.h>
43
44int mail_flags_add_extension(struct mail_flags * flags,
45 char * ext_flag)
46{
47 char * str;
48 int r;
49
50 if (mail_flags_has_extension(flags, ext_flag))
51 return MAIL_NO_ERROR;
52
53 str = strdup(ext_flag);
54 if (str == NULL)
55 return MAIL_ERROR_MEMORY;
56
57 r = clist_append(flags->fl_extension, str);
58 if (r < 0) {
59 free(str);
60 return MAIL_ERROR_MEMORY;
61 }
62
63 return MAIL_NO_ERROR;
64}
65
66int mail_flags_remove_extension(struct mail_flags * flags,
67 char * ext_flag)
68{
69 clistiter * cur;
70
71 cur = clist_begin(flags->fl_extension);
72 while (cur != NULL) {
73 char * flag_name;
74
75 flag_name = clist_content(cur);
76
77 if (strcasecmp(flag_name, ext_flag) == 0) {
78 free(flag_name);
79 cur = clist_delete(flags->fl_extension, cur);
80 }
81 else
82 cur = clist_next(cur);
83 }
84
85 return MAIL_NO_ERROR;
86}
87
88int mail_flags_has_extension(struct mail_flags * flags,
89 char * ext_flag)
90{
91 clistiter * cur;
92
93 for(cur = clist_begin(flags->fl_extension) ; cur != NULL ;
94 cur = clist_next(cur)) {
95 char * flag_name;
96
97 flag_name = clist_content(cur);
98
99 if (strcasecmp(flag_name, ext_flag) == 0)
100 return TRUE;
101 }
102
103 return FALSE;
104}
diff --git a/kmicromail/libetpan/generic/maildriver_types_helper.h b/kmicromail/libetpan/generic/maildriver_types_helper.h
new file mode 100644
index 0000000..2e74dea
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types_helper.h
@@ -0,0 +1,99 @@
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#ifndef MAILDRIVER_TYPES_HELPER_H
37
38#define MAILDRIVER_TYPES_HELPER_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mail_flags_add_extension adds the given flag if it does not exists in
48 the flags.
49
50 @param flags this is the flag to change
51
52 @param ext_flag this is the name of an extension flag
53 the given flag name is duplicated and is no more needed after
54 the function call.
55
56 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
57 on error
58*/
59
60int mail_flags_add_extension(struct mail_flags * flags,
61 char * ext_flag);
62
63/*
64 mail_flags_remove_extension removes the given flag if it does not exists in
65 the flags.
66
67 @param flags this is the flag to change
68
69 @param ext_flag this is the name of an extension flag
70 the given flag name is no more needed after the function call.
71
72 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
73 on error
74*/
75
76int mail_flags_remove_extension(struct mail_flags * flags,
77 char * ext_flag);
78
79/*
80 mail_flags_has_extension returns 1 if the flags is in the given flags,
81 0 is returned otherwise.
82
83 @param flags this is the flag to change
84
85 @param ext_flag this is the name of an extension flag
86 the given flag name is no more needed after the function call.
87
88 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
89 on error
90*/
91
92int mail_flags_has_extension(struct mail_flags * flags,
93 char * ext_flag);
94
95#ifdef __cplusplus
96}
97#endif
98
99#endif
diff --git a/kmicromail/libetpan/generic/mailfolder.c b/kmicromail/libetpan/generic/mailfolder.c
new file mode 100644
index 0000000..2ddc37d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailfolder.c
@@ -0,0 +1,96 @@
1#include "mailfolder.h"
2
3#include "maildriver.h"
4
5int mailfolder_noop(struct mailfolder * folder)
6{
7 return mailsession_noop(folder->fld_session);
8}
9
10int mailfolder_check(struct mailfolder * folder)
11{
12 return mailsession_check_folder(folder->fld_session);
13}
14
15int mailfolder_expunge(struct mailfolder * folder)
16{
17 return mailsession_expunge_folder(folder->fld_session);
18}
19
20int mailfolder_status(struct mailfolder * folder,
21 uint32_t * result_messages, uint32_t * result_recent,
22 uint32_t * result_unseen)
23{
24 return mailsession_status_folder(folder->fld_session,
25 folder->fld_pathname, result_messages,
26 result_recent, result_unseen);
27}
28
29int mailfolder_append_message(struct mailfolder * folder,
30 char * message, size_t size)
31{
32 return mailsession_append_message(folder->fld_session, message, size);
33}
34
35int mailfolder_get_messages_list(struct mailfolder * folder,
36 struct mailmessage_list ** result)
37{
38 int r;
39 struct mailmessage_list * msg_list;
40 unsigned int i;
41
42 r = mailsession_get_messages_list(folder->fld_session, &msg_list);
43 if (r != MAIL_NO_ERROR)
44 return r;
45
46 for(i = 0 ; i < carray_count(msg_list->msg_tab) ; i ++) {
47 mailmessage * msg;
48
49 msg = carray_get(msg_list->msg_tab, i);
50 msg->msg_folder = folder;
51 }
52
53 * result = msg_list;
54
55 return MAIL_NO_ERROR;
56}
57
58int mailfolder_get_envelopes_list(struct mailfolder * folder,
59 struct mailmessage_list * result)
60{
61 return mailsession_get_envelopes_list(folder->fld_session, result);
62}
63
64int mailfolder_get_message(struct mailfolder * folder,
65 uint32_t num, mailmessage ** result)
66{
67 mailmessage * msg;
68 int r;
69
70 r = mailsession_get_message(folder->fld_session, num, &msg);
71 if (r != MAIL_NO_ERROR)
72 return r;
73
74 msg->msg_folder = folder;
75
76 * result = msg;
77
78 return MAIL_NO_ERROR;
79}
80
81int mailfolder_get_message_by_uid(struct mailfolder * folder,
82 const char * uid, mailmessage ** result)
83{
84 mailmessage * msg;
85 int r;
86
87 r = mailsession_get_message_by_uid(folder->fld_session, uid, &msg);
88 if (r != MAIL_NO_ERROR)
89 return r;
90
91 msg->msg_folder = folder;
92
93 * result = msg;
94
95 return MAIL_NO_ERROR;
96}
diff --git a/kmicromail/libetpan/generic/mailfolder.h b/kmicromail/libetpan/generic/mailfolder.h
new file mode 100644
index 0000000..3ecad23
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailfolder.h
@@ -0,0 +1,32 @@
1#ifndef MAILFOLDER_H
2
3#define MAILFOLDER_H
4
5#include "mailstorage_types.h"
6
7int mailfolder_noop(struct mailfolder * folder);
8
9int mailfolder_check(struct mailfolder * folder);
10
11int mailfolder_expunge(struct mailfolder * folder);
12
13int mailfolder_status(struct mailfolder * folder,
14 uint32_t * result_messages, uint32_t * result_recent,
15 uint32_t * result_unseen);
16
17int mailfolder_append_message(struct mailfolder * folder,
18 char * message, size_t size);
19
20int mailfolder_get_messages_list(struct mailfolder * folder,
21 struct mailmessage_list ** result);
22
23int mailfolder_get_envelopes_list(struct mailfolder * folder,
24 struct mailmessage_list * result);
25
26int mailfolder_get_message(struct mailfolder * folder,
27 uint32_t num, mailmessage ** result);
28
29int mailfolder_get_message_by_uid(struct mailfolder * folder,
30 const char * uid, mailmessage ** result);
31
32#endif
diff --git a/kmicromail/libetpan/generic/mailmessage.c b/kmicromail/libetpan/generic/mailmessage.c
new file mode 100644
index 0000000..9d3884f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage.c
@@ -0,0 +1,240 @@
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 "mailmessage.h"
37
38#include "mail.h"
39
40#include <string.h>
41
42int mailmessage_init(mailmessage * msg_info,
43 mailsession * msg_session,
44 mailmessage_driver * msg_driver,
45 uint32_t msg_index, size_t msg_size)
46{
47 int r;
48 int res;
49
50 msg_info->msg_driver = msg_driver;
51 msg_info->msg_session = msg_session;
52 msg_info->msg_index = msg_index;
53 msg_info->msg_uid = NULL;
54
55 msg_info->msg_cached = FALSE;
56 msg_info->msg_size = msg_size;
57 msg_info->msg_fields = NULL;
58 memset(&msg_info->msg_single_fields, 0,
59 sizeof(struct mailimf_single_fields));
60 msg_info->msg_resolved = FALSE;
61 msg_info->msg_flags = NULL;
62
63 msg_info->msg_mime = NULL;
64 msg_info->msg_data = NULL;
65 msg_info->msg_folder = NULL;
66 msg_info->msg_user_data = NULL;
67
68 if (msg_driver->msg_initialize != NULL) {
69 r = msg_driver->msg_initialize(msg_info);
70 if (r != MAIL_NO_ERROR) {
71 res = r;
72 goto err;
73 }
74 }
75
76 return MAIL_NO_ERROR;
77
78 err:
79 msg_info->msg_driver = NULL;
80 msg_info->msg_session = NULL;
81 return res;
82}
83
84int mailmessage_flush(mailmessage * msg_info)
85{
86 if (msg_info->msg_driver->msg_flush == NULL)
87 return MAIL_ERROR_NOT_IMPLEMENTED;
88
89 msg_info->msg_driver->msg_flush(msg_info);
90
91 return MAIL_NO_ERROR;
92}
93
94int mailmessage_check(mailmessage * msg_info)
95{
96 if (msg_info->msg_driver->msg_check == NULL)
97 return MAIL_ERROR_NOT_IMPLEMENTED;
98
99 msg_info->msg_driver->msg_check(msg_info);
100
101 return MAIL_NO_ERROR;
102}
103
104int mailmessage_fetch_result_free(mailmessage * msg_info,
105 char * msg)
106{
107 if (msg_info->msg_driver->msg_fetch_result_free == NULL)
108 return MAIL_ERROR_NOT_IMPLEMENTED;
109
110 msg_info->msg_driver->msg_fetch_result_free(msg_info, msg);
111
112 return MAIL_NO_ERROR;
113}
114
115int mailmessage_fetch(mailmessage * msg_info,
116 char ** result,
117 size_t * result_len)
118{
119 if (msg_info->msg_driver->msg_fetch == NULL)
120 return MAIL_ERROR_NOT_IMPLEMENTED;
121
122 return msg_info->msg_driver->msg_fetch(msg_info, result, result_len);
123}
124
125int mailmessage_fetch_header(mailmessage * msg_info,
126 char ** result,
127 size_t * result_len)
128{
129 if (msg_info->msg_driver->msg_fetch_header == NULL)
130 return MAIL_ERROR_NOT_IMPLEMENTED;
131
132 return msg_info->msg_driver->msg_fetch_header(msg_info, result, result_len);
133}
134
135int mailmessage_fetch_body(mailmessage * msg_info,
136 char ** result, size_t * result_len)
137{
138 if (msg_info->msg_driver->msg_fetch_body == NULL)
139 return MAIL_ERROR_NOT_IMPLEMENTED;
140
141 return msg_info->msg_driver->msg_fetch_body(msg_info, result, result_len);
142}
143
144int mailmessage_fetch_size(mailmessage * msg_info,
145 size_t * result)
146{
147 if (msg_info->msg_driver->msg_fetch_size == NULL)
148 return MAIL_ERROR_NOT_IMPLEMENTED;
149
150 return msg_info->msg_driver->msg_fetch_size(msg_info, result);
151}
152
153int mailmessage_get_bodystructure(mailmessage * msg_info,
154 struct mailmime ** result)
155{
156 if (msg_info->msg_driver->msg_get_bodystructure == NULL)
157 return MAIL_ERROR_NOT_IMPLEMENTED;
158
159 return msg_info->msg_driver->msg_get_bodystructure(msg_info, result);
160}
161
162int mailmessage_fetch_section(mailmessage * msg_info,
163 struct mailmime * mime,
164 char ** result, size_t * result_len)
165{
166 if (msg_info->msg_driver->msg_fetch_section == NULL)
167 return MAIL_ERROR_NOT_IMPLEMENTED;
168
169 return msg_info->msg_driver->msg_fetch_section(msg_info, mime, result, result_len);
170}
171
172int mailmessage_fetch_section_header(mailmessage * msg_info,
173 struct mailmime * mime,
174 char ** result,
175 size_t * result_len)
176{
177 if (msg_info->msg_driver->msg_fetch_section_header == NULL)
178 return MAIL_ERROR_NOT_IMPLEMENTED;
179
180 return msg_info->msg_driver->msg_fetch_section_header(msg_info, mime,
181 result, result_len);
182}
183
184int mailmessage_fetch_section_mime(mailmessage * msg_info,
185 struct mailmime * mime,
186 char ** result,
187 size_t * result_len)
188{
189 if (msg_info->msg_driver->msg_fetch_section_mime == NULL)
190 return MAIL_ERROR_NOT_IMPLEMENTED;
191
192 return msg_info->msg_driver->msg_fetch_section_mime(msg_info, mime,
193 result, result_len);
194}
195
196int mailmessage_fetch_section_body(mailmessage * msg_info,
197 struct mailmime * mime,
198 char ** result,
199 size_t * result_len)
200{
201 if (msg_info->msg_driver->msg_fetch_section_body == NULL)
202 return MAIL_ERROR_NOT_IMPLEMENTED;
203
204 return msg_info->msg_driver->msg_fetch_section_body(msg_info, mime,
205 result, result_len);
206}
207
208int mailmessage_fetch_envelope(mailmessage * msg_info,
209 struct mailimf_fields ** result)
210{
211 if (msg_info->msg_driver->msg_fetch_envelope == NULL)
212 return MAIL_ERROR_NOT_IMPLEMENTED;
213
214 return msg_info->msg_driver->msg_fetch_envelope(msg_info, result);
215}
216
217int mailmessage_get_flags(mailmessage * msg_info,
218 struct mail_flags ** result)
219{
220 struct mail_flags * dummy;
221
222 if (msg_info->msg_driver->msg_get_flags == NULL)
223 return MAIL_ERROR_NOT_IMPLEMENTED;
224
225 if (result != NULL)
226 return msg_info->msg_driver->msg_get_flags(msg_info, result);
227 else
228 return msg_info->msg_driver->msg_get_flags(msg_info, &dummy);
229}
230
231void mailmessage_resolve_single_fields(mailmessage * msg_info)
232{
233 if (!msg_info->msg_resolved) {
234 if (msg_info->msg_fields != NULL) {
235 mailimf_single_fields_init(&msg_info->msg_single_fields,
236 msg_info->msg_fields);
237 msg_info->msg_resolved = TRUE;
238 }
239 }
240}
diff --git a/kmicromail/libetpan/generic/mailmessage.h b/kmicromail/libetpan/generic/mailmessage.h
new file mode 100644
index 0000000..df9b790
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage.h
@@ -0,0 +1,379 @@
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 <libetpan/mailmessage_types.h>
37
38#ifndef MAILMESSAGE_H
39
40#define MAILMESSAGE_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mailmessage_new
48
49 This function will initializes a new empty message.
50
51 @return a new empty message will be returned.
52*/
53
54mailmessage * mailmessage_new(void);
55
56/*
57 mailmessage_free
58
59 This function will release the memory used by this message.
60*/
61
62void mailmessage_free(mailmessage * info);
63
64/*
65 mailmessage_init
66
67 This function will initializes a mailmessage structure
68 with a message from a given session.
69
70 @param msg_info This is the message to initialize.
71
72 @param session This is the source session of the message. It
73 can be NULL if the message does not get the information
74 through the session.
75
76 @param driver This is the driver to use for the message.
77
78 @param index This is the message number in the session. 0 can
79 be given if the message is not attached to a session.
80
81 @param size is an optional parameter, 0 can be given.
82 This is informational. This is the size of message content.
83
84 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
85 on error
86*/
87
88int mailmessage_init(mailmessage * msg_info,
89 mailsession * session,
90 mailmessage_driver * driver,
91 uint32_t index, size_t size);
92
93/*
94 mailmessage_flush
95
96 This function will release all the temporary resources that are not
97 necessary to use the mailmessage structure from memory. These
98 resources are for example cached information, such as the MIME
99 structure.
100
101 @param info is the message to clean.
102
103 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
104 on error. We can assume that MAIL_NO_ERROR is always returned.
105*/
106
107int mailmessage_flush(mailmessage * info);
108
109/*
110 mailmessage_check
111
112 This function will notify the new value of the flags to the session,
113 it must be called before mailsession_check_folder() in case the flags have
114 been changed.
115
116 @param info is the message to checkpoint.
117
118 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
119 on error. We can assume that MAIL_NO_ERROR is always returned.
120*/
121
122int mailmessage_check(mailmessage * info);
123
124/*
125 mailmessage_fetch_result_free
126
127 This function releases the memory used by a message returned
128 by any of the fetch function that returns a (char *).
129
130 @param msg_info is the message which the given buffer is from.
131
132 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
133 on error. We can assume that MAIL_NO_ERROR is always returned.
134*/
135
136int mailmessage_fetch_result_free(mailmessage * msg_info,
137 char * msg);
138
139/*
140 mailmessage_fetch
141
142 This function returns the content of the message (headers and text).
143
144 @param msg_info is the message from which we want to fetch information.
145
146 @param result The content of the message is returned in (* result)
147
148 @param result_len The length of the returned string is stored
149 in (* result_len).
150
151 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
152 on error.
153*/
154
155int mailmessage_fetch(mailmessage * msg_info,
156 char ** result,
157 size_t * result_len);
158
159/*
160 mailmessage_fetch_header
161
162 This function returns the header of the message as a string.
163
164 @param msg_info is the message from which we want to fetch information.
165
166 @param result The header of the message is returned in (* result)
167
168 @param result_len The length of the returned string is stored
169 in (* result_len).
170
171 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
172 on error.
173*/
174
175int mailmessage_fetch_header(mailmessage * msg_info,
176 char ** result,
177 size_t * result_len);
178
179/*
180 mailmessage_fetch_body
181
182 This function returns the content of the message (without headers).
183
184 @param msg_info is the message from which we want to fetch information.
185 @param result The message text (without headers) is returned
186 in (* result)
187 @param result_len The length of the returned string is stored
188 in (* result_len).
189
190 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
191 on error.
192*/
193
194int mailmessage_fetch_body(mailmessage * msg_info,
195 char ** result, size_t * result_len);
196
197/*
198 mailmessage_fetch_size
199
200 This function returns the size of the message content.
201
202 @param msg_info is the message from which we want to fetch information.
203
204 @param result The length of the message content is stored in (* result).
205
206 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
207 on error.
208*/
209
210int mailmessage_fetch_size(mailmessage * msg_info,
211 size_t * result);
212
213/*
214 mailmessage_get_bodystructure
215
216 This functions returns the MIME structure of the message.
217 The returned information MUST not be freed by hand. It is freed by
218 mailmessage_flush() or mailmessage_free().
219
220 @param msg_info is the message from which we want to fetch information.
221
222 @param result The MIME structure is stored in (* result).
223
224 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
225 on error.
226*/
227
228int mailmessage_get_bodystructure(mailmessage * msg_info,
229 struct mailmime ** result);
230
231/*
232 mailmessage_fetch_section
233
234 This function returns the content of a MIME part.
235
236 @param msg_info is the message from which we want to fetch information.
237
238 @param mime is the MIME part identifier.
239
240 @param result The content is returned in (* result)
241
242 @param result_len The length of the returned string is stored
243 in (* result_len).
244
245 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
246 on error.
247 */
248
249int mailmessage_fetch_section(mailmessage * msg_info,
250 struct mailmime * mime,
251 char ** result, size_t * result_len);
252
253/*
254 mailmessage_fetch_section_header
255
256 This function returns the header of the message contained
257 in the given MIME part.
258
259 @param msg_info is the message from which we want to fetch information.
260
261 @param mime is the MIME part identifier.
262
263 @param result The header is returned in (* result)
264
265 @param result_len The length of the returned string is stored
266 in (* result_len).
267
268 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
269 on error.
270*/
271
272int mailmessage_fetch_section_header(mailmessage * msg_info,
273 struct mailmime * mime,
274 char ** result,
275 size_t * result_len);
276
277/*
278 mailmessage_fetch_section_mime
279
280 This function returns the MIME header of the given MIME part.
281
282 @param msg_info is the message from which we want to fetch information.
283
284 @param mime is the MIME part identifier.
285
286 @param result The MIME header is returned in (* result)
287
288 @param result_len The length of the returned string is stored
289 in (* result_len).
290
291 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
292 on error.
293*/
294
295int mailmessage_fetch_section_mime(mailmessage * msg_info,
296 struct mailmime * mime,
297 char ** result,
298 size_t * result_len);
299
300/*
301 mailmessage_fetch_section_body
302
303 This function returns the text part of the message contained
304 in the given MIME part.
305
306 @param msg_info is the message from which we want to fetch information.
307
308 @param mime is the MIME part identifier.
309
310 @param result The message text is returned in (* result)
311
312 @param result_len The length of the returned string is stored
313 in (* result_len).
314
315 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
316 on error.
317 */
318
319int mailmessage_fetch_section_body(mailmessage * msg_info,
320 struct mailmime * mime,
321 char ** result,
322 size_t * result_len);
323
324/*
325 mailmessage_fetch_envelope
326
327 This function returns a list of parsed fields of the message,
328 chosen by the driver.
329 The returned structure must be freed with mailimf_fields_free().
330
331 @param msg_info is the message from which we want to fetch information.
332
333 @param result The headers list is returned in (* result)
334
335 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
336 on error.
337 */
338
339int mailmessage_fetch_envelope(mailmessage * msg_info,
340 struct mailimf_fields ** result);
341
342
343/*
344 mailmessage_get_flags
345
346 This function returns the flags related to the message.
347 The returned information MUST not be freed by hand. It is freed by
348 mailmessage_free().
349
350 @param msg_info is the message from which we want to fetch information.
351
352 @param result The flags are stored in (* result).
353
354 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
355 on error.
356*/
357
358int mailmessage_get_flags(mailmessage * msg_info,
359 struct mail_flags ** result);
360
361/*
362 mailmessage_resolve_single_fields
363
364 This function will use the fields information to fill the single_fields
365 structure in the mailmessage structure.
366
367 @param msg_info This is the msg_info to process.
368
369 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
370 on error.
371*/
372
373void mailmessage_resolve_single_fields(mailmessage * msg_info);
374
375#ifdef __cplusplus
376}
377#endif
378
379#endif
diff --git a/kmicromail/libetpan/generic/mailmessage_tools.c b/kmicromail/libetpan/generic/mailmessage_tools.c
new file mode 100644
index 0000000..e66f6ba
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_tools.c
@@ -0,0 +1,600 @@
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 "mailmessage_tools.h"
37#include "mailmessage.h"
38
39#include <stdlib.h>
40
41#include "maildriver.h"
42#include "maildriver_tools.h"
43
44int
45mailmessage_generic_initialize(mailmessage * msg_info)
46{
47 struct generic_message_t * msg;
48
49 msg = malloc(sizeof(* msg));
50
51 if (msg == NULL) {
52 return MAIL_ERROR_MEMORY;
53 }
54
55 msg->msg_fetched = 0;
56 msg->msg_message = NULL;
57 msg->msg_length = 0;
58
59 msg->msg_prefetch = NULL;
60 msg->msg_prefetch_free = NULL;
61 msg->msg_data = NULL;
62
63 msg_info->msg_data = msg;
64
65 return MAIL_NO_ERROR;
66}
67
68void mailmessage_generic_flush(mailmessage * msg_info)
69{
70 struct generic_message_t * msg;
71
72 if (msg_info->msg_mime != NULL) {
73 mailmime_free(msg_info->msg_mime);
74 msg_info->msg_mime = NULL;
75 }
76 msg = msg_info->msg_data;
77 if (msg != NULL) {
78 if (msg->msg_prefetch_free != NULL)
79 msg->msg_prefetch_free(msg);
80 msg->msg_fetched = 0;
81 }
82}
83
84void mailmessage_generic_uninitialize(mailmessage * msg_info)
85{
86 struct generic_message_t * msg;
87
88 mailmessage_generic_flush(msg_info);
89
90 msg = msg_info->msg_data;
91 msg_info->msg_data = NULL;
92 free(msg);
93}
94
95static inline int
96mailmessage_generic_prefetch(mailmessage * msg_info)
97{
98 struct generic_message_t * msg;
99 int r;
100
101 msg = msg_info->msg_data;
102
103 if (msg->msg_fetched)
104 return MAIL_NO_ERROR;
105
106#if 0
107 if (msg->message != NULL)
108 return MAIL_NO_ERROR;
109#endif
110
111 r = msg->msg_prefetch(msg_info);
112 if (r != MAIL_NO_ERROR)
113 return r;
114
115 msg->msg_fetched = 1;
116
117 return MAIL_NO_ERROR;
118}
119
120static int
121mailmessage_generic_prefetch_bodystructure(mailmessage * msg_info)
122{
123 size_t length;
124 char * message;
125 size_t cur_token;
126 struct mailmime * mime;
127 int r;
128 int res;
129 struct generic_message_t * msg;
130
131 if (msg_info->msg_mime != NULL) {
132 /* it has already been fetched */
133 return MAIL_NO_ERROR;
134 }
135
136#if 0
137 msg = msg_info->data;
138 if (msg->message == NULL) {
139 r = mailmessage_generic_prefetch(msg_info);
140 if (r != MAIL_NO_ERROR) {
141 res = r;
142 goto err;
143 }
144 }
145#endif
146 r = mailmessage_generic_prefetch(msg_info);
147 if (r != MAIL_NO_ERROR) {
148 res = r;
149 goto err;
150 }
151
152 msg = msg_info->msg_data;
153 message = msg->msg_message;
154 length = msg->msg_length;
155 cur_token = 0;
156 r = mailmime_parse(message, length, &cur_token, &mime);
157 if (r != MAILIMF_NO_ERROR) {
158 res = MAIL_ERROR_PARSE;
159 goto err;
160 }
161
162 msg_info->msg_mime = mime;
163
164 return MAIL_NO_ERROR;
165
166 err:
167 return res;
168}
169
170void
171mailmessage_generic_fetch_result_free(mailmessage * msg_info, char * msg)
172{
173 int r;
174
175 r = mmap_string_unref(msg);
176}
177
178int mailmessage_generic_fetch(mailmessage * msg_info,
179 char ** result,
180 size_t * result_len)
181{
182 int r;
183 char * message;
184 size_t cur_token;
185 size_t length;
186 MMAPString * mmapstr;
187 int res;
188 struct generic_message_t * msg;
189
190 msg = msg_info->msg_data;
191 r = mailmessage_generic_prefetch(msg_info);
192 if (r != MAIL_NO_ERROR) {
193 res = r;
194 goto err;
195 }
196
197 message = msg->msg_message;
198 length = msg->msg_length;
199 cur_token = 0;
200
201 mmapstr = mmap_string_new_len(message, length);
202 if (mmapstr == NULL) {
203 res = MAIL_ERROR_MEMORY;
204 goto err;
205 }
206
207 r = mmap_string_ref(mmapstr);
208 if (r < 0) {
209 res = MAIL_ERROR_MEMORY;
210 goto free_mmap;
211 }
212
213 * result = mmapstr->str;
214 * result_len = length;
215
216 return MAIL_NO_ERROR;
217
218 free_mmap:
219 mmap_string_free(mmapstr);
220 err:
221 return res;
222}
223
224int mailmessage_generic_fetch_header(mailmessage * msg_info,
225 char ** result,
226 size_t * result_len)
227{
228 int r;
229 char * message;
230 size_t cur_token;
231 size_t length;
232 MMAPString * mmapstr;
233 char * headers;
234 int res;
235 struct generic_message_t * msg;
236
237 msg = msg_info->msg_data;
238 r = mailmessage_generic_prefetch(msg_info);
239 if (r != MAIL_NO_ERROR) {
240 res = r;
241 goto err;
242 }
243
244 message = msg->msg_message;
245 length = msg->msg_length;
246 cur_token = 0;
247
248 while (1) {
249 r = mailimf_ignore_field_parse(message, length, &cur_token);
250 if (r == MAILIMF_NO_ERROR) {
251 /* do nothing */
252 }
253 else
254 break;
255 }
256 mailimf_crlf_parse(message, length, &cur_token);
257
258 mmapstr = mmap_string_new_len(message, cur_token);
259 if (mmapstr == NULL) {
260 res = MAIL_ERROR_MEMORY;
261 goto err;
262 }
263
264 r = mmap_string_ref(mmapstr);
265 if (r < 0) {
266 res = MAIL_ERROR_MEMORY;
267 goto free_mmap;
268 }
269
270 headers = mmapstr->str;
271
272 * result = headers;
273 * result_len = cur_token;
274
275 return MAIL_NO_ERROR;
276
277 free_mmap:
278 mmap_string_free(mmapstr);
279 err:
280 return res;
281}
282
283int mailmessage_generic_fetch_body(mailmessage * msg_info,
284 char ** result, size_t * result_len)
285{
286 int r;
287 char * message;
288 size_t cur_token;
289 MMAPString * mmapstr;
290 size_t length;
291 int res;
292 struct generic_message_t * msg;
293
294 msg = msg_info->msg_data;
295 r = mailmessage_generic_prefetch(msg_info);
296 if (r != MAIL_NO_ERROR) {
297 res = r;
298 goto err;
299 }
300
301 message = msg->msg_message;
302 length = msg->msg_length;
303 cur_token = 0;
304
305 while (1) {
306 r = mailimf_ignore_field_parse(message, length, &cur_token);
307 if (r == MAILIMF_NO_ERROR) {
308 /* do nothing */
309 }
310 else
311 break;
312 }
313 mailimf_crlf_parse(message, length, &cur_token);
314
315 mmapstr = mmap_string_new_len(message + cur_token, length - cur_token);
316 if (mmapstr == NULL) {
317 res = MAIL_ERROR_MEMORY;
318 goto err;
319 }
320
321 r = mmap_string_ref(mmapstr);
322 if (r < 0) {
323 res = MAIL_ERROR_MEMORY;
324 goto free_mmap;
325 }
326
327 * result = mmapstr->str;
328 * result_len = length - cur_token;
329
330 return MAIL_NO_ERROR;
331
332 free_mmap:
333 mmap_string_free(mmapstr);
334 err:
335 return res;
336}
337
338
339
340
341int
342mailmessage_generic_get_bodystructure(mailmessage * msg_info,
343 struct mailmime ** result)
344{
345 int r;
346
347 r = mailmessage_generic_prefetch_bodystructure(msg_info);
348 if (r != MAIL_NO_ERROR)
349 return r;
350
351 * result = msg_info->msg_mime;
352
353 return MAIL_NO_ERROR;
354}
355
356
357
358
359int
360mailmessage_generic_fetch_section(mailmessage * msg_info,
361 struct mailmime * mime,
362 char ** result, size_t * result_len)
363{
364 MMAPString * mmapstr;
365 int r;
366 int res;
367
368 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
369 mime->mm_body->dt_data.dt_text.dt_length);
370 if (mmapstr == NULL) {
371 res = MAIL_ERROR_MEMORY;
372 goto err;
373 }
374
375 r = mmap_string_ref(mmapstr);
376 if (r < 0) {
377 res = MAIL_ERROR_MEMORY;
378 goto free_mmap;
379 }
380
381 * result = mmapstr->str;
382 * result_len = mmapstr->len;
383
384 return MAIL_NO_ERROR;
385
386 free_mmap:
387 mmap_string_free(mmapstr);
388 err:
389 return res;
390}
391
392int
393mailmessage_generic_fetch_section_header(mailmessage * msg_info,
394 struct mailmime * mime,
395 char ** result,
396 size_t * result_len)
397{
398 MMAPString * mmapstr;
399 int r;
400 int res;
401 size_t cur_token;
402
403 /* skip mime */
404
405 cur_token = 0;
406
407 if (mime->mm_type == MAILMIME_MESSAGE) {
408
409 while (1) {
410 r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
411 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
412 if (r == MAILIMF_NO_ERROR) {
413 /* do nothing */
414 }
415 else
416 break;
417 }
418
419 r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
420 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
421 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
422 res = maildriver_imf_error_to_mail_error(r);
423 goto err;
424 }
425 }
426
427 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
428 cur_token);
429 if (mmapstr == NULL) {
430 res = MAIL_ERROR_MEMORY;
431 goto err;
432 }
433
434 r = mmap_string_ref(mmapstr);
435 if (r < 0) {
436 res = MAIL_ERROR_MEMORY;
437 goto free_mmap;
438 }
439
440 * result = mmapstr->str;
441 * result_len = mmapstr->len;
442
443 return MAIL_NO_ERROR;
444
445 free_mmap:
446 mmap_string_free(mmapstr);
447 err:
448 return res;
449}
450
451int
452mailmessage_generic_fetch_section_mime(mailmessage * msg_info,
453 struct mailmime * mime,
454 char ** result,
455 size_t * result_len)
456{
457 MMAPString * mmapstr;
458 int r;
459 int res;
460 size_t cur_token;
461
462 cur_token = 0;
463
464 /* skip header */
465
466 while (1) {
467 r = mailimf_ignore_field_parse(mime->mm_mime_start,
468 mime->mm_length, &cur_token);
469 if (r == MAILIMF_NO_ERROR) {
470 /* do nothing */
471 }
472 else
473 break;
474 }
475
476 r = mailimf_crlf_parse(mime->mm_mime_start, mime->mm_length, &cur_token);
477 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
478 res = maildriver_imf_error_to_mail_error(r);
479 goto err;
480 }
481
482 mmapstr = mmap_string_new_len(mime->mm_mime_start, cur_token);
483 if (mmapstr == NULL) {
484 res = MAIL_ERROR_MEMORY;
485 goto err;
486 }
487
488 r = mmap_string_ref(mmapstr);
489 if (r < 0) {
490 res = MAIL_ERROR_MEMORY;
491 goto free_mmap;
492 }
493
494 * result = mmapstr->str;
495 * result_len = mmapstr->len;
496
497 return MAIL_NO_ERROR;
498
499 free_mmap:
500 mmap_string_free(mmapstr);
501 err:
502 return res;
503}
504
505int
506mailmessage_generic_fetch_section_body(mailmessage * msg_info,
507 struct mailmime * mime,
508 char ** result,
509 size_t * result_len)
510{
511 MMAPString * mmapstr;
512 int r;
513 int res;
514 size_t cur_token;
515
516 cur_token = 0;
517
518 if (mime->mm_type == MAILMIME_MESSAGE) {
519
520 /* skip header */
521
522 while (1) {
523 r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
524 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
525 if (r == MAILIMF_NO_ERROR) {
526 /* do nothing */
527 }
528 else
529 break;
530 }
531
532 r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
533 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
534 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
535 res = maildriver_imf_error_to_mail_error(r);
536 goto err;
537 }
538 }
539
540 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data +
541 cur_token, mime->mm_body->dt_data.dt_text.dt_length - cur_token);
542 if (mmapstr == NULL) {
543 res = MAIL_ERROR_MEMORY;
544 goto err;
545 }
546
547 r = mmap_string_ref(mmapstr);
548 if (r < 0) {
549 res = MAIL_ERROR_MEMORY;
550 goto free_mmap;
551 }
552
553 * result = mmapstr->str;
554 * result_len = mmapstr->len;
555
556 return MAIL_NO_ERROR;
557
558 free_mmap:
559 mmap_string_free(mmapstr);
560 err:
561 return res;
562}
563
564int mailmessage_generic_fetch_envelope(mailmessage * msg_info,
565 struct mailimf_fields ** result)
566{
567 int r;
568 int res;
569 size_t cur_token;
570 char * header;
571 size_t length;
572 struct mailimf_fields * fields;
573
574 r = mailmessage_fetch_header(msg_info, &header, &length);
575 if (r != MAIL_NO_ERROR) {
576 res = r;
577 goto err;
578 }
579
580 cur_token = 0;
581
582 r = mailimf_envelope_fields_parse(header, length, &cur_token,
583 &fields);
584 if (r != MAILIMF_NO_ERROR) {
585 res = maildriver_imf_error_to_mail_error(r);
586 goto free;
587 /* do nothing */
588 }
589
590 mailmessage_fetch_result_free(msg_info, header);
591
592 * result = fields;
593
594 return MAIL_NO_ERROR;
595
596 free:
597 mailmessage_fetch_result_free(msg_info, header);
598 err:
599 return res;
600}
diff --git a/kmicromail/libetpan/generic/mailmessage_tools.h b/kmicromail/libetpan/generic/mailmessage_tools.h
new file mode 100644
index 0000000..a4f9b1e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_tools.h
@@ -0,0 +1,103 @@
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#ifndef MAILMESSAGE_TOOLS_H
37
38#define MAILMESSAGE_TOOLS_H
39
40#include "mailmessage_types.h"
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46int
47mailmessage_generic_initialize(mailmessage *
48 msg_info);
49
50void mailmessage_generic_uninitialize(mailmessage *
51 msg_info);
52
53void mailmessage_generic_flush(mailmessage * msg_info);
54
55void mailmessage_generic_fetch_result_free(mailmessage * msg_info,
56 char * msg);
57
58int mailmessage_generic_fetch(mailmessage * msg_info,
59 char ** result,
60 size_t * result_len);
61
62int mailmessage_generic_fetch_header(mailmessage * msg_info,
63 char ** result,
64 size_t * result_len);
65
66int mailmessage_generic_fetch_body(mailmessage * msg_info,
67 char ** result, size_t * result_len);
68
69int mailmessage_generic_get_bodystructure(mailmessage *
70 msg_info,
71 struct mailmime ** result);
72
73int
74mailmessage_generic_fetch_section(mailmessage * msg_info,
75 struct mailmime * mime,
76 char ** result, size_t * result_len);
77
78int
79mailmessage_generic_fetch_section_header(mailmessage * msg_info,
80 struct mailmime * mime,
81 char ** result,
82 size_t * result_len);
83
84int
85mailmessage_generic_fetch_section_mime(mailmessage * msg_info,
86 struct mailmime * mime,
87 char ** result,
88 size_t * result_len);
89
90int
91mailmessage_generic_fetch_section_body(mailmessage * msg_info,
92 struct mailmime * mime,
93 char ** result,
94 size_t * result_len);
95
96int mailmessage_generic_fetch_envelope(mailmessage * msg_info,
97 struct mailimf_fields ** result);
98
99#ifdef __cplusplus
100}
101#endif
102
103#endif
diff --git a/kmicromail/libetpan/generic/mailmessage_types.c b/kmicromail/libetpan/generic/mailmessage_types.c
new file mode 100644
index 0000000..9f8c355
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_types.c
@@ -0,0 +1,92 @@
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 "mailmessage_types.h"
37
38#include "mail.h"
39
40#include <stdlib.h>
41#include <string.h>
42
43mailmessage * mailmessage_new(void)
44{
45 mailmessage * msg_info;
46
47 msg_info = malloc(sizeof(* msg_info));
48 if (msg_info == NULL)
49 goto err;
50
51 msg_info->msg_driver = NULL;
52 msg_info->msg_session = NULL;
53 msg_info->msg_index = 0;
54 msg_info->msg_uid = NULL;
55
56 msg_info->msg_cached = FALSE;
57 msg_info->msg_size = 0;
58 msg_info->msg_fields = NULL;
59 memset(&msg_info->msg_single_fields,
60 0, sizeof(struct mailimf_single_fields));
61 msg_info->msg_resolved = FALSE;
62 msg_info->msg_flags = NULL;
63
64 msg_info->msg_mime = NULL;
65 msg_info->msg_data = NULL;
66
67 msg_info->msg_folder = NULL;
68 msg_info->msg_user_data = NULL;
69
70 return msg_info;
71
72 err:
73 return NULL;
74}
75
76void mailmessage_free(mailmessage * msg_info)
77{
78 if (msg_info->msg_driver != NULL) {
79 if (msg_info->msg_driver->msg_uninitialize != NULL)
80 msg_info->msg_driver->msg_uninitialize(msg_info);
81 }
82
83 if (msg_info->msg_fields != NULL)
84 mailimf_fields_free(msg_info->msg_fields);
85 if (msg_info->msg_mime != NULL)
86 mailmime_free(msg_info->msg_mime);
87 if (msg_info->msg_flags != NULL)
88 mail_flags_free(msg_info->msg_flags);
89 if (msg_info->msg_uid != NULL)
90 free(msg_info->msg_uid);
91 free(msg_info);
92}
diff --git a/kmicromail/libetpan/generic/mailmessage_types.h b/kmicromail/libetpan/generic/mailmessage_types.h
new file mode 100644
index 0000000..655ed2c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_types.h
@@ -0,0 +1,50 @@
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#ifndef MAILMESSAGE_TYPES_H
37
38#define MAILMESSAGE_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46#ifdef __cplusplus
47}
48#endif
49
50#endif
diff --git a/kmicromail/libetpan/generic/mailstorage.c b/kmicromail/libetpan/generic/mailstorage.c
new file mode 100644
index 0000000..25e561e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage.c
@@ -0,0 +1,334 @@
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 "mailstorage.h"
37
38#include "maildriver.h"
39
40#include <stdlib.h>
41#include <string.h>
42
43static int mailstorage_get_folder(struct mailstorage * storage,
44 char * pathname, mailsession ** result);
45
46struct mailfolder * mailfolder_new(struct mailstorage * storage,
47 char * pathname, char * virtual_name)
48{
49 struct mailfolder * folder;
50
51 folder = malloc(sizeof(struct mailfolder));
52 if (folder == NULL)
53 goto err;
54
55 if (pathname != NULL) {
56 folder->fld_pathname = strdup(pathname);
57 if (folder->fld_pathname == NULL)
58 goto free;
59 }
60 else
61 folder->fld_pathname = NULL;
62
63 if (virtual_name != NULL) {
64 folder->fld_virtual_name = strdup(virtual_name);
65 if (folder->fld_virtual_name == NULL)
66 goto free_pathname;
67 }
68 else
69 folder->fld_virtual_name = NULL;
70
71 folder->fld_storage = storage;
72
73 folder->fld_session = NULL;
74 folder->fld_shared_session = 0;
75 folder->fld_pos = NULL;
76
77 folder->fld_parent = NULL;
78 folder->fld_sibling_index = 0;
79 folder->fld_children = carray_new(128);
80 if (folder->fld_children == NULL)
81 goto free_virtualname;
82
83 return folder;
84
85free_virtualname:
86 if (folder->fld_virtual_name != NULL)
87 free(folder->fld_virtual_name);
88free_pathname:
89 if (folder->fld_pathname != NULL)
90 free(folder->fld_pathname);
91free:
92 free(folder);
93err:
94 return NULL;
95}
96
97void mailfolder_free(struct mailfolder * folder)
98{
99 if (folder->fld_parent != NULL)
100 mailfolder_detach_parent(folder);
101
102 while (carray_count(folder->fld_children) > 0) {
103 struct mailfolder * child;
104
105 child = carray_get(folder->fld_children, 0);
106 mailfolder_detach_parent(child);
107 }
108
109 carray_free(folder->fld_children);
110
111 if (folder->fld_session != NULL)
112 mailfolder_disconnect(folder);
113
114 if (folder->fld_virtual_name != NULL)
115 free(folder->fld_virtual_name);
116 if (folder->fld_pathname != NULL)
117 free(folder->fld_pathname);
118 free(folder);
119}
120
121int mailfolder_connect(struct mailfolder * folder)
122{
123 mailsession * session;
124 int res;
125 int r;
126
127 if (folder->fld_storage == NULL) {
128 res = MAIL_ERROR_INVAL;
129 goto err;
130 }
131
132 if (folder->fld_storage->sto_session == NULL) {
133 r = mailstorage_connect(folder->fld_storage);
134 if (r != MAIL_NO_ERROR) {
135 res = r;
136 goto err;
137 }
138 }
139
140 if (folder->fld_session != NULL) {
141 if ((folder->fld_pathname != NULL) && (folder->fld_shared_session)) {
142 if (folder->fld_session->sess_driver->sess_select_folder != NULL) {
143 r = mailsession_select_folder(folder->fld_session,
144 folder->fld_pathname);
145 if (r != MAIL_NO_ERROR) {
146 res = r;
147 goto err;
148 }
149 }
150 }
151
152 return MAIL_NO_ERROR;
153 }
154
155 r = mailstorage_get_folder(folder->fld_storage, folder->fld_pathname,
156 &session);
157 if (r != MAIL_NO_ERROR) {
158 res = r;
159 goto err;
160 }
161 folder->fld_session = session;
162 folder->fld_shared_session = (session == folder->fld_storage->sto_session);
163 if (folder->fld_shared_session) {
164 r = clist_append(folder->fld_storage->sto_shared_folders, folder);
165 if (r < 0) {
166 folder->fld_session = NULL;
167 res = MAIL_ERROR_MEMORY;
168 goto err;
169 }
170 folder->fld_pos = clist_end(folder->fld_storage->sto_shared_folders);
171 }
172
173 return MAIL_NO_ERROR;
174
175err:
176 return res;
177}
178
179void mailfolder_disconnect(struct mailfolder * folder)
180{
181 if (folder->fld_session == NULL)
182 return;
183
184 if (folder->fld_shared_session) {
185 clist_delete(folder->fld_storage->sto_shared_folders, folder->fld_pos);
186 folder->fld_pos = NULL;
187 }
188 else {
189 mailsession_logout(folder->fld_session);
190 mailsession_free(folder->fld_session);
191 }
192
193 folder->fld_session = NULL;
194}
195
196int mailfolder_add_child(struct mailfolder * parent,
197 struct mailfolder * child)
198{
199 unsigned int index;
200 int r;
201
202 r = carray_add(parent->fld_children, child, &index);
203 if (r < 0)
204 return MAIL_ERROR_MEMORY;
205
206 child->fld_sibling_index = index;
207 child->fld_parent = parent;
208
209 return MAIL_NO_ERROR;
210}
211
212int mailfolder_detach_parent(struct mailfolder * folder)
213{
214 unsigned int i;
215 int r;
216
217 if (folder->fld_parent == NULL)
218 return MAIL_ERROR_INVAL;
219
220 r = carray_delete_slow(folder->fld_parent->fld_children,
221 folder->fld_sibling_index);
222 if (r < 0)
223 return MAIL_ERROR_INVAL;
224
225 for(i = 0 ; i < carray_count(folder->fld_parent->fld_children) ; i ++) {
226 struct mailfolder * child;
227
228 child = carray_get(folder->fld_parent->fld_children, i);
229 child->fld_sibling_index = i;
230 }
231
232 folder->fld_parent = NULL;
233 folder->fld_sibling_index = 0;
234
235 return MAIL_NO_ERROR;
236}
237
238struct mailstorage * mailstorage_new(char * sto_id)
239{
240 struct mailstorage * storage;
241
242 storage = malloc(sizeof(struct mailstorage));
243 if (storage == NULL)
244 goto err;
245
246 if (sto_id != NULL) {
247 storage->sto_id = strdup(sto_id);
248 if (storage->sto_id == NULL)
249 goto free;
250 }
251 else
252 storage->sto_id = NULL;
253
254 storage->sto_data = NULL;
255 storage->sto_session = NULL;
256 storage->sto_driver = NULL;
257 storage->sto_shared_folders = clist_new();
258 if (storage->sto_shared_folders == NULL)
259 goto free_id;
260
261 return storage;
262
263 free_id:
264 if (storage->sto_id != NULL)
265 free(storage->sto_id);
266 free:
267 free(storage);
268 err:
269 return NULL;
270}
271
272void mailstorage_free(struct mailstorage * storage)
273{
274 if (storage->sto_session != NULL)
275 mailstorage_disconnect(storage);
276
277 if (storage->sto_driver != NULL) {
278 if (storage->sto_driver->sto_uninitialize != NULL)
279 storage->sto_driver->sto_uninitialize(storage);
280 }
281
282 clist_free(storage->sto_shared_folders);
283
284 if (storage->sto_id != NULL)
285 free(storage->sto_id);
286
287 free(storage);
288}
289
290int mailstorage_connect(struct mailstorage * storage)
291{
292 if (storage->sto_session != NULL)
293 return MAIL_NO_ERROR;
294
295 if (!clist_isempty(storage->sto_shared_folders))
296 return MAIL_ERROR_BAD_STATE;
297
298 if (storage->sto_driver->sto_connect == NULL)
299 return MAIL_ERROR_NOT_IMPLEMENTED;
300
301 return storage->sto_driver->sto_connect(storage);
302}
303
304
305void mailstorage_disconnect(struct mailstorage * storage)
306{
307 int r;
308 clistiter * cur;
309
310 while ((cur = clist_begin(storage->sto_shared_folders)) != NULL) {
311 struct mailfolder * folder;
312
313 folder = cur->data;
314 mailfolder_disconnect(folder);
315 }
316
317 if (storage->sto_session == NULL)
318 return;
319
320 r = mailsession_logout(storage->sto_session);
321
322 mailsession_free(storage->sto_session);
323 storage->sto_session = NULL;
324}
325
326static int mailstorage_get_folder(struct mailstorage * storage,
327 char * pathname, mailsession ** result)
328{
329 if (storage->sto_driver->sto_get_folder_session == NULL)
330 return MAIL_ERROR_NOT_IMPLEMENTED;
331
332 return storage->sto_driver->sto_get_folder_session(storage,
333 pathname, result);
334}
diff --git a/kmicromail/libetpan/generic/mailstorage.h b/kmicromail/libetpan/generic/mailstorage.h
new file mode 100644
index 0000000..d56aef1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage.h
@@ -0,0 +1,98 @@
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#ifndef MAIL_STORAGE_H
37
38#define MAIL_STORAGE_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/mailstorage_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* storage */
48
49/*
50 mailstorage_new
51
52 This function creates an empty storage. This storage have to be initialized.
53 The "driver" and "data" fields should be initialized.
54
55 @param id is the name of the storage. It can be NULL.
56 The given parameter is no more needed when the creation is finished.
57 The given string is duplicated.
58
59 @return The mail storage is returned.
60*/
61
62struct mailstorage * mailstorage_new(char * sto_id);
63
64void mailstorage_free(struct mailstorage * storage);
65
66/*
67 session will be initialized on success.
68*/
69
70int mailstorage_connect(struct mailstorage * storage);
71
72void mailstorage_disconnect(struct mailstorage * storage);
73
74
75/* folder */
76
77struct mailfolder * mailfolder_new(struct mailstorage * fld_storage,
78 char * fld_pathname, char * fld_virtual_name);
79
80void mailfolder_free(struct mailfolder * folder);
81
82int mailfolder_add_child(struct mailfolder * parent,
83 struct mailfolder * child);
84
85int mailfolder_detach_parent(struct mailfolder * folder);
86
87int mailfolder_connect(struct mailfolder * folder);
88
89void mailfolder_disconnect(struct mailfolder * folder);
90
91
92#ifdef __cplusplus
93}
94#endif
95
96#endif
97
98
diff --git a/kmicromail/libetpan/generic/mailstorage_tools.c b/kmicromail/libetpan/generic/mailstorage_tools.c
new file mode 100644
index 0000000..92e2657
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage_tools.c
@@ -0,0 +1,372 @@
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 "mailstorage_tools.h"
37
38#include "libetpan-config.h"
39
40#include <sys/types.h>
41#include <netdb.h>
42#include <netinet/in.h>
43#include <sys/socket.h>
44#include <unistd.h>
45#include <stdlib.h>
46#include <sys/wait.h>
47#include <sys/ioctl.h>
48#include <fcntl.h>
49#include <string.h>
50
51#include "mail.h"
52#include "mailmessage.h"
53#include "maildriver.h"
54
55/* tools */
56
57/* connection to TCP/IP server */
58
59static int tcp_connect(char * server, uint16_t port)
60{
61 struct hostent * remotehost;
62 struct sockaddr_in sa;
63 int s;
64 int r;
65
66 s = socket(PF_INET, SOCK_STREAM, 0);
67 if (s == -1)
68 goto err;
69
70 remotehost = gethostbyname(server);
71 if (remotehost == NULL)
72 goto close_socket;
73
74 sa.sin_family = AF_INET;
75 sa.sin_port = htons(port);
76 memcpy(&sa.sin_addr, remotehost->h_addr, remotehost->h_length);
77
78 r = connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
79 if (r == -1)
80 goto close_socket;
81
82 return s;
83
84 close_socket:
85 close(s);
86 err:
87 return -1;
88}
89
90
91/* connection through a shell command */
92
93static void do_exec_command(int fd, const char *command,
94 char *servername, uint16_t port)
95{
96 int i, maxopen;
97
98 if (fork() > 0) {
99 /* Fork again to become a child of init rather than
100 the etpan client. */
101 exit(0);
102 }
103
104 if (servername)
105 setenv("ETPANSERVER", servername, 1);
106 else
107 unsetenv("ETPANSERVER");
108
109 if (port) {
110 char porttext[20];
111
112 snprintf(porttext, sizeof(porttext), "%d", port);
113 setenv("ETPANPORT", porttext, 1);
114 }
115 else {
116 unsetenv("ETPANPORT");
117 }
118
119 /* Not a lot we can do if there's an error other than bail. */
120 if (dup2(fd, 0) == -1)
121 exit(1);
122 if (dup2(fd, 1) == -1)
123 exit(1);
124
125 /* Should we close stderr and reopen /dev/null? */
126
127 maxopen = sysconf(_SC_OPEN_MAX);
128 for (i=3; i < maxopen; i++)
129 close(i);
130
131#ifdef TIOCNOTTY
132 /* Detach from the controlling tty if we have one. Otherwise,
133 SSH might do something stupid like trying to use it instead
134 of running $SSH_ASKPASS. Doh. */
135 fd = open("/dev/tty", O_RDONLY);
136 if (fd != -1) {
137 ioctl(fd, TIOCNOTTY, NULL);
138 close(fd);
139 }
140#endif /* TIOCNOTTY */
141
142 execl("/bin/sh", "/bin/sh", "-c", command, NULL);
143
144 /* Eep. Shouldn't reach this */
145 exit(1);
146}
147
148static int subcommand_connect(char *command, char *servername, uint16_t port)
149{
150 int sockfds[2];
151 pid_t childpid;
152
153 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds))
154 return -1;
155
156 childpid = fork();
157 if (!childpid) {
158 do_exec_command(sockfds[1], command, servername, port);
159 }
160 else if (childpid == -1) {
161 close(sockfds[0]);
162 close(sockfds[1]);
163 return -1;
164 }
165
166 close(sockfds[1]);
167
168 /* Reap child, leaving grandchild process to run */
169 waitpid(childpid, NULL, 0);
170
171 return sockfds[0];
172}
173
174int mailstorage_generic_connect(mailsession_driver * driver,
175 char * servername,
176 uint16_t port,
177 char * command,
178 int connection_type,
179 int cache_function_id,
180 char * cache_directory,
181 int flags_function_id,
182 char * flags_directory,
183 mailsession ** result)
184{
185 int r;
186 int res;
187 mailstream * stream;
188 int fd;
189 mailsession * session;
190 int connect_result;
191
192 switch (connection_type) {
193 case CONNECTION_TYPE_PLAIN:
194 case CONNECTION_TYPE_TRY_STARTTLS:
195 case CONNECTION_TYPE_STARTTLS:
196 case CONNECTION_TYPE_TLS:
197 fd = tcp_connect(servername, port);
198 if (fd == -1) {
199 res = MAIL_ERROR_CONNECT;
200 goto err;
201 }
202 break;
203
204 case CONNECTION_TYPE_COMMAND:
205 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
206 case CONNECTION_TYPE_COMMAND_STARTTLS:
207 case CONNECTION_TYPE_COMMAND_TLS:
208 fd = subcommand_connect(command, servername, port);
209 break;
210
211 default:
212 fd = -1;
213 break;
214 }
215
216 if (fd == -1) {
217 res = MAIL_ERROR_INVAL;
218 goto err;
219 }
220
221 switch (connection_type) {
222 case CONNECTION_TYPE_PLAIN:
223 case CONNECTION_TYPE_TRY_STARTTLS:
224 case CONNECTION_TYPE_STARTTLS:
225 case CONNECTION_TYPE_COMMAND:
226 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
227 case CONNECTION_TYPE_COMMAND_STARTTLS:
228 stream = mailstream_socket_open(fd);
229 break;
230
231 case CONNECTION_TYPE_TLS:
232 case CONNECTION_TYPE_COMMAND_TLS:
233 stream = mailstream_ssl_open(fd);
234 break;
235
236 default:
237 stream = NULL;
238 break;
239 }
240
241 if (stream == NULL) {
242 res = MAIL_ERROR_STREAM;
243 close(fd);
244 goto err;
245 }
246
247 session = mailsession_new(driver);
248 if (session == NULL) {
249 res = MAIL_ERROR_MEMORY;
250 goto close_stream;
251 }
252
253 if (cache_directory != NULL) {
254 char cache_directory_server[PATH_MAX];
255
256 snprintf(cache_directory_server, PATH_MAX, "%s/%s",
257 cache_directory, servername);
258
259 r = mailsession_parameters(session,
260 cache_function_id,
261 cache_directory_server);
262 if (r != MAIL_NO_ERROR) {
263 res = r;
264 goto close_stream;
265 }
266 }
267
268 if (flags_directory != NULL) {
269 char flags_directory_server[PATH_MAX];
270
271 snprintf(flags_directory_server, PATH_MAX, "%s/%s",
272 flags_directory, servername);
273
274 r = mailsession_parameters(session,
275 flags_function_id,
276 flags_directory_server);
277 if (r != MAIL_NO_ERROR) {
278 res = r;
279 goto close_stream;
280 }
281 }
282
283 r = mailsession_connect_stream(session, stream);
284 switch (r) {
285 case MAIL_NO_ERROR_NON_AUTHENTICATED:
286 case MAIL_NO_ERROR_AUTHENTICATED:
287 case MAIL_NO_ERROR:
288 break;
289 default:
290 res = r;
291 goto free;
292 }
293
294 connect_result = r;
295
296 switch (connection_type) {
297 case CONNECTION_TYPE_TRY_STARTTLS:
298 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
299 r = mailsession_starttls(session);
300 if ((r != MAIL_NO_ERROR) && (r != MAIL_ERROR_NO_TLS)) {
301 res = r;
302 goto free;
303 }
304 break;
305
306 case CONNECTION_TYPE_STARTTLS:
307 case CONNECTION_TYPE_COMMAND_STARTTLS:
308 r = mailsession_starttls(session);
309 if (r != MAIL_NO_ERROR) {
310 res = r;
311 goto free;
312 }
313 }
314
315 * result = session;
316
317 return connect_result;
318
319 close_stream:
320 mailstream_close(stream);
321 free:
322 mailsession_free(session);
323 err:
324 return res;
325}
326
327
328
329
330
331int mailstorage_generic_auth(mailsession * session,
332 int connect_result,
333 int auth_type,
334 char * login,
335 char * password)
336{
337 int must_auth;
338 int r;
339 int res;
340
341 r = connect_result;
342
343 must_auth = FALSE;
344 switch (r) {
345 case MAIL_NO_ERROR_NON_AUTHENTICATED:
346 must_auth = TRUE;
347 break;
348 case MAIL_NO_ERROR_AUTHENTICATED:
349 case MAIL_NO_ERROR:
350 break;
351 default:
352 res = r;
353 goto err;
354 }
355
356 if ((login == NULL) || (password == NULL))
357 must_auth = FALSE;
358
359 if (must_auth) {
360 r = mailsession_login(session, login, password);
361 if (r != MAIL_NO_ERROR) {
362 mailsession_logout(session);
363 res = r;
364 goto err;
365 }
366 }
367
368 return MAIL_NO_ERROR;
369
370 err:
371 return res;
372}
diff --git a/kmicromail/libetpan/generic/mailstorage_tools.h b/kmicromail/libetpan/generic/mailstorage_tools.h
new file mode 100644
index 0000000..280b214
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage_tools.h
@@ -0,0 +1,67 @@
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 "mailstorage.h"
37
38#ifndef MAILSTORAGE_TOOLS_H
39
40#define MAILSTORAGE_TOOLS_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46int mailstorage_generic_connect(mailsession_driver * driver,
47 char * servername,
48 uint16_t port,
49 char * command,
50 int connection_type,
51 int cache_function_id,
52 char * cache_directory,
53 int flags_function_id,
54 char * flags_directory,
55 mailsession ** result);
56
57int mailstorage_generic_auth(mailsession * session,
58 int connect_result,
59 int auth_type,
60 char * login,
61 char * password);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/kmicromail/libetpan/generic/mailstorage_types.h b/kmicromail/libetpan/generic/mailstorage_types.h
new file mode 100644
index 0000000..5e08f80
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage_types.h
@@ -0,0 +1,203 @@
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#ifndef MAILSTORAGE_TYPES_H
37
38#define MAILSTORAGE_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46struct mailstorage;
47
48typedef struct mailstorage_driver mailstorage_driver;
49
50
51/*
52 There is three kinds of identities :
53 - storage
54 - folders
55 - session
56
57 A storage (struct mailstorage) represents whether a server or
58 a main path,
59
60 A storage can be an IMAP server, the root path of a MH or a mbox file.
61
62 Folders (struct mailfolder) are the mailboxes we can
63 choose in the server or as sub-folder of the main path.
64
65 Folders for IMAP are the IMAP mailboxes, for MH this is one of the
66 folder of the MH storage, for mbox, there is only one folder, the
67 mbox file content;
68
69 A mail session (struct mailsession) is whether a connection to a server
70 or a path that is open. It is the abstraction lower folders and storage.
71 It allow us to send commands.
72
73 We have a session driver for mail session for each kind of storage.
74
75 From a session, we can get a message (struct mailmessage) to read.
76 We have a message driver for each kind of storage.
77*/
78
79/*
80 mailstorage_driver is the driver structure for mail storages
81
82 - name is the name of the driver
83
84 - connect() connects the storage to the remote access or to
85 the path in the local filesystem.
86
87 - get_folder() can have two kinds of behaviour.
88 Either it creates a new session and independant from the session
89 used by the storage and select the given mailbox or
90 it selects the given mailbox in the current session.
91 It depends on the efficiency of the mail driver.
92
93 - uninitialize() frees the data created with mailstorage constructor.
94*/
95
96struct mailstorage_driver {
97 char * sto_name;
98 int (* sto_connect)(struct mailstorage * storage);
99 int (* sto_get_folder_session)(struct mailstorage * storage,
100 char * pathname, mailsession ** result);
101 void (* sto_uninitialize)(struct mailstorage * storage);
102};
103
104/*
105 mailstorage is the data structure for a storage
106
107 - id is the name of the storage, it can be NULL.
108
109 - data is the data specific to the driver.
110 This is the internal state of the storage.
111
112 - session is the session related to the storage.
113
114 - driver is the driver for the storage.
115
116 - shared_folders is the list of folders returned by the storage.
117*/
118
119struct mailstorage {
120 char * sto_id;
121 void * sto_data;
122 mailsession * sto_session;
123 mailstorage_driver * sto_driver;
124 clist * sto_shared_folders; /* list of (struct mailfolder *) */
125
126 void * sto_user_data;
127};
128
129
130
131/*
132 mailfolder is the data structure for a mailbox
133
134 - pathname is the path of the mailbox on the storage
135
136 - virtual_name is the folder identifier, it can be a path,
137 a name or NULL.
138
139 - storage is the storage to which the folder belongs to.
140
141 - session is the session related to the folder. It can be
142 different of the session of the storage.
143
144 - shared_session is != 0 if the session is the same as the
145 session of the storage.
146
147 - pos is the position of the folder in the "shared_folders" field
148 of the storage.
149
150 folders can be chained into a tree.
151
152 - parent is the parent of the folder.
153
154 - sibling_index is the index of the folder in the list of children
155 of the parent.
156
157 - children is the folder.
158*/
159
160struct mailfolder {
161 char * fld_pathname;
162 char * fld_virtual_name;
163
164 struct mailstorage * fld_storage;
165
166 mailsession * fld_session;
167 int fld_shared_session;
168 clistiter * fld_pos;
169
170 struct mailfolder * fld_parent;
171 unsigned int fld_sibling_index;
172 carray * fld_children; /* array of (struct mailfolder *) */
173
174 void * fld_user_data;
175};
176
177/*
178 this is the type of socket connection
179*/
180
181enum {
182 CONNECTION_TYPE_PLAIN, /* when the connection is plain text */
183 CONNECTION_TYPE_STARTTLS, /* when the connection is first plain,
184 then, we want to switch to
185 TLS (secure connection) */
186 CONNECTION_TYPE_TRY_STARTTLS, /* the connection is first plain,
187 then, we will try to switch to TLS */
188 CONNECTION_TYPE_TLS, /* the connection is over TLS */
189 CONNECTION_TYPE_COMMAND, /* the connection is over a shell command */
190 CONNECTION_TYPE_COMMAND_STARTTLS, /* the connection is over a shell
191 command and STARTTLS will be used */
192 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, /* the connection is over
193 a shell command and STARTTLS will
194 be tried */
195 CONNECTION_TYPE_COMMAND_TLS, /* the connection is over a shell
196 command in TLS */
197};
198
199#ifdef __cplusplus
200}
201#endif
202
203#endif
diff --git a/kmicromail/libetpan/generic/mailthread.c b/kmicromail/libetpan/generic/mailthread.c
new file mode 100644
index 0000000..1dca70d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread.c
@@ -0,0 +1,1631 @@
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 "mailthread.h"
37#include "mailthread_types.h"
38
39#include <string.h>
40#include <time.h>
41#include <stdlib.h>
42#include <ctype.h>
43
44#include "mail.h"
45#include "chash.h"
46#include "carray.h"
47#include "clist.h"
48#include "mailmessage.h"
49
50static inline char * get_msg_id(mailmessage * msg)
51{
52 if (msg->msg_single_fields.fld_message_id != NULL)
53 return msg->msg_single_fields.fld_message_id->mid_value;
54 else
55 return NULL;
56}
57
58static inline clist * get_ref(mailmessage * msg)
59{
60 if (msg->msg_single_fields.fld_references != NULL)
61 return msg->msg_single_fields.fld_references->mid_list;
62 else
63 return NULL;
64}
65
66static inline clist * get_in_reply_to(mailmessage * msg)
67{
68 if (msg->msg_single_fields.fld_in_reply_to != NULL)
69 return msg->msg_single_fields.fld_in_reply_to->mid_list;
70 else
71 return NULL;
72}
73
74static inline int skip_subj_blob(char * subj, size_t * begin,
75 size_t length)
76{
77 /* subj-blob = "[" *BLOBCHAR "]" *WSP */
78 size_t cur_token;
79
80 cur_token = * begin;
81
82 if (subj[cur_token] != '[')
83 return FALSE;
84
85 cur_token ++;
86
87 while (1) {
88 if (cur_token >= length)
89 return FALSE;
90
91 if (subj[cur_token] == '[')
92 return FALSE;
93
94 if (subj[cur_token] == ']')
95 break;
96
97 cur_token ++;
98 }
99
100 cur_token ++;
101
102 while (1) {
103 if (cur_token >= length)
104 break;
105
106 if (subj[cur_token] != ' ')
107 break;
108
109 cur_token ++;
110 }
111
112 * begin = cur_token;
113
114 return TRUE;
115}
116
117static inline int skip_subj_refwd(char * subj, size_t * begin,
118 size_t length)
119{
120 /* subj-refwd = ("re" / ("fw" ["d"])) *WSP [subj-blob] ":" */
121 size_t cur_token;
122 int prefix;
123
124 cur_token = * begin;
125
126 prefix = FALSE;
127 if (length >= 3) {
128 if (strncasecmp(subj + cur_token, "fwd", 3) == 0) {
129 cur_token += 3;
130 prefix = TRUE;
131 }
132 }
133 if (!prefix) {
134 if (length >= 2) {
135 if (strncasecmp(subj + cur_token, "fw", 2) == 0) {
136 cur_token += 2;
137 prefix = TRUE;
138 }
139 else if (strncasecmp(subj + cur_token, "re", 2) == 0) {
140 cur_token += 2;
141 prefix = TRUE;
142 }
143 }
144 }
145
146 if (!prefix)
147 return FALSE;
148
149 while (1) {
150 if (cur_token >= length)
151 break;
152
153 if (subj[cur_token] != ' ')
154 break;
155
156 cur_token ++;
157 }
158
159 skip_subj_blob(subj, &cur_token, length);
160
161 if (subj[cur_token] != ':')
162 return FALSE;
163
164 cur_token ++;
165
166 * begin = cur_token;
167
168 return TRUE;
169}
170
171static inline int skip_subj_leader(struct mailmessage_tree * tree,
172 char * subj, size_t * begin,
173 size_t length)
174{
175 size_t cur_token;
176
177 cur_token = * begin;
178
179 /* subj-leader = (*subj-blob subj-refwd) / WSP */
180
181 if (subj[cur_token] == ' ') {
182 cur_token ++;
183 }
184 else {
185 while (cur_token < length) {
186 if (!skip_subj_blob(subj, &cur_token, length))
187 break;
188 }
189 if (!skip_subj_refwd(subj, &cur_token, length))
190 return FALSE;
191 tree->node_is_reply = TRUE;
192 }
193
194 * begin = cur_token;
195
196 return TRUE;
197}
198
199
200static char * extract_subject(char * default_from,
201 struct mailmessage_tree * tree,
202 char * str)
203{
204 char * subj;
205 char * cur;
206 char * write_pos;
207 size_t len;
208 size_t begin;
209
210 char * decoded;
211 size_t cur_token;
212
213 int do_repeat_5;
214 int do_repeat_6;
215 int r;
216
217 /*
218 (1) Convert any RFC 2047 encoded-words in the subject to
219 UTF-8.
220 */
221
222 decoded = NULL;
223
224 cur_token = 0;
225 r = mailmime_encoded_phrase_parse(default_from, str, strlen(str),
226 &cur_token, "utf-8",
227 &decoded);
228
229 if (r == MAILIMF_NO_ERROR) {
230 subj = decoded;
231 }
232 else
233 subj = strdup(str);
234
235 len = strlen(subj);
236
237 /*
238 Convert all tabs and continuations to space.
239 Convert all multiple spaces to a single space.
240 */
241
242 cur = subj;
243 write_pos = subj;
244 while (* cur != '\0') {
245 int cont;
246
247 switch (* cur) {
248 case '\t':
249 case '\r':
250 case '\n':
251 cont = TRUE;
252
253 cur ++;
254 while (* cur && cont) {
255 switch (* cur) {
256 case '\t':
257 case '\r':
258 case '\n':
259 cont = TRUE;
260 break;
261 default:
262 cont = FALSE;
263 break;
264 }
265 cur ++;
266 }
267
268 * write_pos = ' ';
269 write_pos ++;
270
271 break;
272
273 default:
274 * write_pos = * cur;
275 write_pos ++;
276
277 cur ++;
278
279 break;
280 }
281 }
282 * write_pos = '\0';
283
284 begin = 0;
285
286 do {
287 do_repeat_6 = FALSE;
288
289 /*
290 (2) Remove all trailing text of the subject that matches
291 the subj-trailer ABNF, repeat until no more matches are
292 possible.
293 */
294
295 while (len > 0) {
296 int chg;
297
298 chg = FALSE;
299
300 /* subj-trailer = "(fwd)" / WSP */
301 if (subj[len - 1] == ' ') {
302 subj[len - 1] = '\0';
303 len --;
304 }
305 else {
306 if (len < 5)
307 break;
308
309 if (strncasecmp(subj + len - 5, "(fwd)", 5) != 0)
310 break;
311
312 subj[len - 5] = '\0';
313 len -= 5;
314 tree->node_is_reply = TRUE;
315 }
316 }
317
318 do {
319 size_t saved_begin;
320
321 do_repeat_5 = FALSE;
322
323 /*
324 (3) Remove all prefix text of the subject that matches the
325 subj-leader ABNF.
326 */
327
328 if (skip_subj_leader(tree, subj, &begin, len))
329 do_repeat_5 = TRUE;
330
331 /*
332 (4) If there is prefix text of the subject that matches the
333 subj-blob ABNF, and removing that prefix leaves a non-empty
334 subj-base, then remove the prefix text.
335 */
336
337 saved_begin = begin;
338 if (skip_subj_blob(subj, &begin, len)) {
339 if (begin == len) {
340 /* this will leave a empty subject base */
341 begin = saved_begin;
342 }
343 else
344 do_repeat_5 = TRUE;
345 }
346
347 /*
348 (5) Repeat (3) and (4) until no matches remain.
349 Note: it is possible to defer step (2) until step (6),
350 but this requires checking for subj-trailer in step (4).
351 */
352
353 }
354 while (do_repeat_5);
355
356 /*
357 (6) If the resulting text begins with the subj-fwd-hdr ABNF
358 and ends with the subj-fwd-trl ABNF, remove the
359 subj-fwd-hdr and subj-fwd-trl and repeat from step (2).
360 */
361
362 if (len >= 5) {
363 size_t saved_begin;
364
365 saved_begin = begin;
366 if (strncasecmp(subj + begin, "[fwd:", 5) == 0) {
367 begin += 5;
368
369 if (subj[len - 1] != ']')
370 saved_begin = begin;
371 else {
372 tree->node_is_reply = TRUE;
373
374 subj[len - 1] = '\0';
375 len --;
376 do_repeat_6 = TRUE;
377 }
378 }
379 }
380
381 }
382 while (do_repeat_6);
383
384 /*
385 (7) The resulting text is the "base subject" used in
386 threading.
387 */
388
389 /* convert to upper case */
390
391 cur = subj + begin;
392 write_pos = subj;
393
394 while (* cur != '\0') {
395 * write_pos = (char) toupper((unsigned char) * cur);
396 cur ++;
397 write_pos ++;
398 }
399 * write_pos = '\0';
400
401 return subj;
402}
403
404static int get_extracted_subject(char * default_from,
405 struct mailmessage_tree * tree,
406 char ** result)
407{
408 if (tree->node_msg->msg_single_fields.fld_subject != NULL) {
409 char * subj;
410
411 subj = extract_subject(default_from,
412 tree, tree->node_msg->msg_single_fields.fld_subject->sbj_value);
413 if (subj == NULL)
414 return MAIL_ERROR_MEMORY;
415
416 * result = subj;
417
418 return MAIL_NO_ERROR;
419 }
420
421 return MAIL_ERROR_SUBJECT_NOT_FOUND;
422}
423
424static int get_thread_subject(char * default_from,
425 struct mailmessage_tree * tree,
426 char ** result)
427{
428 char * thread_subject;
429 int r;
430 unsigned int i;
431
432 if (tree->node_msg != NULL) {
433 if (tree->node_msg->msg_fields != NULL) {
434 r = get_extracted_subject(default_from, tree, &thread_subject);
435
436 if (r != MAIL_NO_ERROR)
437 return r;
438
439 * result = thread_subject;
440 return MAIL_NO_ERROR;
441 }
442 }
443
444 for(i = 0 ; i < carray_count(tree->node_children) ; i ++) {
445 struct mailmessage_tree * child;
446
447 child = carray_get(tree->node_children, i);
448
449 r = get_thread_subject(default_from, child, &thread_subject);
450
451 switch (r) {
452 case MAIL_NO_ERROR:
453 * result = thread_subject;
454 return MAIL_NO_ERROR;
455
456 case MAIL_ERROR_SUBJECT_NOT_FOUND:
457 /* do nothing */
458 break;
459
460 default:
461 return r;
462 }
463 }
464
465 return MAIL_ERROR_SUBJECT_NOT_FOUND;
466}
467
468
469
470#ifndef WRONG
471 #define WRONG(-1)
472#endif /* !defined WRONG */
473
474static int tmcomp(struct tm * atmp, struct tm * btmp)
475{
476 register intresult;
477
478 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
479 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
480 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
481 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
482 (result = (atmp->tm_min - btmp->tm_min)) == 0)
483 result = atmp->tm_sec - btmp->tm_sec;
484 return result;
485}
486
487static time_t mkgmtime(struct tm * tmp)
488{
489 register int dir;
490 register int bits;
491 register int saved_seconds;
492 time_t t;
493 struct tm yourtm, *mytm;
494
495 yourtm = *tmp;
496 saved_seconds = yourtm.tm_sec;
497 yourtm.tm_sec = 0;
498 /*
499 ** Calculate the number of magnitude bits in a time_t
500 ** (this works regardless of whether time_t is
501 ** signed or unsigned, though lint complains if unsigned).
502 */
503 for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
504 ;
505 /*
506 ** If time_t is signed, then 0 is the median value,
507 ** if time_t is unsigned, then 1 << bits is median.
508 */
509 t = (t < 0) ? 0 : ((time_t) 1 << bits);
510 for ( ; ; ) {
511 mytm = gmtime(&t);
512 dir = tmcomp(mytm, &yourtm);
513 if (dir != 0) {
514 if (bits-- < 0)
515 return WRONG;
516 if (bits < 0)
517 --t;
518 else if (dir > 0)
519 t -= (time_t) 1 << bits;
520 elset += (time_t) 1 << bits;
521 continue;
522 }
523 break;
524 }
525 t += saved_seconds;
526 return t;
527}
528
529static inline time_t get_date(mailmessage * msg)
530{
531 struct tm tmval;
532 time_t timeval;
533 struct mailimf_date_time * date_time;
534
535 if (msg->msg_single_fields.fld_orig_date == NULL)
536 return (time_t) -1;
537
538 date_time = msg->msg_single_fields.fld_orig_date->dt_date_time;
539
540 tmval.tm_sec = date_time->dt_sec;
541 tmval.tm_min = date_time->dt_min;
542 tmval.tm_hour = date_time->dt_hour;
543 tmval.tm_sec = date_time->dt_sec;
544 tmval.tm_mday = date_time->dt_day;
545 tmval.tm_mon = date_time->dt_month - 1;
546 tmval.tm_year = date_time->dt_year - 1900;
547
548 timeval = mkgmtime(&tmval);
549
550 timeval -= date_time->dt_zone * 36;
551
552 return timeval;
553}
554
555static inline int is_descendant(struct mailmessage_tree * node,
556 struct mailmessage_tree * maybe_child)
557{
558 unsigned int i;
559
560 for(i = 0 ; i < carray_count(node->node_children) ; i++) {
561 struct mailmessage_tree * tree;
562
563 tree = carray_get(node->node_children, i);
564 if (tree == maybe_child)
565 return TRUE;
566 if (carray_count(tree->node_children) != 0)
567 if (is_descendant(tree, maybe_child))
568 return TRUE;
569 }
570
571 return FALSE;
572}
573
574static int delete_dummy(carray * rootlist, carray * sibling_list,
575 unsigned int cur, unsigned int * pnext)
576{
577 struct mailmessage_tree * env_tree;
578 int res;
579 int r;
580 unsigned int cur_child;
581 unsigned int next;
582
583 env_tree = carray_get(sibling_list, cur);
584
585 cur_child = 0;
586 while (cur_child < carray_count(env_tree->node_children)) {
587 delete_dummy(rootlist, env_tree->node_children, cur_child, &cur_child);
588 }
589
590 if (env_tree->node_msg == NULL) {
591 if (carray_count(env_tree->node_children) == 0) {
592
593 /* If it is a dummy message with NO children, delete it. */
594 mailmessage_tree_free(env_tree);
595 carray_delete(sibling_list, cur);
596 next = cur;
597 }
598 else {
599 /* If it is a dummy message with children, delete it, but
600 promote its children to the current level. */
601
602 /*
603 Do not promote the children if doing so would make them
604 children of the root, unless there is only one child.
605 */
606
607 cur_child = 0;
608 if ((sibling_list != rootlist) ||
609 (carray_count(env_tree->node_children) == 1)) {
610 while (cur_child < carray_count(env_tree->node_children)) {
611 struct mailmessage_tree * child;
612
613 child = carray_get(env_tree->node_children, cur_child);
614 r = carray_add(sibling_list, child, NULL);
615 if (r < 0) {
616 res = MAIL_ERROR_MEMORY;
617 goto err;
618 }
619 /* set new parent of the children */
620 child->node_parent = env_tree->node_parent;
621
622 carray_delete(env_tree->node_children, cur_child);
623 }
624 mailmessage_tree_free(env_tree);
625 carray_delete(sibling_list, cur);
626 next = cur;
627 }
628 else
629 next = cur + 1;
630 }
631 }
632 else
633 next = cur + 1;
634
635 * pnext = next;
636
637 return MAIL_NO_ERROR;
638
639 err:
640 return res;
641}
642
643static inline time_t tree_get_date(struct mailmessage_tree * tree)
644{
645 if (tree->node_msg != NULL) {
646 return tree->node_date;
647 }
648 else {
649 struct mailmessage_tree * subtree;
650
651 if (carray_count(tree->node_children) == 0)
652 return (time_t) -1;
653
654 subtree = carray_get(tree->node_children, 0);
655
656 return subtree->node_date;
657 }
658}
659
660static inline uint32_t tree_get_index(struct mailmessage_tree * tree)
661{
662 if (tree->node_msg == NULL)
663 return 0;
664
665 return tree->node_msg->msg_index;
666}
667
668int mailthread_tree_timecomp(struct mailmessage_tree ** ptree1,
669 struct mailmessage_tree ** ptree2)
670{
671 time_t date1;
672 time_t date2;
673
674 date1 = tree_get_date(* ptree1);
675 date2 = tree_get_date(* ptree2);
676
677 if ((date1 == (time_t) -1) || (date2 == (time_t) -1)) {
678 uint32_t index1;
679 uint32_t index2;
680
681 index1 = tree_get_index(* ptree1);
682 index2 = tree_get_index(* ptree2);
683 return (int) ((long) index1 - (long) index2);
684 }
685
686 return (int) ((long) date1 - (long) date2);
687}
688
689static int tree_subj_time_comp(struct mailmessage_tree ** ptree1,
690 struct mailmessage_tree ** ptree2)
691{
692 char * subj1;
693 char * subj2;
694 time_t date1;
695 time_t date2;
696 int r;
697
698 subj1 = (* ptree1)->node_base_subject;
699 subj2 = (* ptree2)->node_base_subject;
700
701 if ((subj1 != NULL) && (subj2 != NULL))
702 r = strcmp(subj1, subj2);
703 else {
704 if ((subj1 == NULL) && (subj2 == NULL))
705 r = 0;
706 else if (subj1 == NULL)
707 r = -1;
708 else /* subj2 == NULL */
709 r = 1;
710 }
711
712 if (r != 0)
713 return r;
714
715 date1 = (* ptree1)->node_date;
716 date2 = (* ptree2)->node_date;
717
718 if ((date1 == (time_t) -1) || (date2 == (time_t) -1))
719 return ((int32_t) (* ptree1)->node_msg->msg_index) -
720 ((int32_t) (* ptree2)->node_msg->msg_index);
721
722 return (int) ((long) date1 - (long) date2);
723}
724
725
726
727int mail_thread_sort(struct mailmessage_tree * tree,
728 int (* comp_func)(struct mailmessage_tree **,
729 struct mailmessage_tree **),
730 int sort_sub)
731{
732 unsigned int cur;
733 int r;
734 int res;
735
736 for(cur = 0 ; cur < carray_count(tree->node_children) ; cur ++) {
737 struct mailmessage_tree * subtree;
738
739 subtree = carray_get(tree->node_children, cur);
740
741 if (sort_sub) {
742 r = mail_thread_sort(subtree, comp_func, sort_sub);
743 if (r != MAIL_NO_ERROR) {
744 res = r;
745 goto err;
746 }
747 }
748 }
749
750 qsort(carray_data(tree->node_children), carray_count(tree->node_children),
751 sizeof(struct mailmessage_tree *),
752 (int (*)(const void *, const void *)) comp_func);
753
754 return MAIL_NO_ERROR;
755
756 err:
757 return res;
758}
759
760
761static int
762mail_build_thread_references(char * default_from,
763 struct mailmessage_list * env_list,
764 struct mailmessage_tree ** result,
765 int use_subject,
766 int (* comp_func)(struct mailmessage_tree **,
767 struct mailmessage_tree **))
768{
769 int r;
770 int res;
771 chash * msg_id_hash;
772 unsigned int cur;
773 struct mailmessage_tree * root;
774 carray * rootlist;
775 carray * msg_list;
776 unsigned int i;
777 chash * subject_hash;
778
779 msg_id_hash = chash_new(128, CHASH_COPYNONE);
780 if (msg_id_hash == NULL) {
781 res = MAIL_ERROR_MEMORY;
782 goto err;
783 }
784
785 root = mailmessage_tree_new(NULL, (time_t) -1, NULL);
786 if (root == NULL) {
787 res = MAIL_ERROR_MEMORY;
788 goto free_hash;
789 }
790 rootlist = root->node_children;
791
792 msg_list = carray_new(128);
793 if (msg_list == NULL) {
794 res = MAIL_ERROR_MEMORY;
795 goto free_root;
796 }
797
798 /* collect message-ID */
799 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
800 mailmessage * msg;
801 char * msgid;
802 struct mailmessage_tree * env_tree;
803 chashdatum hashkey;
804 chashdatum hashdata;
805 chashdatum hashold;
806 time_t date;
807
808 msg = carray_get(env_list->msg_tab, i);
809
810 if (msg == NULL)
811 continue;
812
813 if (msg->msg_fields != NULL) {
814 msgid = get_msg_id(msg);
815
816 if (msgid == NULL) {
817 msgid = mailimf_get_message_id();
818 }
819 else {
820 hashkey.data = msgid;
821 hashkey.len = strlen(msgid);
822
823 if (chash_get(msg_id_hash, &hashkey, &hashdata) == 0)
824 msgid = mailimf_get_message_id();
825 else
826 msgid = strdup(msgid);
827 }
828
829 if (msgid == NULL) {
830 res = MAIL_ERROR_MEMORY;
831 goto free_list;
832 }
833
834 date = get_date(msg);
835
836 env_tree = mailmessage_tree_new(msgid, date, msg);
837 if (env_tree == NULL) {
838 res = MAIL_ERROR_MEMORY;
839 goto free_list;
840 }
841
842 r = carray_add(msg_list, env_tree, NULL);
843 if (r < 0) {
844 mailmessage_tree_free(env_tree);
845 res = MAIL_ERROR_MEMORY;
846 goto free_list;
847 }
848
849 hashkey.data = msgid;
850 hashkey.len = strlen(msgid);
851
852 hashdata.data = env_tree;
853 hashdata.len = 0;
854
855 r = chash_set(msg_id_hash, &hashkey, &hashdata, &hashold);
856 if (r < 0) {
857 res = MAIL_ERROR_MEMORY;
858 goto free_list;
859 }
860 }
861 }
862
863 /* (1) for all messages */
864
865 for(cur = 0 ; cur < carray_count(msg_list) ; cur ++) {
866 struct mailmessage_tree * env_tree;
867 mailmessage * msg;
868 clist * ref;
869
870 env_tree = carray_get(msg_list, cur);
871
872 msg = env_tree->node_msg;
873
874 ref = NULL;
875 if (msg != NULL) {
876 ref = get_ref(msg);
877 if (ref == NULL)
878 ref = get_in_reply_to(msg);
879 }
880
881 /* (A) Using the Message IDs in the message's references, link
882 the corresponding messages (those whose Message-ID header
883 line contains the given reference Message ID) together as
884 parent/child.
885 */
886
887 if (ref != NULL) {
888 /* try to start a tree */
889
890 clistiter * cur_ref;
891 chashdatum hashkey;
892 chashdatum hashdata;
893 chashdatum hashold;
894 struct mailmessage_tree * env_cur_tree;
895 struct mailmessage_tree * last_env_cur_tree;
896
897 env_cur_tree = NULL;
898 for(cur_ref = clist_begin(ref) ; cur_ref != NULL ;
899 cur_ref = clist_next(cur_ref)) {
900 char * msgid;
901
902 last_env_cur_tree = env_cur_tree;
903
904 msgid = clist_content(cur_ref);
905
906 hashkey.data = msgid;
907 hashkey.len = strlen(msgid);
908
909 r = chash_get(msg_id_hash, &hashkey, &hashdata);
910 if (r < 0) {
911 /* not found, create a dummy message */
912 msgid = strdup(msgid);
913 if (msgid == NULL) {
914 res = MAIL_ERROR_MEMORY;
915 goto free_list;
916 }
917
918 env_cur_tree = mailmessage_tree_new(msgid, (time_t) -1, NULL);
919 if (env_cur_tree == NULL) {
920 free(msgid);
921 res = MAIL_ERROR_MEMORY;
922 goto free_list;
923 }
924
925 r = carray_add(msg_list, env_cur_tree, NULL);
926 if (r < 0) {
927 mailmessage_tree_free(env_cur_tree);
928 res = MAIL_ERROR_MEMORY;
929 goto free_list;
930 }
931
932 hashkey.data = msgid;
933 hashkey.len = strlen(msgid);
934
935 hashdata.data = env_cur_tree;
936 hashdata.len = 0;
937
938 r = chash_set(msg_id_hash, &hashkey, &hashdata, &hashold);
939 if (r < 0) {
940 res = MAIL_ERROR_MEMORY;
941 goto free_list;
942 }
943 }
944 else {
945 env_cur_tree = hashdata.data;
946 }
947
948 if (last_env_cur_tree != NULL) {
949 if (env_cur_tree->node_parent == NULL) {
950 /* make it one child */
951 if (env_cur_tree != last_env_cur_tree) {
952 if (!is_descendant(env_cur_tree, last_env_cur_tree)) {
953 /* set parent */
954 env_cur_tree->node_parent = last_env_cur_tree;
955 r = carray_add(last_env_cur_tree->node_children,
956 env_cur_tree, NULL);
957 if (r < 0) {
958 res = MAIL_ERROR_MEMORY;
959 goto free_list;
960 }
961 }
962 }
963 }
964 }
965 }
966
967 /* (B) Create a parent/child link between the last reference
968 (or NIL if there are no references) and the current message.
969 If the current message already has a parent, it is probably
970 the result of a truncated References header line, so break
971 the current parent/child link before creating the new
972 correct one.
973 */
974
975 last_env_cur_tree = env_cur_tree;
976
977 if (last_env_cur_tree != NULL) {
978 if (env_tree->node_parent == NULL) {
979 if (last_env_cur_tree != env_tree) {
980 if (!is_descendant(env_tree, last_env_cur_tree)) {
981 /* set parent */
982 env_tree->node_parent = last_env_cur_tree;
983 r = carray_add(last_env_cur_tree->node_children, env_tree, NULL);
984 if (r < 0) {
985 res = MAIL_ERROR_MEMORY;
986 goto free_list;
987 }
988 }
989 }
990 }
991 }
992 }
993 }
994
995 chash_free(msg_id_hash);
996 msg_id_hash = NULL;
997
998 /* (2) Gather together all of the messages that have no parents
999 and make them all children (siblings of one another) of a dummy
1000 parent (the "root").
1001 */
1002
1003 for(cur = 0 ; cur < carray_count(msg_list) ; cur ++) {
1004 struct mailmessage_tree * env_tree;
1005
1006 env_tree = carray_get(msg_list, cur);
1007 if (env_tree->node_parent == NULL) {
1008 r = carray_add(rootlist, env_tree, NULL);
1009 if (r < 0) {
1010 res = MAIL_ERROR_MEMORY;
1011 goto free_list;
1012 }
1013 /* set parent */
1014 env_tree->node_parent = root;
1015 }
1016 }
1017
1018 carray_free(msg_list);
1019 msg_list = NULL;
1020
1021 /* (3) Prune dummy messages from the thread tree.
1022 */
1023
1024 cur = 0;
1025 while (cur < carray_count(rootlist)) {
1026 r = delete_dummy(rootlist, rootlist, cur, &cur);
1027 if (r != MAIL_NO_ERROR) {
1028 res = r;
1029 goto free_list;
1030 }
1031 }
1032
1033 /* (4) Sort the messages under the root (top-level siblings only)
1034 by sent date.
1035 */
1036
1037 r = mail_thread_sort(root, mailthread_tree_timecomp, FALSE);
1038 if (r != MAIL_NO_ERROR) {
1039 res = r;
1040 goto free_list;
1041 }
1042
1043 if (use_subject) {
1044
1045 /* (5) Gather together messages under the root that have the same
1046 extracted subject text.
1047
1048 (A) Create a table for associating extracted subjects with
1049 messages.
1050 */
1051
1052 subject_hash = chash_new(128, CHASH_COPYVALUE);
1053 if (subject_hash == NULL) {
1054 res = MAIL_ERROR_MEMORY;
1055 goto free_list;
1056 }
1057
1058 /*
1059 (B) Populate the subject table with one message per
1060 extracted subject. For each child of the root:
1061 */
1062
1063 for(cur = 0 ; cur < carray_count(rootlist) ; cur ++) {
1064 struct mailmessage_tree * env_tree;
1065 chashdatum key;
1066 chashdatum data;
1067 char * base_subject;
1068 int r;
1069
1070 env_tree = carray_get(rootlist, cur);
1071
1072 /*
1073 (i) Find the subject of this thread by extracting the
1074 base subject from the current message, or its first child
1075 if the current message is a dummy.
1076 */
1077
1078 r = get_thread_subject(default_from, env_tree, &base_subject);
1079
1080 /*
1081 (ii) If the extracted subject is empty, skip this
1082 message.
1083 */
1084
1085 if (r == MAIL_ERROR_SUBJECT_NOT_FOUND) {
1086 /* no subject found */
1087 continue;
1088 }
1089 else if (r == MAIL_NO_ERROR) {
1090 if (* base_subject == '\0') {
1091 /* subject empty */
1092 free(base_subject);
1093 continue;
1094 }
1095 else {
1096 /* do nothing */
1097 }
1098 }
1099 else {
1100 res = r;
1101 goto free_subject_hash;
1102 }
1103
1104 env_tree->node_base_subject = base_subject;
1105
1106 /*
1107 (iii) Lookup the message associated with this extracted
1108 subject in the table.
1109 */
1110
1111 key.data = base_subject;
1112 key.len = strlen(base_subject);
1113
1114 r = chash_get(subject_hash, &key, &data);
1115
1116 if (r < 0) {
1117 /*
1118 (iv) If there is no message in the table with this
1119 subject, add the current message and the extracted
1120 subject to the subject table.
1121 */
1122
1123 data.data = &cur;
1124 data.len = sizeof(cur);
1125
1126 r = chash_set(subject_hash, &key, &data, NULL);
1127 if (r < 0) {
1128 res = MAIL_ERROR_MEMORY;
1129 goto free_subject_hash;
1130 }
1131 }
1132 else {
1133 /*
1134 Otherwise, replace the message in the table with the
1135 current message if the message in the table is not a
1136 dummy AND either of the following criteria are true:
1137 The current message is a dummy, OR
1138 The message in the table is a reply or forward (its
1139 original subject contains a subj-refwd part and/or a
1140 "(fwd)" subj-trailer) and the current message is not.
1141 */
1142 struct mailmessage_tree * msg_in_table;
1143 unsigned int * iter_in_table;
1144 int replace;
1145
1146 iter_in_table = data.data;
1147 msg_in_table = carray_get(rootlist, cur);
1148
1149 replace = FALSE;
1150 /* message is dummy if info is NULL */
1151 if (msg_in_table->node_msg != NULL) {
1152
1153 if (env_tree->node_msg == NULL)
1154 replace = TRUE;
1155 else {
1156 if (env_tree->node_is_reply && !env_tree->node_is_reply)
1157 replace = TRUE;
1158 }
1159 }
1160
1161 if (replace) {
1162 data.data = &cur;
1163 data.len = sizeof(cur);
1164
1165 r = chash_set(subject_hash, &key, &data, NULL);
1166 if (r < 0) {
1167 res = MAIL_ERROR_MEMORY;
1168 goto free_subject_hash;
1169 }
1170 }
1171 }
1172 }
1173
1174 /*
1175 (C) Merge threads with the same subject. For each child of
1176 the root:
1177 */
1178
1179 cur = 0;
1180 while (cur < carray_count(rootlist)) {
1181 struct mailmessage_tree * env_tree;
1182 chashdatum key;
1183 chashdatum data;
1184 int r;
1185 struct mailmessage_tree * main_tree;
1186 unsigned int * main_cur;
1187
1188 env_tree = carray_get(rootlist, cur);
1189
1190 if (env_tree == NULL)
1191 goto next_msg;
1192
1193 /*
1194 (i) Find the subject of this thread as in step 4.B.i
1195 above.
1196 */
1197
1198 /* already done in tree->node_base_subject */
1199
1200 /*
1201 (ii) If the extracted subject is empty, skip this
1202 message.
1203 */
1204
1205 if (env_tree->node_base_subject == NULL)
1206 goto next_msg;
1207
1208 if (* env_tree->node_base_subject == '\0')
1209 goto next_msg;
1210
1211 /*
1212 (iii) Lookup the message associated with this extracted
1213 subject in the table.
1214 */
1215
1216 key.data = env_tree->node_base_subject;
1217 key.len = strlen(env_tree->node_base_subject);
1218
1219 r = chash_get(subject_hash, &key, &data);
1220 if (r < 0)
1221 goto next_msg;
1222
1223 /*
1224 (iv) If the message in the table is the current message,
1225 skip this message.
1226 */
1227
1228 main_cur = data.data;
1229 if (* main_cur == cur)
1230 goto next_msg;
1231
1232 /*
1233 Otherwise, merge the current message with the one in the
1234 table using the following rules:
1235 */
1236
1237 main_tree = carray_get(rootlist, * main_cur);
1238
1239 /*
1240 If both messages are dummies, append the current
1241 message's children to the children of the message in
1242 the table (the children of both messages become
1243 siblings), and then delete the current message.
1244 */
1245
1246 if ((env_tree->node_msg == NULL) && (main_tree->node_msg == NULL)) {
1247 unsigned int old_size;
1248
1249 old_size = carray_count(main_tree->node_children);
1250
1251 r = carray_set_size(main_tree->node_children, old_size +
1252 carray_count(env_tree->node_children));
1253 if (r < 0) {
1254 res = MAIL_ERROR_MEMORY;
1255 goto free_subject_hash;
1256 }
1257
1258 for(i = 0 ; i < carray_count(env_tree->node_children) ; i ++) {
1259 struct mailmessage_tree * child;
1260
1261 child = carray_get(env_tree->node_children, i);
1262 carray_set(main_tree->node_children, old_size + i, child);
1263 /* set parent */
1264 child->node_parent = main_tree;
1265 }
1266 carray_set_size(env_tree->node_children, 0);
1267 /* this is the only case where children can be NULL,
1268 this is before freeing it */
1269 mailmessage_tree_free(env_tree);
1270 carray_delete_fast(rootlist, cur);
1271 }
1272
1273 /*
1274 If the message in the table is a dummy and the current
1275 message is not, make the current message a child of
1276 the message in the table (a sibling of it's children).
1277 */
1278
1279 else if (main_tree->node_msg == NULL) {
1280 r = carray_add(main_tree->node_children, env_tree, NULL);
1281 if (r < 0) {
1282 res = MAIL_ERROR_MEMORY;
1283 goto free_subject_hash;
1284 }
1285 /* set parent */
1286 env_tree->node_parent = main_tree;
1287
1288 carray_delete_fast(rootlist, cur);
1289 }
1290
1291 /*
1292 If the current message is a reply or forward and the
1293 message in the table is not, make the current message
1294 a child of the message in the table (a sibling of it's
1295 children).
1296 */
1297
1298 else if (env_tree->node_is_reply && !main_tree->node_is_reply) {
1299 r = carray_add(main_tree->node_children, env_tree, NULL);
1300 if (r < 0) {
1301 res = MAIL_ERROR_MEMORY;
1302 goto free_subject_hash;
1303 }
1304 /* set parent */
1305 env_tree->node_parent = main_tree;
1306
1307 carray_delete_fast(rootlist, cur);
1308 }
1309
1310 /*
1311 Otherwise, create a new dummy message and make both
1312 the current message and the message in the table
1313 children of the dummy. Then replace the message in
1314 the table with the dummy message.
1315 Note: Subject comparisons are case-insensitive, as
1316 described under "Internationalization
1317 Considerations."
1318 */
1319
1320 else {
1321 struct mailmessage_tree * new_main_tree;
1322 char * base_subject;
1323 unsigned int last;
1324
1325 new_main_tree = mailmessage_tree_new(NULL, (time_t) -1, NULL);
1326 if (new_main_tree == NULL) {
1327 res = MAIL_ERROR_MEMORY;
1328 goto free_subject_hash;
1329 }
1330
1331 /* main_tree->node_base_subject is never NULL */
1332
1333 base_subject = strdup(main_tree->node_base_subject);
1334 if (base_subject == NULL) {
1335 mailmessage_tree_free(new_main_tree);
1336 res = MAIL_ERROR_MEMORY;
1337 goto free_subject_hash;
1338 }
1339
1340 new_main_tree->node_base_subject = base_subject;
1341
1342 r = carray_add(rootlist, new_main_tree, &last);
1343 if (r < 0) {
1344 mailmessage_tree_free(new_main_tree);
1345 res = MAIL_ERROR_MEMORY;
1346 goto free_subject_hash;
1347 }
1348
1349 r = carray_add(new_main_tree->node_children, main_tree, NULL);
1350 if (r < 0) {
1351 res = MAIL_ERROR_MEMORY;
1352 goto free_subject_hash;
1353 }
1354 /* set parent */
1355 main_tree->node_parent = new_main_tree;
1356
1357 carray_delete_fast(rootlist, * main_cur);
1358
1359 r = carray_add(new_main_tree->node_children, env_tree, NULL);
1360 if (r < 0) {
1361 res = MAIL_ERROR_MEMORY;
1362 goto free_subject_hash;
1363 }
1364 /* set parent */
1365 env_tree->node_parent = new_main_tree;
1366
1367 carray_delete_fast(rootlist, cur);
1368
1369 data.data = &last;
1370 data.len = sizeof(last);
1371
1372 r = chash_set(subject_hash, &key, &data, NULL);
1373
1374 if (r < 0) {
1375 res = MAIL_ERROR_MEMORY;
1376 goto free_subject_hash;
1377 }
1378 }
1379
1380 continue;
1381
1382 next_msg:
1383 cur ++;
1384 continue;
1385 }
1386
1387 i = 0;
1388 for(cur = 0 ; cur < carray_count(rootlist) ; cur ++) {
1389 struct mailmessage_tree * env_tree;
1390
1391 env_tree = carray_get(rootlist, cur);
1392 if (env_tree == NULL)
1393 continue;
1394
1395 carray_set(rootlist, i, env_tree);
1396 i ++;
1397 }
1398 carray_set_size(rootlist, i);
1399
1400 chash_free(subject_hash);
1401 }
1402
1403 /*
1404 (6) Traverse the messages under the root and sort each set of
1405 siblings by sent date. Traverse the messages in such a way
1406 that the "youngest" set of siblings are sorted first, and the
1407 "oldest" set of siblings are sorted last (grandchildren are
1408 sorted before children, etc).
1409
1410 In the case of an exact match on
1411 sent date or if either of the Date: headers used in a
1412 comparison can not be parsed, use the order in which the
1413 messages appear in the mailbox (that is, by sequence number) to
1414 determine the order. In the case of a dummy message (which can
1415 only occur with top-level siblings), use its first child for
1416 sorting.
1417 */
1418
1419 if (comp_func != NULL) {
1420 r = mail_thread_sort(root, comp_func, TRUE);
1421 if (r != MAIL_NO_ERROR) {
1422 res = r;
1423 goto free_list;
1424 }
1425 }
1426
1427 * result = root;
1428
1429 return MAIL_NO_ERROR;
1430
1431 free_subject_hash:
1432 chash_free(subject_hash);
1433 free_list:
1434 if (msg_list != NULL) {
1435 for(i = 0 ; i < carray_count(msg_list) ; i ++)
1436 mailmessage_tree_free(carray_get(msg_list, i));
1437 carray_free(msg_list);
1438 }
1439 free_root:
1440 mailmessage_tree_free_recursive(root);
1441 free_hash:
1442 if (msg_id_hash != NULL)
1443 chash_free(msg_id_hash);
1444 err:
1445 return res;
1446}
1447
1448
1449
1450static int
1451mail_build_thread_orderedsubject(char * default_from,
1452 struct mailmessage_list * env_list,
1453 struct mailmessage_tree ** result,
1454 int (* comp_func)(struct mailmessage_tree **,
1455 struct mailmessage_tree **))
1456{
1457 unsigned int i;
1458 carray * rootlist;
1459 unsigned int cur;
1460 struct mailmessage_tree * root;
1461 int res;
1462 int r;
1463 struct mailmessage_tree * current_thread;
1464
1465 root = mailmessage_tree_new(NULL, (time_t) -1, NULL);
1466 if (root == NULL) {
1467 res = MAIL_ERROR_MEMORY;
1468 goto err;
1469 }
1470 rootlist = root->node_children;
1471
1472 /*
1473 The ORDEREDSUBJECT threading algorithm is also referred to as
1474 "poor man's threading."
1475 */
1476
1477 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1478 mailmessage * msg;
1479 struct mailmessage_tree * env_tree;
1480 char * base_subject;
1481 time_t date;
1482
1483 msg = carray_get(env_list->msg_tab, i);
1484
1485 if (msg == NULL)
1486 continue;
1487
1488 if (msg->msg_fields != NULL) {
1489
1490 date = get_date(msg);
1491
1492 env_tree = mailmessage_tree_new(NULL, date, msg);
1493 if (env_tree == NULL) {
1494 res = MAIL_ERROR_MEMORY;
1495 goto free;
1496 }
1497
1498 /* set parent */
1499 env_tree->node_parent = root;
1500 r = carray_add(rootlist, env_tree, NULL);
1501 if (r < 0) {
1502 mailmessage_tree_free(env_tree);
1503 res = MAIL_ERROR_MEMORY;
1504 goto free;
1505 }
1506
1507 r = get_extracted_subject(default_from, env_tree, &base_subject);
1508 switch (r) {
1509 case MAIL_NO_ERROR:
1510 env_tree->node_base_subject = base_subject;
1511 break;
1512
1513 case MAIL_ERROR_SUBJECT_NOT_FOUND:
1514 break;
1515
1516 default:
1517 res = r;
1518 goto free;
1519 }
1520 }
1521 }
1522
1523 /*
1524 The searched messages are sorted by
1525 subject and then by the sent date.
1526 */
1527
1528 r = mail_thread_sort(root, tree_subj_time_comp, FALSE);
1529 if (r != MAIL_NO_ERROR) {
1530 res = r;
1531 goto free;
1532 }
1533
1534 /*
1535 The messages are then split
1536 into separate threads, with each thread containing messages
1537 with the same extracted subject text.
1538 */
1539
1540 current_thread = NULL;
1541
1542 cur = 0;
1543 while (cur < carray_count(rootlist)) {
1544 struct mailmessage_tree * cur_env_tree;
1545
1546 cur_env_tree = carray_get(rootlist, cur);
1547 if (current_thread == NULL) {
1548 current_thread = cur_env_tree;
1549 cur ++;
1550 continue;
1551 }
1552
1553 if ((cur_env_tree->node_base_subject == NULL) ||
1554 (current_thread->node_base_subject == NULL)) {
1555 current_thread = cur_env_tree;
1556 cur ++;
1557 continue;
1558 }
1559
1560 if (strcmp(cur_env_tree->node_base_subject,
1561 current_thread->node_base_subject) == 0) {
1562
1563 /* set parent */
1564 cur_env_tree->node_parent = current_thread;
1565 r = carray_add(current_thread->node_children, cur_env_tree, NULL);
1566 if (r < 0) {
1567 res = MAIL_ERROR_MEMORY;
1568 goto free;
1569 }
1570
1571 carray_delete(rootlist, cur);
1572 }
1573 else
1574 cur ++;
1575 current_thread = cur_env_tree;
1576 }
1577
1578 /*
1579 Finally, the threads are
1580 sorted by the sent date of the first message in the thread.
1581 Note that each message in a thread is a child (as opposed to a
1582 sibling) of the previous message.
1583 */
1584
1585 if (comp_func != NULL) {
1586 r = mail_thread_sort(root, comp_func, FALSE);
1587 if (r != MAIL_NO_ERROR) {
1588 res = r;
1589 goto free;
1590 }
1591 }
1592
1593 * result = root;
1594
1595 return MAIL_NO_ERROR;
1596
1597 free:
1598 mailmessage_tree_free_recursive(root);
1599 err:
1600 return res;
1601}
1602
1603
1604int mail_build_thread(int type, char * default_from,
1605 struct mailmessage_list * env_list,
1606 struct mailmessage_tree ** result,
1607 int (* comp_func)(struct mailmessage_tree **,
1608 struct mailmessage_tree **))
1609{
1610 unsigned int i;
1611
1612 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++)
1613 mailmessage_resolve_single_fields(carray_get(env_list->msg_tab, i));
1614
1615 switch (type) {
1616 case MAIL_THREAD_REFERENCES:
1617 return mail_build_thread_references(default_from,
1618 env_list, result, TRUE, comp_func);
1619
1620 case MAIL_THREAD_REFERENCES_NO_SUBJECT:
1621 return mail_build_thread_references(default_from,
1622 env_list, result, FALSE, comp_func);
1623
1624 case MAIL_THREAD_ORDEREDSUBJECT:
1625 return mail_build_thread_orderedsubject(default_from,
1626 env_list, result, comp_func);
1627
1628 default:
1629 return MAIL_ERROR_NOT_IMPLEMENTED;
1630 }
1631}
diff --git a/kmicromail/libetpan/generic/mailthread.h b/kmicromail/libetpan/generic/mailthread.h
new file mode 100644
index 0000000..e4e33ff
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread.h
@@ -0,0 +1,108 @@
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#ifndef MAILTHREAD_H
37
38#define MAILTHREAD_H
39
40#include <libetpan/mailthread_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mail_build_thread constructs a tree with the message using the
48 given style.
49
50 @param type is the type of threading to apply, the value can be
51 MAIL_THREAD_REFERENCES, MAIL_THREAD_REFERENCES_NO_SUBJECT or
52 MAIL_THREAD_ORDEREDSUBJECT.
53
54 @param default_from is the default charset to use whenever the
55 subject is not tagged with a charset. "US-ASCII" can be used
56 if you don't know what to use.
57
58 @param env_list is the message list (with header fields fetched)
59 to use to build the message tree.
60
61 @param result * result) will contain the resulting message tree.
62
63 @param if comp_func is NULL, no sorting algorithm is used.
64
65 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
66 on error
67*/
68
69int mail_build_thread(int type, char * default_from,
70 struct mailmessage_list * env_list,
71 struct mailmessage_tree ** result,
72 int (* comp_func)(struct mailmessage_tree **,
73 struct mailmessage_tree **));
74
75/*
76 mail_thread_sort sort the messages in the message tree, using the
77 given sort function.
78
79 @param tree is the message tree to sort.
80
81 @param comp_func is the sort function to use (this is the same kind of
82 functions than those used for qsort()). mailthread_tree_timecomp can be
83 used for default sort.
84
85 @param sort_sub if this value is 0, only the children of the root message
86 are sorted.
87*/
88
89int mail_thread_sort(struct mailmessage_tree * tree,
90 int (* comp_func)(struct mailmessage_tree **,
91 struct mailmessage_tree **),
92 int sort_sub);
93
94/*
95 mailthread_tree_timecomp is the default sort function.
96
97 The message are compared by date, then by message numbers.
98 The tree are given in (* ptree1) and (* ptree2).
99*/
100
101int mailthread_tree_timecomp(struct mailmessage_tree ** ptree1,
102 struct mailmessage_tree ** ptree2);
103
104#ifdef __cplusplus
105}
106#endif
107
108#endif
diff --git a/kmicromail/libetpan/generic/mailthread_types.c b/kmicromail/libetpan/generic/mailthread_types.c
new file mode 100644
index 0000000..f1c5d37
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread_types.c
@@ -0,0 +1,90 @@
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 "mailthread_types.h"
37
38#include "mail.h"
39#include <stdlib.h>
40
41struct mailmessage_tree *
42mailmessage_tree_new(char * node_msgid, time_t node_date,
43 mailmessage * node_msg)
44{
45 struct mailmessage_tree * tree;
46 carray * array;
47
48 array = carray_new(16);
49 if (array == NULL)
50 return NULL;
51
52 tree = malloc(sizeof(* tree));
53 tree->node_parent = NULL;
54 tree->node_date = node_date;
55 tree->node_msgid = node_msgid;
56 tree->node_msg = node_msg;
57 tree->node_children = array;
58 tree->node_base_subject = NULL;
59 tree->node_is_reply = FALSE;
60
61 return tree;
62}
63
64void mailmessage_tree_free(struct mailmessage_tree * tree)
65{
66 if (tree->node_base_subject != NULL)
67 free(tree->node_base_subject);
68
69 if (tree->node_children != NULL)
70 carray_free(tree->node_children);
71 if (tree->node_msgid != NULL)
72 free(tree->node_msgid);
73
74 free(tree);
75}
76
77void mailmessage_tree_free_recursive(struct mailmessage_tree * tree)
78{
79 unsigned int i;
80
81 for(i = 0 ; i < carray_count(tree->node_children) ; i++) {
82 struct mailmessage_tree * child;
83
84 child = carray_get(tree->node_children, i);
85
86 mailmessage_tree_free_recursive(child);
87 }
88
89 mailmessage_tree_free(tree);
90}
diff --git a/kmicromail/libetpan/generic/mailthread_types.h b/kmicromail/libetpan/generic/mailthread_types.h
new file mode 100644
index 0000000..5ef7b46
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread_types.h
@@ -0,0 +1,63 @@
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#ifndef MAILTHREAD_TYPES_H
37
38#define MAILTHREAD_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/maildriver_types.h>
45#include <libetpan/mailmessage_types.h>
46
47/*
48 This is the type of tree construction to apply.
49*/
50
51enum {
52 MAIL_THREAD_REFERENCES, /* this is threading using
53 References fields only) */
54 MAIL_THREAD_REFERENCES_NO_SUBJECT, /* this is threading using References
55 fields, then subject */
56 MAIL_THREAD_ORDEREDSUBJECT, /* this is threading using only subject */
57};
58
59#ifdef __cplusplus
60}
61#endif
62
63#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver.c b/kmicromail/libetpan/generic/mboxdriver.c
new file mode 100644
index 0000000..fa3e2ea
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver.c
@@ -0,0 +1,505 @@
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 "mboxdriver.h"
37
38#include <stdio.h>
39#include <string.h>
40#include <sys/types.h>
41#include <dirent.h>
42#include <unistd.h>
43#include <sys/stat.h>
44#include <ctype.h>
45#include <stdlib.h>
46#include <sys/times.h>
47
48#include "mail.h"
49#include "maildriver_tools.h"
50#include "mailmbox.h"
51#include "mboxdriver_tools.h"
52#include "maildriver.h"
53#include "carray.h"
54#include "mboxdriver_message.h"
55#include "mailmessage.h"
56
57static int mboxdriver_initialize(mailsession * session);
58
59static void mboxdriver_uninitialize(mailsession * session);
60
61static int mboxdriver_parameters(mailsession * session,
62 int id, void * value);
63
64static int mboxdriver_connect_path(mailsession * session, char * path);
65
66static int mboxdriver_logout(mailsession * session);
67
68static int mboxdriver_expunge_folder(mailsession * session);
69
70static int mboxdriver_status_folder(mailsession * session, char * mb,
71 uint32_t * result_messages, uint32_t * result_recent,
72 uint32_t * result_unseen);
73
74static int mboxdriver_messages_number(mailsession * session, char * mb,
75 uint32_t * result);
76
77static int mboxdriver_append_message(mailsession * session,
78 char * message, size_t size);
79
80static int mboxdriver_get_messages_list(mailsession * session,
81 struct mailmessage_list ** result);
82
83static int
84mboxdriver_get_envelopes_list(mailsession * session,
85 struct mailmessage_list * env_list);
86
87static int mboxdriver_remove_message(mailsession * session, uint32_t num);
88
89static int mboxdriver_get_message(mailsession * session,
90 uint32_t num, mailmessage ** result);
91
92static int mboxdriver_get_message_by_uid(mailsession * session,
93 const char * uid,
94 mailmessage ** result);
95
96static mailsession_driver local_mbox_session_driver = {
97 .sess_name = "mbox",
98
99 .sess_initialize = mboxdriver_initialize,
100 .sess_uninitialize = mboxdriver_uninitialize,
101
102 .sess_parameters = mboxdriver_parameters,
103
104 .sess_connect_path = mboxdriver_connect_path,
105 .sess_connect_stream = NULL,
106 .sess_starttls = NULL,
107 .sess_login = NULL,
108 .sess_logout = mboxdriver_logout,
109 .sess_noop = NULL,
110
111 .sess_build_folder_name = NULL,
112 .sess_create_folder = NULL,
113 .sess_delete_folder = NULL,
114 .sess_rename_folder = NULL,
115 .sess_check_folder = NULL,
116 .sess_examine_folder = NULL,
117 .sess_select_folder = NULL,
118 .sess_expunge_folder = mboxdriver_expunge_folder,
119 .sess_status_folder = mboxdriver_status_folder,
120 .sess_messages_number = mboxdriver_messages_number,
121 .sess_recent_number = mboxdriver_messages_number,
122 .sess_unseen_number = mboxdriver_messages_number,
123 .sess_list_folders = NULL,
124 .sess_lsub_folders = NULL,
125 .sess_subscribe_folder = NULL,
126 .sess_unsubscribe_folder = NULL,
127
128 .sess_append_message = mboxdriver_append_message,
129 .sess_copy_message = NULL,
130 .sess_move_message = NULL,
131
132 .sess_get_messages_list = mboxdriver_get_messages_list,
133 .sess_get_envelopes_list = mboxdriver_get_envelopes_list,
134 .sess_remove_message = mboxdriver_remove_message,
135#if 0
136 .sess_search_messages = maildriver_generic_search_messages,
137#endif
138
139 .sess_get_message = mboxdriver_get_message,
140 .sess_get_message_by_uid = mboxdriver_get_message_by_uid,
141};
142
143mailsession_driver * mbox_session_driver = &local_mbox_session_driver;
144
145static inline struct mbox_session_state_data * get_data(mailsession * session)
146{
147 return session->sess_data;
148}
149
150static inline struct mailmbox_folder * get_mbox_session(mailsession * session)
151{
152 return get_data(session)->mbox_folder;
153}
154
155static int mboxdriver_initialize(mailsession * session)
156{
157 struct mbox_session_state_data * data;
158
159 data = malloc(sizeof(* data));
160 if (data == NULL)
161 goto err;
162
163 data->mbox_folder = NULL;
164
165 data->mbox_force_read_only = FALSE;
166 data->mbox_force_no_uid = TRUE;
167
168 session->sess_data = data;
169
170 return MAIL_NO_ERROR;
171
172 err:
173 return MAIL_ERROR_MEMORY;
174}
175
176static void free_state(struct mbox_session_state_data * mbox_data)
177{
178 if (mbox_data->mbox_folder != NULL) {
179 mailmbox_done(mbox_data->mbox_folder);
180 mbox_data->mbox_folder = NULL;
181 }
182}
183
184static void mboxdriver_uninitialize(mailsession * session)
185{
186 struct mbox_session_state_data * data;
187
188 data = get_data(session);
189
190 free_state(data);
191
192 free(data);
193}
194
195static int mboxdriver_parameters(mailsession * session,
196 int id, void * value)
197{
198 struct mbox_session_state_data * data;
199
200 data = get_data(session);
201
202 switch (id) {
203 case MBOXDRIVER_SET_READ_ONLY:
204 {
205 int * param;
206
207 param = value;
208
209 data->mbox_force_read_only = * param;
210 return MAIL_NO_ERROR;
211 }
212
213 case MBOXDRIVER_SET_NO_UID:
214 {
215 int * param;
216
217 param = value;
218
219 data->mbox_force_no_uid = * param;
220 return MAIL_NO_ERROR;
221 }
222 }
223
224 return MAIL_ERROR_INVAL;
225}
226
227
228static int mboxdriver_connect_path(mailsession * session, char * path)
229{
230 struct mbox_session_state_data * mbox_data;
231 struct mailmbox_folder * folder;
232 int r;
233
234 mbox_data = get_data(session);
235
236 if (mbox_data->mbox_folder != NULL)
237 return MAIL_ERROR_BAD_STATE;
238
239 r = mailmbox_init(path,
240 mbox_data->mbox_force_read_only,
241 mbox_data->mbox_force_no_uid,
242 0,
243 &folder);
244
245 if (r != MAILMBOX_NO_ERROR)
246 return mboxdriver_mbox_error_to_mail_error(r);
247
248 mbox_data->mbox_folder = folder;
249
250 return MAIL_NO_ERROR;
251}
252
253static int mboxdriver_logout(mailsession * session)
254{
255 struct mbox_session_state_data * mbox_data;
256
257 mbox_data = get_data(session);
258
259 if (mbox_data->mbox_folder == NULL)
260 return MAIL_ERROR_BAD_STATE;
261
262 free_state(mbox_data);
263
264 mbox_data->mbox_folder = NULL;
265
266 return MAIL_NO_ERROR;
267}
268
269static int mboxdriver_expunge_folder(mailsession * session)
270{
271 int r;
272 struct mbox_session_state_data * mbox_data;
273
274 mbox_data = get_data(session);
275
276 if (mbox_data->mbox_folder == NULL)
277 return MAIL_ERROR_BAD_STATE;
278
279 r = mailmbox_expunge(mbox_data->mbox_folder);
280 if (r != MAILMBOX_NO_ERROR)
281 return mboxdriver_mbox_error_to_mail_error(r);
282
283 return MAIL_NO_ERROR;
284}
285
286static int mboxdriver_status_folder(mailsession * session, char * mb,
287 uint32_t * result_messages, uint32_t * result_recent,
288 uint32_t * result_unseen)
289{
290 uint32_t count;
291 int r;
292
293 r = mboxdriver_messages_number(session, mb, &count);
294 if (r != MAIL_NO_ERROR)
295 return r;
296
297 * result_messages = count;
298 * result_recent = count;
299 * result_unseen = count;
300
301 return MAIL_NO_ERROR;
302}
303
304static int mboxdriver_messages_number(mailsession * session, char * mb,
305 uint32_t * result)
306{
307 struct mailmbox_folder * folder;
308 int r;
309
310 folder = get_mbox_session(session);
311 if (folder == NULL)
312 return MAIL_ERROR_STATUS;
313
314 r = mailmbox_validate_read_lock(folder);
315 if (r != MAIL_NO_ERROR)
316 return r;
317
318 mailmbox_read_unlock(folder);
319
320 * result = carray_count(folder->mb_tab) - folder->mb_deleted_count;
321
322 return MAILMBOX_NO_ERROR;
323}
324
325/* messages operations */
326
327static int mboxdriver_append_message(mailsession * session,
328 char * message, size_t size)
329{
330 int r;
331 struct mailmbox_folder * folder;
332
333 folder = get_mbox_session(session);
334 if (folder == NULL)
335 return MAIL_ERROR_APPEND;
336
337 r = mailmbox_append_message(folder, message, size);
338
339 switch (r) {
340 case MAILMBOX_ERROR_FILE:
341 return MAIL_ERROR_DISKSPACE;
342 default:
343 return mboxdriver_mbox_error_to_mail_error(r);
344 }
345}
346
347static int mboxdriver_get_messages_list(mailsession * session,
348 struct mailmessage_list ** result)
349{
350 struct mailmbox_folder * folder;
351 int res;
352
353 folder = get_mbox_session(session);
354 if (folder == NULL) {
355 res = MAIL_ERROR_BAD_STATE;
356 goto err;
357 }
358
359 return mbox_get_messages_list(folder, session, mbox_message_driver, result);
360
361 err:
362 return res;
363}
364
365static int
366mboxdriver_get_envelopes_list(mailsession * session,
367 struct mailmessage_list * env_list)
368{
369 struct mailmbox_folder * folder;
370 unsigned int i;
371 int r;
372 int res;
373
374 folder = get_mbox_session(session);
375 if (folder == NULL) {
376 res = MAIL_ERROR_BAD_STATE;
377 goto err;
378 }
379
380 r = mailmbox_validate_read_lock(folder);
381 if (r != MAILMBOX_NO_ERROR) {
382 res = mboxdriver_mbox_error_to_mail_error(r);
383 goto err;
384 }
385
386 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
387 mailmessage * msg;
388 struct mailimf_fields * fields;
389 char * headers;
390 size_t headers_len;
391 size_t cur_token;
392
393 msg = carray_get(env_list->msg_tab, i);
394 if (msg == NULL)
395 continue;
396
397 if (msg->msg_fields != NULL)
398 continue;
399
400 r = mailmbox_fetch_msg_headers_no_lock(folder,
401 msg->msg_index, &headers, &headers_len);
402 if (r != MAILMBOX_NO_ERROR) {
403 res = mboxdriver_mbox_error_to_mail_error(r);
404 goto unlock;
405 }
406
407 cur_token = 0;
408 r = mailimf_envelope_fields_parse(headers, headers_len,
409 &cur_token, &fields);
410
411 if (r != MAILIMF_NO_ERROR)
412 continue;
413
414 msg->msg_fields = fields;
415 }
416
417 mailmbox_read_unlock(folder);
418
419 return MAIL_NO_ERROR;
420
421 unlock:
422 mailmbox_read_unlock(folder);
423 err:
424 return res;
425}
426
427
428static int mboxdriver_remove_message(mailsession * session, uint32_t num)
429{
430 int r;
431 struct mailmbox_folder * folder;
432
433 folder = get_mbox_session(session);
434 if (folder == NULL)
435 return MAIL_ERROR_DELETE;
436
437 r = mailmbox_delete_msg(folder, num);
438
439 return mboxdriver_mbox_error_to_mail_error(r);
440}
441
442static int mboxdriver_get_message(mailsession * session,
443 uint32_t num, mailmessage ** result)
444{
445 mailmessage * msg_info;
446 int r;
447
448 msg_info = mailmessage_new();
449 if (msg_info == NULL)
450 return MAIL_ERROR_MEMORY;
451
452 r = mailmessage_init(msg_info, session, mbox_message_driver, num, 0);
453 if (r != MAIL_NO_ERROR) {
454 mailmessage_free(msg_info);
455 return r;
456 }
457
458 * result = msg_info;
459
460 return MAIL_NO_ERROR;
461}
462
463static int mboxdriver_get_message_by_uid(mailsession * session,
464 const char * uid,
465 mailmessage ** result)
466{
467 uint32_t num;
468 char * p;
469 chashdatum key;
470 chashdatum data;
471 struct mailmbox_msg_info * info;
472 struct mailmbox_folder * folder;
473 int r;
474
475 if (uid == NULL)
476 return MAIL_ERROR_INVAL;
477
478 num = strtoul(uid, &p, 10);
479 if (p == uid || * p != '-')
480 return MAIL_ERROR_INVAL;
481
482 folder = get_mbox_session(session);
483 if (folder == NULL)
484 return MAIL_ERROR_BAD_STATE;
485
486 key.data = &num;
487 key.len = sizeof(num);
488
489 r = chash_get(folder->mb_hash, &key, &data);
490 if (r == 0) {
491 char * body_len_p = p + 1;
492 size_t body_len;
493
494 info = data.data;
495 /* Check if the cached message has the same UID */
496 body_len = strtoul(body_len_p, &p, 10);
497 if (p == body_len_p || * p != '\0')
498 return MAIL_ERROR_INVAL;
499
500 if (body_len == info->msg_body_len)
501 return mboxdriver_get_message(session, num, result);
502 }
503
504 return MAIL_ERROR_MSG_NOT_FOUND;
505}
diff --git a/kmicromail/libetpan/generic/mboxdriver.h b/kmicromail/libetpan/generic/mboxdriver.h
new file mode 100644
index 0000000..c598026
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver.h
@@ -0,0 +1,52 @@
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#ifndef MBOXDRIVER_H
37
38#define MBOXDRIVER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mboxdriver_types.h>
45
46extern mailsession_driver * mbox_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached.c b/kmicromail/libetpan/generic/mboxdriver_cached.c
new file mode 100644
index 0000000..07871fa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached.c
@@ -0,0 +1,1253 @@
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 "mboxdriver_cached.h"
37
38#include <stdio.h>
39#include <string.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <ctype.h>
43#include <sys/types.h>
44#include <sys/stat.h>
45#include <fcntl.h>
46#include <stdlib.h>
47
48#include "mail.h"
49#include "mail_cache_db.h"
50#include "mboxdriver.h"
51#include "mboxdriver_tools.h"
52#include "maildriver_tools.h"
53#include "mailmbox.h"
54#include "maildriver.h"
55#include "carray.h"
56#include "generic_cache.h"
57#include "imfcache.h"
58#include "mboxdriver_cached_message.h"
59#include "libetpan-config.h"
60
61static int mboxdriver_cached_initialize(mailsession * session);
62
63static void mboxdriver_cached_uninitialize(mailsession * session);
64
65static int mboxdriver_cached_parameters(mailsession * session,
66 int id, void * value);
67
68static int mboxdriver_cached_connect_path(mailsession * session, char * path);
69
70static int mboxdriver_cached_logout(mailsession * session);
71
72static int mboxdriver_cached_check_folder(mailsession * session);
73
74static int mboxdriver_cached_expunge_folder(mailsession * session);
75
76static int mboxdriver_cached_status_folder(mailsession * session, char * mb,
77 uint32_t * result_messages, uint32_t * result_recent,
78 uint32_t * result_unseen);
79static int mboxdriver_cached_messages_number(mailsession * session, char * mb,
80 uint32_t * result);
81static int mboxdriver_cached_recent_number(mailsession * session, char * mb,
82 uint32_t * result);
83static int mboxdriver_cached_unseen_number(mailsession * session, char * mb,
84 uint32_t * result);
85
86static int mboxdriver_cached_append_message(mailsession * session,
87 char * message, size_t size);
88
89static int
90mboxdriver_cached_get_messages_list(mailsession * session,
91 struct mailmessage_list ** result);
92
93static int
94mboxdriver_cached_get_envelopes_list(mailsession * session,
95 struct mailmessage_list * env_list);
96
97static int mboxdriver_cached_remove_message(mailsession * session,
98 uint32_t num);
99
100static int mboxdriver_cached_get_message(mailsession * session,
101 uint32_t num, mailmessage ** result);
102
103static int mboxdriver_cached_get_message_by_uid(mailsession * session,
104 const char * uid,
105 mailmessage ** result);
106
107static mailsession_driver local_mbox_cached_session_driver = {
108 .sess_name = "mbox-cached",
109
110 .sess_initialize = mboxdriver_cached_initialize,
111 .sess_uninitialize = mboxdriver_cached_uninitialize,
112
113 .sess_parameters = mboxdriver_cached_parameters,
114
115 .sess_connect_path = mboxdriver_cached_connect_path,
116 .sess_connect_stream = NULL,
117 .sess_starttls = NULL,
118 .sess_login = NULL,
119 .sess_logout = mboxdriver_cached_logout,
120 .sess_noop = NULL,
121
122 .sess_build_folder_name = NULL,
123 .sess_create_folder = NULL,
124 .sess_delete_folder = NULL,
125 .sess_rename_folder = NULL,
126 .sess_check_folder = mboxdriver_cached_check_folder,
127 .sess_examine_folder = NULL,
128 .sess_select_folder = NULL,
129 .sess_expunge_folder = mboxdriver_cached_expunge_folder,
130 .sess_status_folder = mboxdriver_cached_status_folder,
131 .sess_messages_number = mboxdriver_cached_messages_number,
132 .sess_recent_number = mboxdriver_cached_recent_number,
133 .sess_unseen_number = mboxdriver_cached_unseen_number,
134 .sess_list_folders = NULL,
135 .sess_lsub_folders = NULL,
136 .sess_subscribe_folder = NULL,
137 .sess_unsubscribe_folder = NULL,
138
139 .sess_append_message = mboxdriver_cached_append_message,
140 .sess_copy_message = NULL,
141 .sess_move_message = NULL,
142
143 .sess_get_messages_list = mboxdriver_cached_get_messages_list,
144 .sess_get_envelopes_list = mboxdriver_cached_get_envelopes_list,
145 .sess_remove_message = mboxdriver_cached_remove_message,
146#if 0
147 .sess_search_messages = maildriver_generic_search_messages,
148#endif
149
150 .sess_get_message = mboxdriver_cached_get_message,
151 .sess_get_message_by_uid = mboxdriver_cached_get_message_by_uid,
152};
153
154mailsession_driver * mbox_cached_session_driver =
155&local_mbox_cached_session_driver;
156
157
158#define ENV_NAME "env.db"
159#define FLAGS_NAME "flags.db"
160
161
162
163static int mbox_error_to_mail_error(int error)
164{
165 switch (error) {
166 case MAILMBOX_NO_ERROR:
167 return MAIL_NO_ERROR;
168
169 case MAILMBOX_ERROR_PARSE:
170 return MAIL_ERROR_PARSE;
171
172 case MAILMBOX_ERROR_INVAL:
173 return MAIL_ERROR_INVAL;
174
175 case MAILMBOX_ERROR_FILE_NOT_FOUND:
176 return MAIL_ERROR_PARSE;
177
178 case MAILMBOX_ERROR_MEMORY:
179 return MAIL_ERROR_MEMORY;
180
181 case MAILMBOX_ERROR_TEMPORARY_FILE:
182 return MAIL_ERROR_PARSE;
183
184 case MAILMBOX_ERROR_FILE:
185 return MAIL_ERROR_FILE;
186
187 case MAILMBOX_ERROR_MSG_NOT_FOUND:
188 return MAIL_ERROR_MSG_NOT_FOUND;
189
190 case MAILMBOX_ERROR_READONLY:
191 return MAIL_ERROR_READONLY;
192
193 default:
194 return MAIL_ERROR_INVAL;
195 }
196}
197
198
199
200
201static inline struct mbox_cached_session_state_data *
202get_cached_data(mailsession * session)
203{
204 return session->sess_data;
205}
206
207static inline mailsession * get_ancestor(mailsession * session)
208{
209 return get_cached_data(session)->mbox_ancestor;
210}
211
212static inline struct mbox_session_state_data *
213get_ancestor_data(mailsession * session)
214{
215 return get_ancestor(session)->sess_data;
216}
217
218static inline struct mailmbox_folder *
219get_mbox_session(mailsession * session)
220{
221 return get_ancestor_data(session)->mbox_folder;
222}
223
224static int mboxdriver_cached_initialize(mailsession * session)
225{
226 struct mbox_cached_session_state_data * cached_data;
227 struct mbox_session_state_data * mbox_data;
228
229 cached_data = malloc(sizeof(* cached_data));
230 if (cached_data == NULL)
231 goto err;
232
233 cached_data->mbox_flags_store = mail_flags_store_new();
234 if (cached_data->mbox_flags_store == NULL)
235 goto free;
236
237 cached_data->mbox_ancestor = mailsession_new(mbox_session_driver);
238 if (cached_data->mbox_ancestor == NULL)
239 goto free_store;
240
241 cached_data->mbox_quoted_mb = NULL;
242 /*
243 UID must be enabled to take advantage of the cache
244 */
245 mbox_data = cached_data->mbox_ancestor->sess_data;
246 mbox_data->mbox_force_no_uid = FALSE;
247
248 session->sess_data = cached_data;
249
250 return MAIL_NO_ERROR;
251
252 free_store:
253 mail_flags_store_free(cached_data->mbox_flags_store);
254 free:
255 free(cached_data);
256 err:
257 return MAIL_ERROR_MEMORY;
258}
259
260static void free_state(struct mbox_cached_session_state_data * mbox_data)
261{
262 if (mbox_data->mbox_quoted_mb) {
263 free(mbox_data->mbox_quoted_mb);
264 mbox_data->mbox_quoted_mb = NULL;
265 }
266}
267
268static int mbox_flags_store_process(char * flags_directory, char * quoted_mb,
269 struct mail_flags_store * flags_store)
270{
271 char filename_flags[PATH_MAX];
272 struct mail_cache_db * cache_db_flags;
273 MMAPString * mmapstr;
274 unsigned int i;
275 int r;
276 int res;
277
278 if (carray_count(flags_store->fls_tab) == 0)
279 return MAIL_NO_ERROR;
280
281 if (quoted_mb == NULL)
282 return MAIL_NO_ERROR;
283
284 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
285 flags_directory, MAIL_DIR_SEPARATOR, quoted_mb,
286 MAIL_DIR_SEPARATOR, FLAGS_NAME);
287
288 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
289 if (r < 0) {
290 res = MAIL_ERROR_FILE;
291 goto err;
292 }
293
294 mmapstr = mmap_string_new("");
295 if (mmapstr == NULL) {
296 res = MAIL_ERROR_MEMORY;
297 goto close_db_flags;
298 }
299
300 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
301 mailmessage * msg;
302
303 msg = carray_get(flags_store->fls_tab, i);
304
305 r = mboxdriver_write_cached_flags(cache_db_flags, mmapstr,
306 msg->msg_uid, msg->msg_flags);
307 if (r != MAIL_NO_ERROR) {
308 /* ignore errors */
309 }
310 }
311
312 mmap_string_free(mmapstr);
313 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
314
315 mail_flags_store_clear(flags_store);
316
317 return MAIL_NO_ERROR;
318
319 close_db_flags:
320 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
321 err:
322 return res;
323}
324
325static void mboxdriver_cached_uninitialize(mailsession * session)
326{
327 struct mbox_cached_session_state_data * data;
328
329 data = get_cached_data(session);
330
331 mbox_flags_store_process(data->mbox_flags_directory,
332 data->mbox_quoted_mb,
333 data->mbox_flags_store);
334
335 mail_flags_store_free(data->mbox_flags_store);
336
337 free_state(data);
338 mailsession_free(data->mbox_ancestor);
339 free(data);
340
341 session->sess_data = NULL;
342}
343
344static int mboxdriver_cached_parameters(mailsession * session,
345 int id, void * value)
346{
347 struct mbox_cached_session_state_data * data;
348 int r;
349
350 data = get_cached_data(session);
351
352 switch (id) {
353 case MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY:
354 strncpy(data->mbox_cache_directory, value, PATH_MAX);
355 data->mbox_cache_directory[PATH_MAX - 1] = '\0';
356
357 r = generic_cache_create_dir(data->mbox_cache_directory);
358 if (r != MAIL_NO_ERROR)
359 return r;
360
361 return MAIL_NO_ERROR;
362
363 case MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY:
364 strncpy(data->mbox_flags_directory, value, PATH_MAX);
365 data->mbox_flags_directory[PATH_MAX - 1] = '\0';
366
367 r = generic_cache_create_dir(data->mbox_flags_directory);
368 if (r != MAIL_NO_ERROR)
369 return r;
370
371 return MAIL_NO_ERROR;
372
373 case MBOXDRIVER_SET_NO_UID:
374 return MAIL_ERROR_INVAL;
375
376 default:
377 return mailsession_parameters(data->mbox_ancestor, id, value);
378 }
379}
380
381
382static int get_cache_directory(mailsession * session,
383 char * path, char ** result)
384{
385 char * quoted_mb;
386 char dirname[PATH_MAX];
387 int res;
388 int r;
389 struct mbox_cached_session_state_data * cached_data;
390
391 cached_data = get_cached_data(session);
392
393 quoted_mb = maildriver_quote_mailbox(path);
394 if (quoted_mb == NULL) {
395 res = MAIL_ERROR_MEMORY;
396 goto err;
397 }
398
399 snprintf(dirname, PATH_MAX, "%s%c%s",
400 cached_data->mbox_cache_directory, MAIL_DIR_SEPARATOR, quoted_mb);
401
402 r = generic_cache_create_dir(dirname);
403 if (r != MAIL_NO_ERROR) {
404 res = r;
405 goto free;
406 }
407
408 snprintf(dirname, PATH_MAX, "%s%c%s",
409 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR, quoted_mb);
410
411 r = generic_cache_create_dir(dirname);
412 if (r != MAIL_NO_ERROR) {
413 res = r;
414 goto free;
415 }
416
417 * result = quoted_mb;
418
419 return MAIL_NO_ERROR;
420
421 free:
422 free(quoted_mb);
423 err:
424 return res;
425}
426
427
428
429
430#define FILENAME_MAX_UID "max-uid"
431
432/* write max uid current value */
433
434static int write_max_uid_value(mailsession * session)
435{
436 int r;
437 char filename[PATH_MAX];
438 FILE * f;
439 int res;
440
441#if 0
442 struct mbox_session_state_data * mbox_data;
443#endif
444 struct mbox_cached_session_state_data * cached_data;
445 int fd;
446
447 MMAPString * mmapstr;
448 size_t cur_token;
449 struct mailmbox_folder * folder;
450
451 /* expunge the mailbox */
452
453#if 0
454 mbox_data = get_ancestor(session)->data;
455#endif
456 folder = get_mbox_session(session);
457
458 r = mailmbox_validate_write_lock(folder);
459 if (r != MAILMBOX_NO_ERROR) {
460 res = mbox_error_to_mail_error(r);
461 goto err;
462 }
463
464 r = mailmbox_expunge_no_lock(folder);
465 if (r != MAILMBOX_NO_ERROR) {
466 res = r;
467 goto unlock;
468 }
469
470 cached_data = get_cached_data(session);
471
472 snprintf(filename, PATH_MAX, "%s%c%s%c%s",
473 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR,
474 cached_data->mbox_quoted_mb, MAIL_DIR_SEPARATOR, FILENAME_MAX_UID);
475
476 fd = creat(filename, S_IRUSR | S_IWUSR);
477 if (fd < 0) {
478 res = MAIL_ERROR_FILE;
479 goto err;
480 }
481
482 f = fdopen(fd, "w");
483 if (f == NULL) {
484 close(fd);
485 res = MAIL_ERROR_FILE;
486 goto unlock;
487 }
488
489 mmapstr = mmap_string_new("");
490 if (mmapstr == NULL) {
491 res = MAIL_ERROR_MEMORY;
492 goto close;
493 }
494
495 r = mail_serialize_clear(mmapstr, &cur_token);
496 if (r != MAIL_NO_ERROR) {
497 res = r;
498 goto free_mmapstr;
499 }
500
501 r = mailimf_cache_int_write(mmapstr, &cur_token,
502 folder->mb_written_uid);
503 if (r != MAIL_NO_ERROR) {
504 res = r;
505 goto free_mmapstr;
506 }
507
508 fwrite(mmapstr->str, 1, mmapstr->len, f);
509
510 mmap_string_free(mmapstr);
511 fclose(f);
512 mailmbox_write_unlock(folder);
513
514 return MAIL_NO_ERROR;
515
516 free_mmapstr:
517 mmap_string_free(mmapstr);
518 close:
519 fclose(f);
520 unlock:
521 mailmbox_read_unlock(folder);
522 err:
523 return res;
524}
525
526static int read_max_uid_value(mailsession * session, uint32_t * result)
527{
528 int r;
529 char filename[PATH_MAX];
530 FILE * f;
531 uint32_t written_uid;
532 int res;
533
534 struct mbox_cached_session_state_data * cached_data;
535
536 MMAPString * mmapstr;
537 size_t cur_token;
538 char buf[sizeof(uint32_t)];
539 size_t read_size;
540
541 cached_data = get_cached_data(session);
542
543 snprintf(filename, PATH_MAX, "%s%c%s%c%s",
544 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR,
545 cached_data->mbox_quoted_mb, MAIL_DIR_SEPARATOR, FILENAME_MAX_UID);
546
547 f = fopen(filename, "r");
548 if (f == NULL) {
549 res = MAIL_ERROR_FILE;
550 goto err;
551 }
552
553 read_size = fread(buf, 1, sizeof(uint32_t), f);
554
555 mmapstr = mmap_string_new_len(buf, read_size);
556 if (mmapstr == NULL) {
557 res = MAIL_ERROR_MEMORY;
558 goto close;
559 }
560
561 cur_token = 0;
562
563 r = mailimf_cache_int_read(mmapstr, &cur_token, &written_uid);
564 if (r != MAIL_NO_ERROR) {
565 fclose(f);
566 res = r;
567 goto free_mmapstr;
568 }
569
570 mmap_string_free(mmapstr);
571 fclose(f);
572
573 * result = written_uid;
574
575 return MAIL_NO_ERROR;
576
577 free_mmapstr:
578 mmap_string_free(mmapstr);
579 close:
580 fclose(f);
581 err:
582 return res;
583}
584
585static int mboxdriver_cached_connect_path(mailsession * session, char * path)
586{
587 int r;
588 int res;
589 char * quoted_mb;
590 struct mbox_cached_session_state_data * cached_data;
591 struct mbox_session_state_data * ancestor_data;
592 struct mailmbox_folder * folder;
593 uint32_t written_uid;
594
595 folder = get_mbox_session(session);
596 if (folder != NULL) {
597 res = MAIL_ERROR_BAD_STATE;
598 goto err;
599 }
600
601 r = get_cache_directory(session, path, &quoted_mb);
602 if (r != MAIL_NO_ERROR) {
603 res = r;
604 goto err;
605 }
606
607 cached_data = get_cached_data(session);
608 free_state(cached_data);
609
610 cached_data->mbox_quoted_mb = quoted_mb;
611
612 written_uid = 0;
613 r = read_max_uid_value(session, &written_uid);
614 /* ignore errors */
615
616 ancestor_data = get_ancestor_data(session);
617
618 r = mailmbox_init(path,
619 ancestor_data->mbox_force_read_only,
620 ancestor_data->mbox_force_no_uid,
621 written_uid,
622 &folder);
623
624 if (r != MAILMBOX_NO_ERROR) {
625 cached_data->mbox_quoted_mb = NULL;
626
627 res = mboxdriver_mbox_error_to_mail_error(r);
628 goto free;
629 }
630
631 ancestor_data->mbox_folder = folder;
632
633 return MAIL_NO_ERROR;
634
635 free:
636 free(quoted_mb);
637 err:
638 return res;
639}
640
641
642static int mboxdriver_cached_logout(mailsession * session)
643{
644 struct mbox_cached_session_state_data * cached_data;
645 int r;
646
647 r = write_max_uid_value(session);
648
649 cached_data = get_cached_data(session);
650
651 mbox_flags_store_process(cached_data->mbox_flags_directory,
652 cached_data->mbox_quoted_mb,
653 cached_data->mbox_flags_store);
654
655 r = mailsession_logout(get_ancestor(session));
656 if (r != MAIL_NO_ERROR)
657 return r;
658
659 free_state(cached_data);
660
661 return MAIL_NO_ERROR;
662}
663
664static int mboxdriver_cached_check_folder(mailsession * session)
665{
666 struct mbox_cached_session_state_data * cached_data;
667
668 cached_data = get_cached_data(session);
669
670 mbox_flags_store_process(cached_data->mbox_flags_directory,
671 cached_data->mbox_quoted_mb,
672 cached_data->mbox_flags_store);
673
674 return MAIL_NO_ERROR;
675}
676
677static int mboxdriver_cached_expunge_folder(mailsession * session)
678{
679 struct mailmbox_folder * folder;
680 int res;
681 char filename_flags[PATH_MAX];
682 struct mail_cache_db * cache_db_flags;
683 MMAPString * mmapstr;
684 struct mbox_cached_session_state_data * data;
685 int r;
686 unsigned int i;
687
688 folder = get_mbox_session(session);
689 if (folder == NULL) {
690 res = MAIL_ERROR_BAD_STATE;
691 goto err;
692 }
693
694 data = get_cached_data(session);
695 if (data->mbox_quoted_mb == NULL) {
696 res = MAIL_ERROR_BAD_STATE;
697 goto err;
698 }
699
700 mbox_flags_store_process(data->mbox_flags_directory,
701 data->mbox_quoted_mb,
702 data->mbox_flags_store);
703
704 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
705 data->mbox_flags_directory, MAIL_DIR_SEPARATOR, data->mbox_quoted_mb,
706 MAIL_DIR_SEPARATOR, FLAGS_NAME);
707
708 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
709 if (r < 0) {
710 res = MAIL_ERROR_FILE;
711 goto err;
712 }
713
714 mmapstr = mmap_string_new("");
715 if (mmapstr == NULL) {
716 res = MAIL_ERROR_MEMORY;
717 goto close_db_flags;
718 }
719
720 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
721 struct mailmbox_msg_info * msg_info;
722 struct mail_flags * flags;
723
724 msg_info = carray_get(folder->mb_tab, i);
725 if (msg_info == NULL)
726 continue;
727
728 if (msg_info->msg_deleted)
729 continue;
730
731 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
732 session, msg_info->msg_uid, &flags);
733 if (r != MAIL_NO_ERROR)
734 continue;
735
736 if (flags->fl_flags & MAIL_FLAG_DELETED) {
737 r = mailmbox_delete_msg(folder, msg_info->msg_uid);
738 }
739
740 mail_flags_free(flags);
741 }
742
743 mmap_string_free(mmapstr);
744 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
745
746 r = mailmbox_expunge(folder);
747
748 return MAIL_NO_ERROR;
749
750 close_db_flags:
751 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
752 err:
753 return res;
754}
755
756static int mboxdriver_cached_status_folder(mailsession * session, char * mb,
757 uint32_t * result_messages, uint32_t * result_recent,
758 uint32_t * result_unseen)
759{
760 struct mailmbox_folder * folder;
761 int res;
762 char filename_flags[PATH_MAX];
763 struct mail_cache_db * cache_db_flags;
764 MMAPString * mmapstr;
765 struct mbox_cached_session_state_data * data;
766 int r;
767 unsigned int i;
768 uint32_t recent;
769 uint32_t unseen;
770 uint32_t num;
771
772 num = 0;
773 recent = 0;
774 unseen = 0;
775
776 folder = get_mbox_session(session);
777 if (folder == NULL) {
778 res = MAIL_ERROR_BAD_STATE;
779 goto err;
780 }
781
782 data = get_cached_data(session);
783 if (data->mbox_quoted_mb == NULL) {
784 res = MAIL_ERROR_BAD_STATE;
785 goto err;
786 }
787
788 r = mailmbox_validate_read_lock(folder);
789 if (r != MAIL_NO_ERROR) {
790 res = MAIL_ERROR_BAD_STATE;
791 goto err;
792 }
793
794 mailmbox_read_unlock(folder);
795
796 mbox_flags_store_process(data->mbox_flags_directory, data->mbox_quoted_mb,
797 data->mbox_flags_store);
798
799 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
800 data->mbox_flags_directory, MAIL_DIR_SEPARATOR, data->mbox_quoted_mb,
801 MAIL_DIR_SEPARATOR, FLAGS_NAME);
802
803 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
804 if (r < 0) {
805 res = MAIL_ERROR_FILE;
806 goto err;
807 }
808
809 mmapstr = mmap_string_new("");
810 if (mmapstr == NULL) {
811 res = MAIL_ERROR_MEMORY;
812 goto close_db_flags;
813 }
814
815 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
816 struct mailmbox_msg_info * msg_info;
817 struct mail_flags * flags;
818
819 msg_info = carray_get(folder->mb_tab, i);
820 if (msg_info == NULL)
821 continue;
822
823 if (msg_info->msg_deleted)
824 continue;
825
826 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
827 session, msg_info->msg_uid, &flags);
828 if (r != MAIL_NO_ERROR) {
829 recent ++;
830 unseen ++;
831 num ++;
832 continue;
833 }
834
835 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
836 recent ++;
837 }
838 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
839 unseen ++;
840 }
841
842 num ++;
843
844 mail_flags_free(flags);
845 }
846
847 mmap_string_free(mmapstr);
848 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
849
850 * result_messages = num;
851 * result_recent = recent;
852 * result_unseen = unseen;
853
854 return MAIL_NO_ERROR;
855
856 close_db_flags:
857 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
858 err:
859 return res;
860}
861
862static int mboxdriver_cached_messages_number(mailsession * session, char * mb,
863 uint32_t * result)
864{
865 return mailsession_messages_number(get_ancestor(session), mb, result);
866}
867
868
869static int mboxdriver_cached_recent_number(mailsession * session, char * mb,
870 uint32_t * result)
871{
872 uint32_t messages;
873 uint32_t recent;
874 uint32_t unseen;
875 int r;
876
877 r = mboxdriver_cached_status_folder(session, mb, &messages, &recent, &unseen);
878 if (r != MAIL_NO_ERROR)
879 return r;
880
881 * result = recent;
882
883 return MAIL_NO_ERROR;
884}
885
886static int mboxdriver_cached_unseen_number(mailsession * session, char * mb,
887 uint32_t * result)
888{
889 uint32_t messages;
890 uint32_t recent;
891 uint32_t unseen;
892 int r;
893
894 r = mboxdriver_cached_status_folder(session, mb,
895 &messages, &recent, &unseen);
896 if (r != MAIL_NO_ERROR)
897 return r;
898
899 * result = unseen;
900
901 return MAIL_NO_ERROR;
902}
903
904/* messages operations */
905
906static int mboxdriver_cached_append_message(mailsession * session,
907 char * message, size_t size)
908{
909 return mailsession_append_message(get_ancestor(session), message, size);
910}
911
912static int
913mboxdriver_cached_get_messages_list(mailsession * session,
914 struct mailmessage_list ** result)
915{
916 struct mailmbox_folder * folder;
917 int res;
918
919 folder = get_mbox_session(session);
920 if (folder == NULL) {
921 res = MAIL_ERROR_BAD_STATE;
922 goto err;
923 }
924
925 return mbox_get_uid_messages_list(folder,
926 session, mbox_cached_message_driver, result);
927
928 err:
929 return res;
930}
931
932static int
933get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
934 mailsession * session, uint32_t num,
935 struct mailimf_fields ** result)
936{
937 int r;
938 char keyname[PATH_MAX];
939 struct mailimf_fields * fields;
940 int res;
941 struct mailmbox_msg_info * info;
942 struct mailmbox_folder * folder;
943 chashdatum key;
944 chashdatum data;
945
946 folder = get_mbox_session(session);
947 if (folder == NULL) {
948 res = MAIL_ERROR_BAD_STATE;
949 goto err;
950 }
951
952 key.data = &num;
953 key.len = sizeof(num);
954
955 r = chash_get(folder->mb_hash, &key, &data);
956 if (r < 0) {
957 res = MAIL_ERROR_MSG_NOT_FOUND;
958 goto err;
959 }
960
961 info = data.data;
962
963 snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len);
964
965 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
966 if (r != MAIL_NO_ERROR) {
967 res = r;
968 goto err;
969 }
970
971 * result = fields;
972
973 return MAIL_NO_ERROR;
974
975 err:
976 return res;
977}
978
979static int
980write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
981 mailsession * session, uint32_t num,
982 struct mailimf_fields * fields)
983{
984 int r;
985 char keyname[PATH_MAX];
986 int res;
987 struct mailmbox_msg_info * info;
988 struct mailmbox_folder * folder;
989 chashdatum key;
990 chashdatum data;
991
992 folder = get_mbox_session(session);
993 if (folder == NULL) {
994 res = MAIL_ERROR_BAD_STATE;
995 goto err;
996 }
997
998 key.data = &num;
999 key.len = sizeof(num);
1000
1001 r = chash_get(folder->mb_hash, &key, &data);
1002 if (r < 0) {
1003 res = MAIL_ERROR_MSG_NOT_FOUND;
1004 goto err;
1005 }
1006
1007 info = data.data;
1008
1009 snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len);
1010
1011 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
1012 if (r != MAIL_NO_ERROR) {
1013 res = r;
1014 goto err;
1015 }
1016
1017 return MAIL_NO_ERROR;
1018
1019 err:
1020 return res;
1021}
1022
1023static int
1024mboxdriver_cached_get_envelopes_list(mailsession * session,
1025 struct mailmessage_list * env_list)
1026{
1027 int r;
1028 unsigned int i;
1029 struct mbox_cached_session_state_data * cached_data;
1030 char filename_env[PATH_MAX];
1031 char filename_flags[PATH_MAX];
1032 struct mail_cache_db * cache_db_env;
1033 struct mail_cache_db * cache_db_flags;
1034 MMAPString * mmapstr;
1035 int res;
1036 struct mailmbox_folder * folder;
1037
1038 folder = get_mbox_session(session);
1039 if (folder == NULL) {
1040 res = MAIL_ERROR_BAD_STATE;
1041 goto err;
1042 }
1043
1044 cached_data = get_cached_data(session);
1045 if (cached_data->mbox_quoted_mb == NULL) {
1046 res = MAIL_ERROR_BAD_STATE;
1047 goto err;
1048 }
1049
1050 mbox_flags_store_process(cached_data->mbox_flags_directory,
1051 cached_data->mbox_quoted_mb,
1052 cached_data->mbox_flags_store);
1053
1054 mmapstr = mmap_string_new("");
1055 if (mmapstr == NULL) {
1056 res = MAIL_ERROR_MEMORY;
1057 goto err;
1058 }
1059
1060 snprintf(filename_env, PATH_MAX, "%s%c%s%c%s",
1061 cached_data->mbox_cache_directory, MAIL_DIR_SEPARATOR,
1062 cached_data->mbox_quoted_mb,
1063 MAIL_DIR_SEPARATOR, ENV_NAME);
1064
1065 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1066 if (r < 0) {
1067 res = MAIL_ERROR_MEMORY;
1068 goto free_mmapstr;
1069 }
1070
1071 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
1072 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR,
1073 cached_data->mbox_quoted_mb,
1074 MAIL_DIR_SEPARATOR, FLAGS_NAME);
1075
1076 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1077 if (r < 0) {
1078 res = MAIL_ERROR_FILE;
1079 goto close_db_env;
1080 }
1081
1082 /* fill with cached */
1083
1084 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1085 mailmessage * msg;
1086 struct mailimf_fields * fields;
1087 struct mail_flags * flags;
1088
1089 msg = carray_get(env_list->msg_tab, i);
1090
1091 if (msg->msg_fields == NULL) {
1092 r = get_cached_envelope(cache_db_env, mmapstr, session,
1093 msg->msg_index, &fields);
1094 if (r == MAIL_NO_ERROR) {
1095 msg->msg_cached = TRUE;
1096 msg->msg_fields = fields;
1097 }
1098 }
1099
1100 if (msg->msg_flags == NULL) {
1101 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
1102 session, msg->msg_index,
1103 &flags);
1104 if (r == MAIL_NO_ERROR) {
1105 msg->msg_flags = flags;
1106 }
1107 }
1108 }
1109
1110 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1111 mail_cache_db_close_unlock(filename_env, cache_db_env);
1112
1113 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
1114
1115 if (r != MAIL_NO_ERROR) {
1116 res = r;
1117 goto free_mmapstr;
1118 }
1119
1120 /* add flags */
1121
1122 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1123 mailmessage * msg;
1124
1125 msg = carray_get(env_list->msg_tab, i);
1126
1127 if (msg->msg_flags == NULL)
1128 msg->msg_flags = mail_flags_new_empty();
1129 }
1130
1131 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1132 if (r < 0) {
1133 res = MAIL_ERROR_MEMORY;
1134 goto free_mmapstr;
1135 }
1136
1137 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1138 if (r < 0) {
1139 res = MAIL_ERROR_FILE;
1140 goto close_db_env;
1141 }
1142
1143 /* must write cache */
1144
1145 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1146 mailmessage * msg;
1147
1148 msg = carray_get(env_list->msg_tab, i);
1149
1150 if (msg->msg_fields != NULL) {
1151 if (!msg->msg_cached) {
1152 /* msg->msg_index is the numerical UID of the message */
1153 r = write_cached_envelope(cache_db_env, mmapstr,
1154 session, msg->msg_index, msg->msg_fields);
1155 }
1156 }
1157
1158 if (msg->msg_flags != NULL) {
1159 r = mboxdriver_write_cached_flags(cache_db_flags, mmapstr,
1160 msg->msg_uid, msg->msg_flags);
1161 }
1162 }
1163
1164 /* flush cache */
1165
1166 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
1167
1168 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1169 mail_cache_db_close_unlock(filename_env, cache_db_env);
1170
1171 mmap_string_free(mmapstr);
1172
1173 return MAIL_NO_ERROR;
1174
1175 close_db_env:
1176 mail_cache_db_close_unlock(filename_env, cache_db_env);
1177 free_mmapstr:
1178 mmap_string_free(mmapstr);
1179 err:
1180 return res;
1181}
1182
1183
1184static int
1185mboxdriver_cached_remove_message(mailsession * session, uint32_t num)
1186{
1187 return mailsession_remove_message(get_ancestor(session), num);
1188}
1189
1190static int mboxdriver_cached_get_message(mailsession * session,
1191 uint32_t num, mailmessage ** result)
1192{
1193 mailmessage * msg_info;
1194 int r;
1195
1196 msg_info = mailmessage_new();
1197 if (msg_info == NULL)
1198 return MAIL_ERROR_MEMORY;
1199
1200 r = mailmessage_init(msg_info, session, mbox_cached_message_driver, num, 0);
1201 if (r != MAIL_NO_ERROR) {
1202 mailmessage_free(msg_info);
1203 return r;
1204 }
1205
1206 * result = msg_info;
1207
1208 return MAIL_NO_ERROR;
1209}
1210
1211static int mboxdriver_cached_get_message_by_uid(mailsession * session,
1212 const char * uid,
1213 mailmessage ** result)
1214{
1215 uint32_t num;
1216 char * p;
1217 chashdatum key;
1218 chashdatum data;
1219 struct mailmbox_msg_info * info;
1220 struct mailmbox_folder * folder;
1221 int r;
1222
1223 if (uid == NULL)
1224 return MAIL_ERROR_INVAL;
1225
1226 num = strtoul(uid, &p, 10);
1227 if (p == uid || * p != '-')
1228 return MAIL_ERROR_INVAL;
1229
1230 folder = get_mbox_session(session);
1231 if (folder == NULL)
1232 return MAIL_ERROR_BAD_STATE;
1233
1234 key.data = &num;
1235 key.len = sizeof(num);
1236
1237 r = chash_get(folder->mb_hash, &key, &data);
1238 if (r == 0) {
1239 char * body_len_p = p + 1;
1240 size_t body_len;
1241
1242 info = data.data;
1243 /* Check if the cached message has the same UID */
1244 body_len = strtoul(body_len_p, &p, 10);
1245 if (p == body_len_p || * p != '\0')
1246 return MAIL_ERROR_INVAL;
1247
1248 if (body_len == info->msg_body_len)
1249 return mboxdriver_cached_get_message(session, num, result);
1250 }
1251
1252 return MAIL_ERROR_MSG_NOT_FOUND;
1253}
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached.h b/kmicromail/libetpan/generic/mboxdriver_cached.h
new file mode 100644
index 0000000..b0d8dbf
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached.h
@@ -0,0 +1,54 @@
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#ifndef MBOXDRIVER_CACHED_H
37
38#define MBOXDRIVER_CACHED_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/mboxdriver_types.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48extern mailsession_driver * mbox_cached_session_driver;
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached_message.c b/kmicromail/libetpan/generic/mboxdriver_cached_message.c
new file mode 100644
index 0000000..6d92b22
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached_message.c
@@ -0,0 +1,360 @@
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 "mboxdriver_cached_message.h"
37
38#include "mailmessage_tools.h"
39#include "mboxdriver_tools.h"
40#include "mboxdriver_cached.h"
41#include "mboxdriver.h"
42#include "mailmbox.h"
43#include "mail_cache_db.h"
44#include "generic_cache.h"
45
46#include <unistd.h>
47#include <sys/mman.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <string.h>
52#include <stdlib.h>
53
54static int mbox_prefetch(mailmessage * msg_info);
55
56static void mbox_prefetch_free(struct generic_message_t * msg);
57
58static int mbox_initialize(mailmessage * msg_info);
59
60static void mbox_uninitialize(mailmessage * msg_info);
61
62static void mbox_flush(mailmessage * msg_info);
63
64static void mbox_check(mailmessage * msg_info);
65
66static int mbox_fetch_size(mailmessage * msg_info,
67 size_t * result);
68
69static int mbox_get_flags(mailmessage * msg_info,
70 struct mail_flags ** result);
71
72static int mbox_fetch_header(mailmessage * msg_info,
73 char ** result,
74 size_t * result_len);
75
76static mailmessage_driver local_mbox_cached_message_driver = {
77 .msg_name = "mbox-cached",
78
79 .msg_initialize = mbox_initialize,
80 .msg_uninitialize = mbox_uninitialize,
81
82 .msg_flush = mbox_flush,
83 .msg_check = mbox_check,
84
85 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
86
87 .msg_fetch = mailmessage_generic_fetch,
88 .msg_fetch_header = mbox_fetch_header,
89 .msg_fetch_body = mailmessage_generic_fetch_body,
90 .msg_fetch_size = mbox_fetch_size,
91 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
92 .msg_fetch_section = mailmessage_generic_fetch_section,
93 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
94 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
95 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
96 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
97
98 .msg_get_flags = mbox_get_flags,
99};
100
101mailmessage_driver * mbox_cached_message_driver =
102&local_mbox_cached_message_driver;
103
104static inline struct mbox_cached_session_state_data *
105get_cached_session_data(mailmessage * msg)
106{
107 return msg->msg_session->sess_data;
108}
109
110static inline mailsession * get_ancestor_session(mailmessage * msg)
111{
112 return get_cached_session_data(msg)->mbox_ancestor;
113}
114
115static inline struct mbox_session_state_data *
116get_ancestor_session_data(mailmessage * msg)
117{
118 return get_ancestor_session(msg)->sess_data;
119}
120
121static inline struct mailmbox_folder *
122get_mbox_session(mailmessage * msg)
123{
124 return get_ancestor_session_data(msg)->mbox_folder;
125}
126
127static int mbox_prefetch(mailmessage * msg_info)
128{
129 struct generic_message_t * msg;
130 int r;
131 char * msg_content;
132 size_t msg_length;
133
134 r = mboxdriver_fetch_msg(get_ancestor_session(msg_info),
135 msg_info->msg_index,
136 &msg_content, &msg_length);
137 if (r != MAIL_NO_ERROR)
138 return r;
139
140 msg = msg_info->msg_data;
141
142 msg->msg_message = msg_content;
143 msg->msg_length = msg_length;
144
145 return MAIL_NO_ERROR;
146}
147
148static void mbox_prefetch_free(struct generic_message_t * msg)
149{
150 if (msg->msg_message != NULL) {
151 mmap_string_unref(msg->msg_message);
152 msg->msg_message = NULL;
153 }
154}
155
156static int mbox_initialize(mailmessage * msg_info)
157{
158 struct generic_message_t * msg;
159 int r;
160 char * uid;
161 char static_uid[PATH_MAX];
162 struct mailmbox_msg_info * info;
163 struct mailmbox_folder * folder;
164 int res;
165 chashdatum key;
166 chashdatum data;
167
168 folder = get_mbox_session(msg_info);
169 if (folder == NULL) {
170 res = MAIL_ERROR_BAD_STATE;
171 goto err;
172 }
173
174 key.data = (char *) &msg_info->msg_index;
175 key.len = sizeof(msg_info->msg_index);
176
177 r = chash_get(folder->mb_hash, &key, &data);
178 if (r < 0) {
179 res = MAIL_ERROR_MSG_NOT_FOUND;
180 goto err;
181 }
182
183 info = (struct mailmbox_msg_info *) data.data;
184
185 snprintf(static_uid, PATH_MAX, "%u-%u", msg_info->msg_index, info->msg_body_len);
186 uid = strdup(static_uid);
187 if (uid == NULL) {
188 res = MAIL_ERROR_MEMORY;
189 goto err;
190 }
191
192 r = mailmessage_generic_initialize(msg_info);
193 if (r != MAIL_NO_ERROR) {
194 free(uid);
195 res = r;
196 goto err;
197 }
198
199 msg = msg_info->msg_data;
200
201 msg->msg_prefetch = mbox_prefetch;
202 msg->msg_prefetch_free = mbox_prefetch_free;
203 msg_info->msg_uid = uid;
204
205 return MAIL_NO_ERROR;
206
207 err:
208 return res;
209}
210
211static void mbox_uninitialize(mailmessage * msg_info)
212{
213 mailmessage_generic_uninitialize(msg_info);
214}
215
216#define FLAGS_NAME "flags.db"
217
218static void mbox_flush(mailmessage * msg_info)
219{
220 mailmessage_generic_flush(msg_info);
221}
222
223static void mbox_check(mailmessage * msg_info)
224{
225 int r;
226
227 if (msg_info->msg_flags != NULL) {
228 r = mail_flags_store_set(get_cached_session_data(msg_info)->mbox_flags_store,
229 msg_info);
230 /* ignore errors */
231 }
232}
233
234
235static int mbox_fetch_size(mailmessage * msg_info,
236 size_t * result)
237{
238 int r;
239 size_t size;
240
241 r = mboxdriver_fetch_size(get_ancestor_session(msg_info),
242 msg_info->msg_index, &size);
243 if (r != MAIL_NO_ERROR)
244 return r;
245
246 * result = size;
247
248 return MAIL_NO_ERROR;
249}
250
251static int mbox_get_flags(mailmessage * msg_info,
252 struct mail_flags ** result)
253{
254 int r;
255 struct mail_flags * flags;
256 struct mail_cache_db * cache_db_flags;
257 char filename_flags[PATH_MAX];
258 int res;
259 struct mbox_cached_session_state_data * cached_data;
260 MMAPString * mmapstr;
261 struct mailmbox_folder * folder;
262
263 if (msg_info->msg_flags != NULL) {
264 * result = msg_info->msg_flags;
265
266 return MAIL_NO_ERROR;
267 }
268
269 flags = mail_flags_store_get(get_cached_session_data(msg_info)->mbox_flags_store,
270 msg_info->msg_index);
271
272 if (flags == NULL) {
273 folder = get_mbox_session(msg_info);
274 if (folder == NULL) {
275 res = MAIL_ERROR_BAD_STATE;
276 goto err;
277 }
278
279 cached_data = get_cached_session_data(msg_info);
280 if (cached_data->mbox_quoted_mb == NULL) {
281 res = MAIL_ERROR_BAD_STATE;
282 goto err;
283 }
284
285 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
286 cached_data->mbox_flags_directory,
287 cached_data->mbox_quoted_mb, FLAGS_NAME);
288
289 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
290 if (r < 0) {
291 res = MAIL_ERROR_MEMORY;
292 goto err;
293 }
294
295 mmapstr = mmap_string_new("");
296 if (mmapstr == NULL) {
297 res = MAIL_ERROR_MEMORY;
298 goto close_db_flags;
299 }
300
301 if (msg_info->msg_index > folder->mb_written_uid) {
302 flags = mail_flags_new_empty();
303 }
304 else {
305 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
306 msg_info->msg_session,
307 msg_info->msg_index, &flags);
308 if (r != MAIL_NO_ERROR) {
309 flags = mail_flags_new_empty();
310 if (flags == NULL) {
311 res = MAIL_ERROR_MEMORY;
312 goto free_mmapstr;
313 }
314 }
315 }
316
317 mmap_string_free(mmapstr);
318 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
319 }
320
321 msg_info->msg_flags = flags;
322
323 * result = flags;
324
325 return MAIL_NO_ERROR;
326
327 free_mmapstr:
328 mmap_string_free(mmapstr);
329 close_db_flags:
330 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
331 err:
332 return res;
333}
334
335static int mbox_fetch_header(mailmessage * msg_info,
336 char ** result,
337 size_t * result_len)
338{
339 struct generic_message_t * msg;
340 int r;
341 char * msg_content;
342 size_t msg_length;
343
344 msg = msg_info->msg_data;
345 if (msg->msg_message != NULL) {
346 return mailmessage_generic_fetch_header(msg_info, result, result_len);
347 }
348 else {
349 r = mboxdriver_fetch_header(get_ancestor_session(msg_info),
350 msg_info->msg_index,
351 &msg_content, &msg_length);
352 if (r != MAIL_NO_ERROR)
353 return r;
354
355 * result = msg_content;
356 * result_len = msg_length;
357
358 return MAIL_NO_ERROR;
359 }
360}
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached_message.h b/kmicromail/libetpan/generic/mboxdriver_cached_message.h
new file mode 100644
index 0000000..a6673b3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached_message.h
@@ -0,0 +1,52 @@
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#ifndef MBOXDRIVER_CACHED_MESSAGE_H
37
38#define MBOXDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/mailmessage.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mbox_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_message.c b/kmicromail/libetpan/generic/mboxdriver_message.c
new file mode 100644
index 0000000..da9a65d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_message.c
@@ -0,0 +1,225 @@
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 "mhdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "mboxdriver_tools.h"
40#include "mboxdriver.h"
41#include "mailmbox.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 mbox_prefetch(mailmessage * msg_info);
52
53static void mbox_prefetch_free(struct generic_message_t * msg);
54
55static int mbox_initialize(mailmessage * msg_info);
56
57static int mbox_fetch_size(mailmessage * msg_info,
58 size_t * result);
59
60static int mbox_fetch_header(mailmessage * msg_info,
61 char ** result,
62 size_t * result_len);
63
64static mailmessage_driver local_mbox_message_driver = {
65 .msg_name = "mbox",
66
67 .msg_initialize = mbox_initialize,
68 .msg_uninitialize = mailmessage_generic_uninitialize,
69
70 .msg_flush = mailmessage_generic_flush,
71 .msg_check = NULL,
72
73 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
74
75 .msg_fetch = mailmessage_generic_fetch,
76 .msg_fetch_header = mbox_fetch_header,
77 .msg_fetch_body = mailmessage_generic_fetch_body,
78 .msg_fetch_size = mbox_fetch_size,
79 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
80 .msg_fetch_section = mailmessage_generic_fetch_section,
81 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
82 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
83 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
84 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
85
86 .msg_get_flags = NULL,
87};
88
89mailmessage_driver * mbox_message_driver = &local_mbox_message_driver;
90
91static inline struct mbox_session_state_data * get_data(mailmessage * msg)
92{
93 return msg->msg_session->sess_data;
94}
95
96static inline struct mailmbox_folder * get_mbox_session(mailmessage * msg)
97{
98 return get_data(msg)->mbox_folder;
99}
100
101
102static int mbox_prefetch(mailmessage * msg_info)
103{
104 struct generic_message_t * msg;
105 int r;
106 char * msg_content;
107 size_t msg_length;
108
109 r = mboxdriver_fetch_msg(msg_info->msg_session, msg_info->msg_index,
110 &msg_content, &msg_length);
111 if (r != MAIL_NO_ERROR)
112 return r;
113
114 msg = msg_info->msg_data;
115
116 msg->msg_message = msg_content;
117 msg->msg_length = msg_length;
118
119 return MAIL_NO_ERROR;
120}
121
122static void mbox_prefetch_free(struct generic_message_t * msg)
123{
124 if (msg->msg_message != NULL) {
125 mmap_string_unref(msg->msg_message);
126 msg->msg_message = NULL;
127 }
128}
129
130static int mbox_initialize(mailmessage * msg_info)
131{
132 struct generic_message_t * msg;
133 int r;
134 char * uid;
135 char static_uid[PATH_MAX];
136 struct mailmbox_msg_info * info;
137 struct mailmbox_folder * folder;
138 int res;
139 chashdatum key;
140 chashdatum data;
141
142 folder = get_mbox_session(msg_info);
143 if (folder == NULL) {
144 res = MAIL_ERROR_BAD_STATE;
145 goto err;
146 }
147
148 key.data = &msg_info->msg_index;
149 key.len = sizeof(msg_info->msg_index);
150
151 r = chash_get(folder->mb_hash, &key, &data);
152 if (r < 0) {
153 res = MAIL_ERROR_MSG_NOT_FOUND;
154 goto err;
155 }
156
157 info = data.data;
158
159 snprintf(static_uid, PATH_MAX, "%u-%u",
160 msg_info->msg_index, info->msg_body_len);
161 uid = strdup(static_uid);
162 if (uid == NULL) {
163 res = MAIL_ERROR_MEMORY;
164 goto err;
165 }
166
167 r = mailmessage_generic_initialize(msg_info);
168 if (r != MAIL_NO_ERROR) {
169 free(uid);
170 res = r;
171 goto err;
172 }
173
174 msg = msg_info->msg_data;
175 msg->msg_prefetch = mbox_prefetch;
176 msg->msg_prefetch_free = mbox_prefetch_free;
177 msg_info->msg_uid = uid;
178
179 return MAIL_NO_ERROR;
180
181 err:
182 return res;
183}
184
185static int mbox_fetch_size(mailmessage * msg_info,
186 size_t * result)
187{
188 int r;
189 size_t size;
190
191 r = mboxdriver_fetch_size(msg_info->msg_session,
192 msg_info->msg_index, &size);
193 if (r != MAIL_NO_ERROR)
194 return r;
195
196 * result = size;
197
198 return MAIL_NO_ERROR;
199}
200
201static int mbox_fetch_header(mailmessage * msg_info,
202 char ** result,
203 size_t * result_len)
204{
205 struct generic_message_t * msg;
206 int r;
207 char * msg_content;
208 size_t msg_length;
209
210 msg = msg_info->msg_data;
211 if (msg->msg_message != NULL) {
212 return mailmessage_generic_fetch_header(msg_info, result, result_len);
213 }
214 else {
215 r = mboxdriver_fetch_header(msg_info->msg_session, msg_info->msg_index,
216 &msg_content, &msg_length);
217 if (r != MAIL_NO_ERROR)
218 return r;
219
220 * result = msg_content;
221 * result_len = msg_length;
222
223 return MAIL_NO_ERROR;
224 }
225}
diff --git a/kmicromail/libetpan/generic/mboxdriver_message.h b/kmicromail/libetpan/generic/mboxdriver_message.h
new file mode 100644
index 0000000..cdabd23
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_message.h
@@ -0,0 +1,52 @@
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#ifndef MBOXDRIVER_MESSAGE_H
37
38#define MBOXDRIVER_MESSAGE_H
39
40#include <libetpan/mboxdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mbox_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_tools.c b/kmicromail/libetpan/generic/mboxdriver_tools.c
new file mode 100644
index 0000000..1e27798
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_tools.c
@@ -0,0 +1,434 @@
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 "mboxdriver_tools.h"
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <unistd.h>
42
43#include "maildriver_types.h"
44#include "mailmbox.h"
45#include "mboxdriver_cached.h"
46#include "mboxdriver.h"
47#include "generic_cache.h"
48#include "mailmessage.h"
49#include "imfcache.h"
50#include "mail_cache_db.h"
51
52static inline struct mbox_session_state_data *
53session_get_data(mailsession * session)
54{
55 return session->sess_data;
56}
57
58static inline struct mailmbox_folder *
59session_get_mbox_session(mailsession * session)
60{
61 return session_get_data(session)->mbox_folder;
62}
63
64static inline struct mbox_cached_session_state_data *
65cached_session_get_data(mailsession * session)
66{
67 return session->sess_data;
68}
69
70static inline mailsession *
71cached_session_get_ancestor(mailsession * session)
72{
73 return cached_session_get_data(session)->mbox_ancestor;
74}
75
76static inline struct mbox_session_state_data *
77cached_session_get_ancestor_data(mailsession * session)
78{
79 return cached_session_get_ancestor(session)->sess_data;
80}
81
82static inline struct mailmbox_folder *
83cached_session_get_mbox_session(mailsession * session)
84{
85 return session_get_mbox_session(cached_session_get_ancestor(session));
86}
87
88
89int mboxdriver_mbox_error_to_mail_error(int error)
90{
91 switch (error) {
92 case MAILMBOX_NO_ERROR:
93 return MAIL_NO_ERROR;
94
95 case MAILMBOX_ERROR_PARSE:
96 return MAIL_ERROR_PARSE;
97
98 case MAILMBOX_ERROR_INVAL:
99 return MAIL_ERROR_INVAL;
100
101 case MAILMBOX_ERROR_FILE_NOT_FOUND:
102 return MAIL_ERROR_PARSE;
103
104 case MAILMBOX_ERROR_MEMORY:
105 return MAIL_ERROR_MEMORY;
106
107 case MAILMBOX_ERROR_TEMPORARY_FILE:
108 return MAIL_ERROR_PARSE;
109
110 case MAILMBOX_ERROR_FILE:
111 return MAIL_ERROR_FILE;
112
113 case MAILMBOX_ERROR_MSG_NOT_FOUND:
114 return MAIL_ERROR_MSG_NOT_FOUND;
115
116 case MAILMBOX_ERROR_READONLY:
117 return MAIL_ERROR_READONLY;
118
119 default:
120 return MAIL_ERROR_INVAL;
121 }
122}
123
124int mboxdriver_fetch_msg(mailsession * session, uint32_t index,
125 char ** result, size_t * result_len)
126{
127 int r;
128 char * msg_content;
129 size_t msg_length;
130 struct mailmbox_folder * folder;
131
132 folder = session_get_mbox_session(session);
133 if (folder == NULL)
134 return MAIL_ERROR_BAD_STATE;
135
136 r = mailmbox_fetch_msg(folder, index, &msg_content, &msg_length);
137 if (r != MAILMBOX_NO_ERROR)
138 return mboxdriver_mbox_error_to_mail_error(r);
139
140 * result = msg_content;
141 * result_len = msg_length;
142
143 return MAIL_NO_ERROR;
144}
145
146
147int mboxdriver_fetch_size(mailsession * session, uint32_t index,
148 size_t * result)
149{
150 struct mailmbox_folder * folder;
151 int r;
152 char * data;
153 size_t len;
154 int res;
155
156 folder = session_get_mbox_session(session);
157 if (folder == NULL) {
158 res = MAIL_ERROR_FETCH;
159 goto err;
160 }
161
162 r = mailmbox_validate_read_lock(folder);
163 if (r != MAILMBOX_NO_ERROR) {
164 res = mboxdriver_mbox_error_to_mail_error(r);
165 goto err;
166 }
167
168 r = mailmbox_fetch_msg_no_lock(folder, index, &data, &len);
169 if (r != MAILMBOX_NO_ERROR) {
170 res = mboxdriver_mbox_error_to_mail_error(r);
171 goto unlock;
172 }
173
174 mailmbox_read_unlock(folder);
175
176 * result = len;
177
178 return MAIL_NO_ERROR;
179
180 unlock:
181 mailmbox_read_unlock(folder);
182 err:
183 return res;
184}
185
186
187int
188mboxdriver_get_cached_flags(struct mail_cache_db * cache_db,
189 MMAPString * mmapstr,
190 mailsession * session,
191 uint32_t num,
192 struct mail_flags ** result)
193{
194 int r;
195 char keyname[PATH_MAX];
196 struct mail_flags * flags;
197 int res;
198 struct mailmbox_msg_info * info;
199 struct mailmbox_folder * folder;
200 chashdatum key;
201 chashdatum data;
202
203 folder = cached_session_get_mbox_session(session);
204 if (folder == NULL) {
205 res = MAIL_ERROR_BAD_STATE;
206 goto err;
207 }
208
209 key.data = &num;
210 key.len = sizeof(num);
211
212 r = chash_get(folder->mb_hash, &key, &data);
213 if (r < 0) {
214 res = MAIL_ERROR_MSG_NOT_FOUND;
215 goto err;
216 }
217
218 info = data.data;
219
220 snprintf(keyname, PATH_MAX, "%u-%u-flags", num, info->msg_body_len);
221
222 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
223 if (r != MAIL_NO_ERROR) {
224 res = r;
225 goto err;
226 }
227
228 * result = flags;
229
230 return MAIL_NO_ERROR;
231
232 err:
233 return res;
234}
235
236int
237mboxdriver_write_cached_flags(struct mail_cache_db * cache_db,
238 MMAPString * mmapstr,
239 char * uid,
240 struct mail_flags * flags)
241{
242 int r;
243 char keyname[PATH_MAX];
244 int res;
245
246 snprintf(keyname, PATH_MAX, "%s-flags", uid);
247
248 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
249 if (r != MAIL_NO_ERROR) {
250 res = r;
251 goto err;
252 }
253
254 return MAIL_NO_ERROR;
255
256 err:
257 return res;
258}
259
260
261int mboxdriver_fetch_header(mailsession * session, uint32_t index,
262 char ** result, size_t * result_len)
263{
264 int r;
265 char * msg_content;
266 size_t msg_length;
267 struct mailmbox_folder * folder;
268
269 folder = session_get_mbox_session(session);
270 if (folder == NULL)
271 return MAIL_ERROR_BAD_STATE;
272
273 r = mailmbox_fetch_msg_headers(folder, index, &msg_content, &msg_length);
274 if (r != MAILMBOX_NO_ERROR)
275 return mboxdriver_mbox_error_to_mail_error(r);
276
277 * result = msg_content;
278 * result_len = msg_length;
279
280 return MAIL_NO_ERROR;
281}
282
283int mbox_get_locked_messages_list(struct mailmbox_folder * folder,
284 mailsession * session,
285 mailmessage_driver * driver,
286 int (* lock)(struct mailmbox_folder *),
287 int (* unlock)(struct mailmbox_folder *),
288 struct mailmessage_list ** result)
289{
290 struct mailmessage_list * env_list;
291 unsigned int i;
292 int r;
293 int res;
294 carray * tab;
295
296 tab = carray_new(128);
297 if (tab == NULL) {
298 res = MAIL_ERROR_MEMORY;
299 goto err;
300 }
301
302 r = lock(folder);
303 if (r != MAIL_NO_ERROR) {
304 res = r;
305 goto free;
306 }
307
308 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
309 struct mailmbox_msg_info * msg_info;
310 mailmessage * msg;
311
312 msg_info = carray_get(folder->mb_tab, i);
313 if (msg_info == NULL)
314 continue;
315
316 if (msg_info->msg_deleted)
317 continue;
318
319 msg = mailmessage_new();
320 if (msg == NULL) {
321 res = MAIL_ERROR_MEMORY;
322 goto unlock;
323 }
324
325 r = mailmessage_init(msg, session, driver, msg_info->msg_uid,
326 msg_info->msg_size - msg_info->msg_start_len);
327 if (r != MAIL_NO_ERROR) {
328 res = r;
329 goto unlock;
330 }
331
332 r = carray_add(tab, msg, NULL);
333 if (r < 0) {
334 mailmessage_free(msg);
335 res = MAIL_ERROR_MEMORY;
336 goto unlock;
337 }
338 }
339
340 env_list = mailmessage_list_new(tab);
341 if (env_list == NULL) {
342 res = MAIL_ERROR_MEMORY;
343 goto unlock;
344 }
345
346 unlock(folder);
347
348 * result = env_list;
349
350 return MAIL_NO_ERROR;
351
352 unlock:
353 unlock(folder);
354 free:
355 for(i = 0 ; i < carray_count(tab) ; i ++)
356 mailmessage_free(carray_get(tab, i));
357 carray_free(tab);
358 err:
359 return res;
360}
361
362static int release_read_mbox(struct mailmbox_folder * folder)
363{
364 int r;
365
366 r = mailmbox_read_unlock(folder);
367 return mboxdriver_mbox_error_to_mail_error(r);
368}
369
370static int acquire_read_mbox(struct mailmbox_folder * folder)
371{
372 int r;
373
374 r = mailmbox_validate_read_lock(folder);
375 return mboxdriver_mbox_error_to_mail_error(r);
376}
377
378static int release_write_mbox(struct mailmbox_folder * folder)
379{
380 int r;
381
382 r = mailmbox_write_unlock(folder);
383 return mboxdriver_mbox_error_to_mail_error(r);
384}
385
386static int acquire_write_mbox(struct mailmbox_folder * folder)
387{
388 int r;
389 int res;
390
391 r = mailmbox_validate_write_lock(folder);
392 if (r != MAILMBOX_NO_ERROR) {
393 res = mboxdriver_mbox_error_to_mail_error(r);
394 goto err;
395 }
396
397 if (folder->mb_written_uid < folder->mb_max_uid) {
398 r = mailmbox_expunge_no_lock(folder);
399 if (r != MAILMBOX_NO_ERROR) {
400 res = mboxdriver_mbox_error_to_mail_error(r);
401 goto unlock;
402 }
403 }
404
405 return MAIL_NO_ERROR;
406
407 unlock:
408 mailmbox_write_unlock(folder);
409 err:
410 return res;
411}
412
413/* get message list with all valid written UID */
414
415int mbox_get_uid_messages_list(struct mailmbox_folder * folder,
416 mailsession * session,
417 mailmessage_driver * driver,
418 struct mailmessage_list ** result)
419{
420 return mbox_get_locked_messages_list(folder, session, driver,
421 acquire_write_mbox, release_write_mbox, result);
422}
423
424
425/* get message list */
426
427int mbox_get_messages_list(struct mailmbox_folder * folder,
428 mailsession * session,
429 mailmessage_driver * driver,
430 struct mailmessage_list ** result)
431{
432 return mbox_get_locked_messages_list(folder, session, driver,
433 acquire_read_mbox, release_read_mbox, result);
434}
diff --git a/kmicromail/libetpan/generic/mboxdriver_tools.h b/kmicromail/libetpan/generic/mboxdriver_tools.h
new file mode 100644
index 0000000..3ec82ec
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_tools.h
@@ -0,0 +1,85 @@
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#ifndef MBOXDRIVER_TOOLS_H
37
38#define MBOXDRIVER_TOOLS_H
39
40#include "mail_cache_db_types.h"
41#include "mboxdriver_types.h"
42#include "mailmbox.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48int mboxdriver_mbox_error_to_mail_error(int error);
49
50int mboxdriver_fetch_msg(mailsession * session, uint32_t index,
51 char ** result, size_t * result_len);
52
53int mboxdriver_fetch_size(mailsession * session, uint32_t index,
54 size_t * result);
55
56int
57mboxdriver_get_cached_flags(struct mail_cache_db * cache_db,
58 MMAPString * mmapstr,
59 mailsession * session,
60 uint32_t num,
61 struct mail_flags ** result);
62
63int
64mboxdriver_write_cached_flags(struct mail_cache_db * cache_db,
65 MMAPString * mmapstr,
66 char * uid, struct mail_flags * flags);
67
68int mbox_get_uid_messages_list(struct mailmbox_folder * folder,
69 mailsession * session,
70 mailmessage_driver * driver,
71 struct mailmessage_list ** result);
72
73int mbox_get_messages_list(struct mailmbox_folder * folder,
74 mailsession * session,
75 mailmessage_driver * driver,
76 struct mailmessage_list ** result);
77
78int mboxdriver_fetch_header(mailsession * session, uint32_t index,
79 char ** result, size_t * result_len);
80
81#ifdef __cplusplus
82}
83#endif
84
85#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_types.h b/kmicromail/libetpan/generic/mboxdriver_types.h
new file mode 100644
index 0000000..be31ea3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_types.h
@@ -0,0 +1,107 @@
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#ifndef MBOXDRIVER_TYPES_H
37
38#define MBOXDRIVER_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/mailmbox.h>
42#include <libetpan/mailstorage_types.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/* mbox driver */
49
50enum {
51 MBOXDRIVER_SET_READ_ONLY = 1,
52 MBOXDRIVER_SET_NO_UID,
53};
54
55struct mbox_session_state_data {
56 struct mailmbox_folder * mbox_folder;
57 int mbox_force_read_only;
58 int mbox_force_no_uid;
59};
60
61/* cached version */
62
63enum {
64 /* the mapping of the parameters should be the same as for mbox */
65 MBOXDRIVER_CACHED_SET_READ_ONLY = 1,
66 MBOXDRIVER_CACHED_SET_NO_UID,
67 /* cache specific */
68 MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY,
69 MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY,
70};
71
72struct mbox_cached_session_state_data {
73 mailsession * mbox_ancestor;
74 char * mbox_quoted_mb;
75 char mbox_cache_directory[PATH_MAX];
76 char mbox_flags_directory[PATH_MAX];
77 struct mail_flags_store * mbox_flags_store;
78};
79
80/* mbox storage */
81
82/*
83 mbox_mailstorage is the state data specific to the mbox storage.
84
85 - pathname is the filename that contains the mailbox.
86
87 - cached if this value is != 0, a persistant cache will be
88 stored on local system.
89
90 - cache_directory is the location of the cache.
91
92 - flags_directory is the location of the flags.
93*/
94
95struct mbox_mailstorage {
96 char * mbox_pathname;
97
98 int mbox_cached;
99 char * mbox_cache_directory;
100 char * mbox_flags_directory;
101};
102
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/kmicromail/libetpan/generic/mboxstorage.c b/kmicromail/libetpan/generic/mboxstorage.c
new file mode 100644
index 0000000..0a7dc93
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxstorage.c
@@ -0,0 +1,192 @@
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 "mboxstorage.h"
37
38#include "mail.h"
39#include "mailmessage.h"
40#include "mboxdriver.h"
41#include "mboxdriver_cached.h"
42#include "maildriver.h"
43
44#include <stdlib.h>
45#include <string.h>
46
47/* mbox storage */
48
49static int mbox_mailstorage_connect(struct mailstorage * storage);
50static int
51mbox_mailstorage_get_folder_session(struct mailstorage * storage,
52 char * pathname, mailsession ** result);
53static void mbox_mailstorage_uninitialize(struct mailstorage * storage);
54
55static mailstorage_driver mbox_mailstorage_driver = {
56 .sto_name = "mbox",
57 .sto_connect = mbox_mailstorage_connect,
58 .sto_get_folder_session = mbox_mailstorage_get_folder_session,
59 .sto_uninitialize = mbox_mailstorage_uninitialize,
60};
61
62int mbox_mailstorage_init(struct mailstorage * storage,
63 char * mbox_pathname, int mbox_cached,
64 char * mbox_cache_directory, char * mbox_flags_directory)
65{
66 struct mbox_mailstorage * mbox_storage;
67
68 mbox_storage = malloc(sizeof(struct mbox_mailstorage));
69 if (mbox_storage == NULL)
70 goto err;
71
72 mbox_storage->mbox_pathname = strdup(mbox_pathname);
73 if (mbox_storage->mbox_pathname == NULL)
74 goto free;
75
76 mbox_storage->mbox_cached = mbox_cached;
77
78 if (mbox_cached && (mbox_cache_directory != NULL) &&
79 (mbox_flags_directory != NULL)) {
80 mbox_storage->mbox_cache_directory = strdup(mbox_cache_directory);
81 if (mbox_storage->mbox_cache_directory == NULL)
82 goto free_pathname;
83
84 mbox_storage->mbox_flags_directory = strdup(mbox_flags_directory);
85 if (mbox_storage->mbox_flags_directory == NULL)
86 goto free_cache_directory;
87 }
88 else {
89 mbox_storage->mbox_cached = FALSE;
90 mbox_storage->mbox_cache_directory = NULL;
91 mbox_storage->mbox_flags_directory = NULL;
92 }
93
94 storage->sto_data = mbox_storage;
95 storage->sto_driver = &mbox_mailstorage_driver;
96
97 return MAIL_NO_ERROR;
98
99 free_cache_directory:
100 free(mbox_storage->mbox_cache_directory);
101 free_pathname:
102 free(mbox_storage->mbox_pathname);
103 free:
104 free(mbox_storage);
105 err:
106 return MAIL_ERROR_MEMORY;
107}
108
109static void mbox_mailstorage_uninitialize(struct mailstorage * storage)
110{
111 struct mbox_mailstorage * mbox_storage;
112
113 mbox_storage = storage->sto_data;
114 if (mbox_storage->mbox_flags_directory != NULL)
115 free(mbox_storage->mbox_flags_directory);
116 if (mbox_storage->mbox_cache_directory != NULL)
117 free(mbox_storage->mbox_cache_directory);
118 free(mbox_storage->mbox_pathname);
119 free(mbox_storage);
120
121 storage->sto_data = NULL;
122}
123
124static int mbox_mailstorage_connect(struct mailstorage * storage)
125{
126 struct mbox_mailstorage * mbox_storage;
127 mailsession_driver * driver;
128 int r;
129 int res;
130 mailsession * session;
131
132 mbox_storage = storage->sto_data;
133
134 if (mbox_storage->mbox_cached)
135 driver = mbox_cached_session_driver;
136 else
137 driver = mbox_session_driver;
138
139 session = mailsession_new(driver);
140 if (session == NULL) {
141 res = MAIL_ERROR_MEMORY;
142 goto err;
143 }
144
145 if (mbox_storage->mbox_cached) {
146 r = mailsession_parameters(session,
147 MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY,
148 mbox_storage->mbox_cache_directory);
149 if (r != MAIL_NO_ERROR) {
150 res = r;
151 goto free;
152 }
153
154 r = mailsession_parameters(session,
155 MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY,
156 mbox_storage->mbox_flags_directory);
157 if (r != MAIL_NO_ERROR) {
158 res = r;
159 goto free;
160 }
161 }
162
163 r = mailsession_connect_path(session, mbox_storage->mbox_pathname);
164 switch (r) {
165 case MAIL_NO_ERROR_NON_AUTHENTICATED:
166 case MAIL_NO_ERROR_AUTHENTICATED:
167 case MAIL_NO_ERROR:
168 break;
169 default:
170 res = r;
171 goto free;
172 }
173
174 storage->sto_session = session;
175
176 return MAIL_NO_ERROR;
177
178 free:
179 mailsession_free(session);
180 err:
181 return res;
182}
183
184static int
185mbox_mailstorage_get_folder_session(struct mailstorage * storage,
186 char * pathname, mailsession ** result)
187{
188 * result = storage->sto_session;
189
190 return MAIL_NO_ERROR;
191}
192
diff --git a/kmicromail/libetpan/generic/mboxstorage.h b/kmicromail/libetpan/generic/mboxstorage.h
new file mode 100644
index 0000000..e5e83ce
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxstorage.h
@@ -0,0 +1,69 @@
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#ifndef MBOXSTORAGE_H
37
38#define MBOXSTORAGE_H
39
40#include <libetpan/mboxdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mbox_mailstorage_init is the constructor for a mbox storage.
48
49 @param storage this is the storage to initialize.
50
51 @param pathname is the filename that contains the mailbox.
52
53 @param cached if this value is != 0, a persistant cache will be
54 stored on local system.
55
56 @param cache_directory is the location of the cache
57
58 @param flags_directory is the location of the flags
59*/
60
61int mbox_mailstorage_init(struct mailstorage * storage,
62 char * mb_pathname, int mb_cached,
63 char * mb_cache_directory, char * mb_flags_directory);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/generic/mhdriver.c b/kmicromail/libetpan/generic/mhdriver.c
new file mode 100644
index 0000000..af38d27
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver.c
@@ -0,0 +1,866 @@
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 "mhdriver.h"
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <sys/stat.h>
43#include <ctype.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include "mailmh.h"
50#include "maildriver_tools.h"
51#include "mhdriver_tools.h"
52#include "mhdriver_message.h"
53#include "mailmessage.h"
54
55static int mhdriver_initialize(mailsession * session);
56
57static void mhdriver_uninitialize(mailsession * session);
58
59static int mhdriver_connect_path(mailsession * session, char * path);
60static int mhdriver_logout(mailsession * session);
61
62static int mhdriver_build_folder_name(mailsession * session, char * mb,
63 char * name, char ** result);
64static int mhdriver_create_folder(mailsession * session, char * mb);
65
66static int mhdriver_delete_folder(mailsession * session, char * mb);
67
68static int mhdriver_rename_folder(mailsession * session, char * mb,
69 char * new_name);
70
71static int mhdriver_select_folder(mailsession * session, char * mb);
72
73static int mhdriver_status_folder(mailsession * session, char * mb,
74 uint32_t * result_messages, uint32_t * result_recent,
75 uint32_t * result_unseen);
76
77static int mhdriver_messages_number(mailsession * session, char * mb,
78 uint32_t * result);
79
80static int mhdriver_list_folders(mailsession * session, char * mb,
81 struct mail_list ** result);
82
83static int mhdriver_lsub_folders(mailsession * session, char * mb,
84 struct mail_list ** result);
85
86static int mhdriver_subscribe_folder(mailsession * session, char * mb);
87
88static int mhdriver_unsubscribe_folder(mailsession * session, char * mb);
89
90static int mhdriver_append_message(mailsession * session,
91 char * message, size_t size);
92static int mhdriver_copy_message(mailsession * session,
93 uint32_t num, char * mb);
94
95static int mhdriver_remove_message(mailsession * session, uint32_t num);
96
97static int mhdriver_move_message(mailsession * session,
98 uint32_t num, char * mb);
99
100static int mhdriver_get_messages_list(mailsession * session,
101 struct mailmessage_list ** result);
102
103static int mhdriver_get_message(mailsession * session,
104 uint32_t num, mailmessage ** result);
105
106static int mhdriver_get_message_by_uid(mailsession * session,
107 const char * uid,
108 mailmessage ** result);
109
110static mailsession_driver local_mh_session_driver = {
111 .sess_name = "mh",
112
113 .sess_initialize = mhdriver_initialize,
114 .sess_uninitialize = mhdriver_uninitialize,
115
116 .sess_parameters = NULL,
117
118 .sess_connect_stream = NULL,
119 .sess_connect_path = mhdriver_connect_path,
120 .sess_starttls = NULL,
121 .sess_login = NULL,
122 .sess_logout = mhdriver_logout,
123 .sess_noop = NULL,
124
125 .sess_build_folder_name = mhdriver_build_folder_name,
126 .sess_create_folder = mhdriver_create_folder,
127 .sess_delete_folder = mhdriver_delete_folder,
128 .sess_rename_folder = mhdriver_rename_folder,
129 .sess_check_folder = NULL,
130 .sess_examine_folder = NULL,
131 .sess_select_folder = mhdriver_select_folder,
132 .sess_expunge_folder = NULL,
133 .sess_status_folder = mhdriver_status_folder,
134 .sess_messages_number = mhdriver_messages_number,
135 .sess_recent_number = mhdriver_messages_number,
136 .sess_unseen_number = mhdriver_messages_number,
137 .sess_list_folders = mhdriver_list_folders,
138 .sess_lsub_folders = mhdriver_lsub_folders,
139 .sess_subscribe_folder = mhdriver_subscribe_folder,
140 .sess_unsubscribe_folder = mhdriver_unsubscribe_folder,
141
142 .sess_append_message = mhdriver_append_message,
143 .sess_copy_message = mhdriver_copy_message,
144 .sess_move_message = mhdriver_move_message,
145
146 .sess_get_messages_list = mhdriver_get_messages_list,
147 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
148 .sess_remove_message = mhdriver_remove_message,
149#if 0
150 .sess_search_messages = maildriver_generic_search_messages,
151#endif
152
153 .sess_get_message = mhdriver_get_message,
154 .sess_get_message_by_uid = mhdriver_get_message_by_uid,
155};
156
157mailsession_driver * mh_session_driver = &local_mh_session_driver;
158
159static inline struct mh_session_state_data * get_data(mailsession * session)
160{
161 return session->sess_data;
162}
163
164static inline struct mailmh * get_mh_session(mailsession * session)
165{
166 return get_data(session)->mh_session;
167}
168
169static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session)
170{
171 return get_data(session)->mh_cur_folder;
172}
173
174static int add_to_list(mailsession * session, char * mb)
175{
176 char * new_mb;
177 struct mh_session_state_data * data;
178 int r;
179
180 data = get_data(session);
181
182 new_mb = strdup(mb);
183 if (new_mb == NULL)
184 return -1;
185
186 r = clist_append(data->mh_subscribed_list, new_mb);
187 if (r < 0) {
188 free(mb);
189 return -1;
190 }
191
192 return 0;
193}
194
195static int remove_from_list(mailsession * session, char * mb)
196{
197 clistiter * cur;
198 struct mh_session_state_data * data;
199
200 data = get_data(session);
201
202 for(cur = clist_begin(data->mh_subscribed_list) ;
203 cur != NULL ; cur = clist_next(cur)) {
204 char * cur_name;
205
206 cur_name = clist_content(cur);
207 if (strcmp(cur_name, mb) == 0) {
208 clist_delete(data->mh_subscribed_list, cur);
209 free(cur_name);
210 return 0;
211 }
212 }
213
214 return -1;
215}
216
217static int mhdriver_initialize(mailsession * session)
218{
219 struct mh_session_state_data * data;
220
221 data = malloc(sizeof(* data));
222 if (data == NULL)
223 goto err;
224
225 data->mh_session = NULL;
226 data->mh_cur_folder = NULL;
227
228 data->mh_subscribed_list = clist_new();
229 if (data->mh_subscribed_list == NULL)
230 goto free;
231
232 session->sess_data = data;
233
234 return MAIL_NO_ERROR;
235
236 free:
237 free(data);
238 err:
239 return MAIL_ERROR_MEMORY;
240}
241
242static void mhdriver_uninitialize(mailsession * session)
243{
244 struct mh_session_state_data * data;
245
246 data = get_data(session);
247
248 if (data->mh_session != NULL)
249 mailmh_free(data->mh_session);
250
251 clist_foreach(data->mh_subscribed_list, (clist_func) free, NULL);
252 clist_free(data->mh_subscribed_list);
253
254 free(data);
255
256 session->sess_data = NULL;
257}
258
259
260static int mhdriver_connect_path(mailsession * session, char * path)
261{
262 struct mailmh * mh;
263
264 if (get_mh_session(session) != NULL)
265 return MAIL_ERROR_BAD_STATE;
266
267 mh = mailmh_new(path);
268 if (mh == NULL)
269 return MAIL_ERROR_MEMORY;
270
271 get_data(session)->mh_session = mh;
272
273 return MAIL_NO_ERROR;
274}
275
276static int mhdriver_logout(mailsession * session)
277{
278 struct mailmh * mh;
279
280 mh = get_mh_session(session);
281
282 if (mh == NULL)
283 return MAIL_ERROR_BAD_STATE;
284
285 mailmh_free(mh);
286 get_data(session)->mh_session = NULL;
287
288 return MAIL_NO_ERROR;
289}
290
291/* folders operations */
292
293static int mhdriver_build_folder_name(mailsession * session, char * mb,
294 char * name, char ** result)
295{
296 char * folder_name;
297
298 folder_name = malloc(strlen(mb) + 2 + strlen(name));
299 if (folder_name == NULL)
300 return MAIL_ERROR_MEMORY;
301
302 strcpy(folder_name, mb);
303 strcat(folder_name, "/");
304 strcat(folder_name, name);
305
306 * result = folder_name;
307
308 return MAIL_NO_ERROR;
309}
310
311static int get_parent(mailsession * session, char * mb,
312 struct mailmh_folder ** result_folder,
313 char ** result_name)
314{
315 char * name;
316 size_t length;
317 int i;
318 char * parent_name;
319 struct mailmh_folder * parent;
320 struct mailmh * mh;
321
322 mh = get_mh_session(session);
323 if (mh == NULL)
324 return MAIL_ERROR_BAD_STATE;
325
326 length = strlen(mb);
327 for(i = length - 1 ; i >= 0 ; i--)
328 if (mb[i] == '/')
329 break;
330 name = mb + i + 1;
331
332 parent_name = malloc(i + 1);
333 /* strndup(mb, i) */
334 if (parent_name == NULL)
335 return MAIL_ERROR_MEMORY;
336
337 strncpy(parent_name, mb, i);
338 parent_name[i] = '\0';
339
340 parent = mailmh_folder_find(mh->mh_main, parent_name);
341 free(parent_name);
342 if (parent == NULL)
343 return MAIL_ERROR_FOLDER_NOT_FOUND;
344
345 * result_folder = parent;
346 * result_name = name;
347
348 return MAIL_NO_ERROR;
349}
350
351static int mhdriver_create_folder(mailsession * session, char * mb)
352{
353 int r;
354 struct mailmh_folder * parent;
355 char * name;
356
357 r = get_parent(session, mb, &parent, &name);
358 if (r != MAIL_NO_ERROR)
359 return r;
360
361 r = mailmh_folder_add_subfolder(parent, name);
362
363 return mhdriver_mh_error_to_mail_error(r);
364}
365
366static int mhdriver_delete_folder(mailsession * session, char * mb)
367{
368 int r;
369 struct mailmh_folder * folder;
370 struct mailmh * mh;
371
372 mh = get_mh_session(session);
373 if (mh == NULL)
374 return MAIL_ERROR_BAD_STATE;
375
376 folder = mailmh_folder_find(mh->mh_main, mb);
377 if (folder == NULL)
378 return MAIL_ERROR_FOLDER_NOT_FOUND;
379
380 if (get_mh_cur_folder(session) == folder)
381 get_data(session)->mh_cur_folder = NULL;
382
383 r = mailmh_folder_remove_subfolder(folder);
384
385 return mhdriver_mh_error_to_mail_error(r);
386}
387
388static int mhdriver_rename_folder(mailsession * session, char * mb,
389 char * new_name)
390{
391 struct mailmh_folder * src_folder;
392 struct mailmh_folder * dst_folder;
393 char * name;
394 struct mailmh * mh;
395 int r;
396
397 r = get_parent(session, new_name, &dst_folder, &name);
398 if (r != MAIL_NO_ERROR)
399 return r;
400
401 mh = get_mh_session(session);
402 if (mh == NULL)
403 return MAIL_ERROR_BAD_STATE;
404
405 src_folder = mailmh_folder_find(mh->mh_main, mb);
406 if (src_folder == NULL)
407 return MAIL_ERROR_FOLDER_NOT_FOUND;
408
409 if (get_mh_cur_folder(session) == src_folder)
410 get_data(session)->mh_cur_folder = NULL;
411
412 r = mailmh_folder_rename_subfolder(src_folder, dst_folder, name);
413
414 return mhdriver_mh_error_to_mail_error(r);
415}
416
417static int mhdriver_select_folder(mailsession * session, char * mb)
418{
419 struct mailmh_folder * folder;
420 struct mailmh * mh;
421 int r;
422
423 mh = get_mh_session(session);
424 if (mh == NULL)
425 return MAIL_ERROR_BAD_STATE;
426
427 r = mailmh_folder_update(mh->mh_main);
428
429 folder = mailmh_folder_find(mh->mh_main, mb);
430 if (folder == NULL)
431 return MAIL_ERROR_FOLDER_NOT_FOUND;
432
433 get_data(session)->mh_cur_folder = folder;
434 r = mailmh_folder_update(folder);
435
436 return mhdriver_mh_error_to_mail_error(r);
437}
438
439static int mhdriver_status_folder(mailsession * session, char * mb,
440 uint32_t * result_messages, uint32_t * result_recent,
441 uint32_t * result_unseen)
442{
443 uint32_t count;
444 int r;
445
446 r = mhdriver_messages_number(session, mb, &count);
447 if (r != MAIL_NO_ERROR)
448 return r;
449
450 * result_messages = count;
451 * result_recent = count;
452 * result_unseen = count;
453
454 return MAIL_NO_ERROR;
455}
456
457static int mhdriver_messages_number(mailsession * session, char * mb,
458 uint32_t * result)
459{
460 struct mailmh_folder * folder;
461 uint32_t count;
462 struct mailmh * mh;
463 unsigned int i;
464
465 mh = get_mh_session(session);
466 if (mh == NULL)
467 return MAIL_ERROR_BAD_STATE;
468
469 if (mb != NULL) {
470 folder = mailmh_folder_find(mh->mh_main, mb);
471 if (folder == NULL)
472 return MAIL_ERROR_FOLDER_NOT_FOUND;
473 }
474 else {
475 folder = get_mh_cur_folder(session);
476 if (folder == NULL)
477 return MAIL_ERROR_BAD_STATE;
478 }
479
480 mailmh_folder_update(folder);
481 count = 0;
482 for (i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) {
483 struct mailmh_msg_info * msg_info;
484
485 msg_info = carray_get(folder->fl_msgs_tab, i);
486 if (msg_info != NULL)
487 count ++;
488 }
489
490 * result = count;
491
492 return MAIL_NO_ERROR;
493}
494
495
496static int get_list_folders(struct mailmh_folder * folder, clist ** result)
497{
498 unsigned int i;
499 clist * list;
500 char * new_filename;
501 int res;
502 int r;
503
504 list = * result;
505
506 new_filename = strdup(folder->fl_filename);
507 if (new_filename == NULL) {
508 res = MAIL_ERROR_MEMORY;
509 goto free;
510 }
511
512 r = mailmh_folder_update(folder);
513
514 switch (r) {
515 case MAILMH_NO_ERROR:
516 break;
517
518 default:
519 res = mhdriver_mh_error_to_mail_error(r);
520 goto free;
521 }
522
523 r = clist_append(list, new_filename);
524 if (r < 0) {
525 free(new_filename);
526 res = MAIL_ERROR_MEMORY;
527 goto free;
528 }
529
530 if (folder->fl_subfolders_tab != NULL) {
531 for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) {
532 struct mailmh_folder * subfolder;
533
534 subfolder = carray_get(folder->fl_subfolders_tab, i);
535
536 r = get_list_folders(subfolder, &list);
537 if (r != MAIL_NO_ERROR) {
538 res = MAIL_ERROR_MEMORY;
539 goto free;
540 }
541 }
542 }
543
544 * result = list;
545
546 return MAIL_NO_ERROR;
547
548 free:
549 clist_foreach(list, (clist_func) free, NULL);
550 clist_free(list);
551 return res;
552}
553
554
555static int mhdriver_list_folders(mailsession * session, char * mb,
556 struct mail_list ** result)
557{
558 clist * list;
559 int r;
560 struct mailmh * mh;
561 struct mail_list * ml;
562
563 mh = get_mh_session(session);
564
565 if (mh == NULL)
566 return MAIL_ERROR_BAD_STATE;
567
568 list = clist_new();
569 if (list == NULL)
570 return MAIL_ERROR_MEMORY;
571
572 r = get_list_folders(mh->mh_main, &list);
573 if (r != MAIL_NO_ERROR)
574 return r;
575
576 ml = mail_list_new(list);
577 if (ml == NULL)
578 goto free;
579
580 * result = ml;
581
582 return MAIL_NO_ERROR;
583
584 free:
585 clist_foreach(list, (clist_func) free, NULL);
586 clist_free(list);
587 return MAIL_ERROR_MEMORY;
588}
589
590static int mhdriver_lsub_folders(mailsession * session, char * mb,
591 struct mail_list ** result)
592{
593 clist * subscribed;
594 clist * lsub_result;
595 clistiter * cur;
596 struct mail_list * lsub;
597 size_t length;
598 int r;
599
600 length = strlen(mb);
601
602 subscribed = get_data(session)->mh_subscribed_list;
603
604 lsub_result = clist_new();
605 if (lsub_result == NULL)
606 return MAIL_ERROR_MEMORY;
607
608 for(cur = clist_begin(subscribed) ; cur != NULL ;
609 cur = clist_next(cur)) {
610 char * cur_mb;
611 char * new_mb;
612
613 cur_mb = clist_content(cur);
614
615 if (strncmp(mb, cur_mb, length) == 0) {
616 new_mb = strdup(cur_mb);
617 if (new_mb == NULL)
618 goto free_list;
619
620 r = clist_append(lsub_result, new_mb);
621 if (r < 0) {
622 free(new_mb);
623 goto free_list;
624 }
625 }
626 }
627
628 lsub = mail_list_new(lsub_result);
629 if (lsub == NULL)
630 goto free_list;
631
632 * result = lsub;
633
634 return MAIL_NO_ERROR;
635
636 free_list:
637 clist_foreach(lsub_result, (clist_func) free, NULL);
638 clist_free(lsub_result);
639 return MAIL_ERROR_MEMORY;
640}
641
642static int mhdriver_subscribe_folder(mailsession * session, char * mb)
643{
644 int r;
645
646 r = add_to_list(session, mb);
647 if (r < 0)
648 return MAIL_ERROR_SUBSCRIBE;
649
650 return MAIL_NO_ERROR;
651}
652
653static int mhdriver_unsubscribe_folder(mailsession * session, char * mb)
654{
655 int r;
656
657 r = remove_from_list(session, mb);
658 if (r < 0)
659 return MAIL_ERROR_UNSUBSCRIBE;
660
661 return MAIL_NO_ERROR;
662}
663
664/* messages operations */
665
666static int mhdriver_append_message(mailsession * session,
667 char * message, size_t size)
668{
669 int r;
670 struct mailmh_folder * folder;
671
672 folder = get_mh_cur_folder(session);
673 if (folder == NULL)
674 return MAIL_ERROR_BAD_STATE;
675
676 r = mailmh_folder_add_message(folder, message, size);
677
678 switch (r) {
679 case MAILMH_ERROR_FILE:
680 return MAIL_ERROR_DISKSPACE;
681
682 default:
683 return mhdriver_mh_error_to_mail_error(r);
684 }
685}
686
687static int mhdriver_copy_message(mailsession * session,
688 uint32_t num, char * mb)
689{
690 int fd;
691 int r;
692 struct mailmh_folder * folder;
693 struct mailmh * mh;
694 int res;
695
696 mh = get_mh_session(session);
697 if (mh == NULL) {
698 res = MAIL_ERROR_BAD_STATE;
699 goto err;
700 }
701
702 folder = get_mh_cur_folder(session);
703 if (folder == NULL) {
704 res = MAIL_ERROR_BAD_STATE;
705 goto err;
706 }
707
708 r = mailmh_folder_get_message_fd(folder, num, O_RDONLY, &fd);
709 if (r != MAIL_NO_ERROR) {
710 res = r;
711 goto err;
712 }
713
714 folder = mailmh_folder_find(mh->mh_main, mb);
715 if (folder == NULL) {
716 res = MAIL_ERROR_FOLDER_NOT_FOUND;
717 goto close;
718 }
719
720 r = mailmh_folder_add_message_file(folder, fd);
721 if (r != MAIL_NO_ERROR) {
722 res = MAIL_ERROR_COPY;
723 goto close;
724 }
725
726 close(fd);
727
728 return MAIL_NO_ERROR;
729
730 close:
731 close(fd);
732 err:
733 return res;
734}
735
736static int mhdriver_remove_message(mailsession * session, uint32_t num)
737{
738 int r;
739 struct mailmh_folder * folder;
740
741 folder = get_mh_cur_folder(session);
742 if (folder == NULL)
743 return MAIL_ERROR_DELETE;
744
745 r = mailmh_folder_remove_message(folder, num);
746
747 return mhdriver_mh_error_to_mail_error(r);
748}
749
750static int mhdriver_move_message(mailsession * session,
751 uint32_t num, char * mb)
752{
753 int r;
754 struct mailmh_folder * src_folder;
755 struct mailmh_folder * dest_folder;
756 struct mailmh * mh;
757
758 mh = get_mh_session(session);
759 if (mh == NULL)
760 return MAIL_ERROR_BAD_STATE;
761
762 src_folder = get_mh_cur_folder(session);
763 if (src_folder == NULL)
764 return MAIL_ERROR_BAD_STATE;
765
766 dest_folder = mailmh_folder_find(mh->mh_main, mb);
767 if (dest_folder == NULL)
768 return MAIL_ERROR_FOLDER_NOT_FOUND;
769
770 r = mailmh_folder_move_message(dest_folder, src_folder, num);
771
772 return mhdriver_mh_error_to_mail_error(r);
773}
774
775
776static int mhdriver_get_messages_list(mailsession * session,
777 struct mailmessage_list ** result)
778{
779 struct mailmh_folder * folder;
780 int res;
781
782 folder = get_mh_cur_folder(session);
783 if (folder == NULL) {
784 res = MAIL_ERROR_BAD_STATE;
785 goto err;
786 }
787
788 mailmh_folder_update(folder);
789 return mh_get_messages_list(folder, session, mh_message_driver, result);
790
791 err:
792 return res;
793}
794
795static int mhdriver_get_message(mailsession * session,
796 uint32_t num, mailmessage ** result)
797{
798 mailmessage * msg_info;
799 int r;
800
801 msg_info = mailmessage_new();
802 if (msg_info == NULL)
803 return MAIL_ERROR_MEMORY;
804
805 r = mailmessage_init(msg_info, session, mh_message_driver, num, 0);
806 if (r != MAIL_NO_ERROR) {
807 mailmessage_free(msg_info);
808 return r;
809 }
810
811 * result = msg_info;
812
813 return MAIL_NO_ERROR;
814}
815
816static int mhdriver_get_message_by_uid(mailsession * session,
817 const char * uid,
818 mailmessage ** result)
819{
820 uint32_t index;
821 char *p;
822 struct mailmh_msg_info * mh_msg_info;
823 struct mh_session_state_data * mh_data;
824 chashdatum key;
825 chashdatum data;
826 int r;
827 time_t mtime;
828 char * mtime_p;
829
830 if (uid == NULL)
831 return MAIL_ERROR_INVAL;
832
833 index = strtoul(uid, &p, 10);
834 if (p == uid || * p != '-')
835 return MAIL_ERROR_INVAL;
836
837 mh_data = session->sess_data;
838#if 0
839 mh_msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, index);
840#endif
841 key.data = &index;
842 key.len = sizeof(index);
843 r = chash_get(mh_data->mh_cur_folder->fl_msgs_hash, &key, &data);
844 if (r < 0)
845 return MAIL_ERROR_MSG_NOT_FOUND;
846
847 mh_msg_info = data.data;
848
849 mtime_p = p + 1;
850
851 mtime = strtoul(mtime_p, &p, 10);
852 if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) {
853 size_t size;
854 char *size_p;
855
856 size_p = p + 1;
857 size = strtoul(size_p, &p, 10);
858 if ((* p == '\0') && (size == mh_msg_info->msg_size))
859 return mhdriver_get_message(session, index, result);
860 }
861 else if (* p != '-') {
862 return MAIL_ERROR_INVAL;
863 }
864
865 return MAIL_ERROR_MSG_NOT_FOUND;
866}
diff --git a/kmicromail/libetpan/generic/mhdriver.h b/kmicromail/libetpan/generic/mhdriver.h
new file mode 100644
index 0000000..a82b9c1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver.h
@@ -0,0 +1,52 @@
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#ifndef MHDRIVER_H
37
38#define MHDRIVER_H
39
40#include <libetpan/maildriver.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * mh_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_cached.c b/kmicromail/libetpan/generic/mhdriver_cached.c
new file mode 100644
index 0000000..5c35089
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached.c
@@ -0,0 +1,1232 @@
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 "mhdriver_cached.h"
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <sys/stat.h>
43#include <ctype.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include "mail.h"
50#include "mail_cache_db.h"
51
52#include "generic_cache.h"
53#include "imfcache.h"
54#include "mhdriver.h"
55
56#include "mhdriver_cached_message.h"
57#include "mailmh.h"
58#include "maildriver_tools.h"
59#include "mhdriver_tools.h"
60#include "mailmessage.h"
61
62static int mhdriver_cached_initialize(mailsession * session);
63
64static void mhdriver_cached_uninitialize(mailsession * session);
65
66static int mhdriver_cached_parameters(mailsession * session,
67 int id, void * value);
68
69static int mhdriver_cached_connect_path(mailsession * session, char * path);
70static int mhdriver_cached_logout(mailsession * session);
71
72static int mhdriver_cached_build_folder_name(mailsession * session, char * mb,
73 char * name, char ** result);
74static int mhdriver_cached_create_folder(mailsession * session, char * mb);
75
76static int mhdriver_cached_delete_folder(mailsession * session, char * mb);
77
78static int mhdriver_cached_rename_folder(mailsession * session, char * mb,
79 char * new_name);
80
81static int mhdriver_cached_check_folder(mailsession * session);
82
83static int mhdriver_cached_select_folder(mailsession * session, char * mb);
84
85static int mhdriver_cached_expunge_folder(mailsession * session);
86
87static int mhdriver_cached_status_folder(mailsession * session, char * mb,
88 uint32_t * result_messages, uint32_t * result_recent,
89 uint32_t * result_unseen);
90
91static int mhdriver_cached_messages_number(mailsession * session, char * mb,
92 uint32_t * result);
93static int mhdriver_cached_recent_number(mailsession * session, char * mb,
94 uint32_t * result);
95static int mhdriver_cached_unseen_number(mailsession * session, char * mb,
96 uint32_t * result);
97
98static int mhdriver_cached_list_folders(mailsession * session, char * mb,
99 struct mail_list ** result);
100
101static int mhdriver_cached_lsub_folders(mailsession * session, char * mb,
102 struct mail_list ** result);
103
104static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb);
105
106static int mhdriver_cached_unsubscribe_folder(mailsession * session,
107 char * mb);
108
109static int mhdriver_cached_append_message(mailsession * session,
110 char * message, size_t size);
111static int mhdriver_cached_copy_message(mailsession * session,
112 uint32_t num, char * mb);
113
114static int mhdriver_cached_remove_message(mailsession * session,
115 uint32_t num);
116
117static int mhdriver_cached_move_message(mailsession * session,
118 uint32_t num, char * mb);
119
120static int
121mhdriver_cached_get_messages_list(mailsession * session,
122 struct mailmessage_list ** result);
123
124static int
125mhdriver_cached_get_envelopes_list(mailsession * session,
126 struct mailmessage_list * env_list);
127
128static int mhdriver_cached_get_message(mailsession * session,
129 uint32_t num, mailmessage ** result);
130
131static int mhdriver_cached_get_message_by_uid(mailsession * session,
132 const char * uid,
133 mailmessage ** result);
134
135static mailsession_driver local_mh_cached_session_driver = {
136 .sess_name = "mh-cached",
137
138 .sess_initialize = mhdriver_cached_initialize,
139 .sess_uninitialize = mhdriver_cached_uninitialize,
140
141 .sess_parameters = mhdriver_cached_parameters,
142
143 .sess_connect_stream = NULL,
144 .sess_connect_path = mhdriver_cached_connect_path,
145 .sess_starttls = NULL,
146 .sess_login = NULL,
147 .sess_logout = mhdriver_cached_logout,
148 .sess_noop = NULL,
149
150 .sess_build_folder_name = mhdriver_cached_build_folder_name,
151 .sess_create_folder = mhdriver_cached_create_folder,
152 .sess_delete_folder = mhdriver_cached_delete_folder,
153 .sess_rename_folder = mhdriver_cached_rename_folder,
154 .sess_check_folder = mhdriver_cached_check_folder,
155 .sess_examine_folder = NULL,
156 .sess_select_folder = mhdriver_cached_select_folder,
157 .sess_expunge_folder = mhdriver_cached_expunge_folder,
158 .sess_status_folder = mhdriver_cached_status_folder,
159 .sess_messages_number = mhdriver_cached_messages_number,
160 .sess_recent_number = mhdriver_cached_recent_number,
161 .sess_unseen_number = mhdriver_cached_unseen_number,
162 .sess_list_folders = mhdriver_cached_list_folders,
163 .sess_lsub_folders = mhdriver_cached_lsub_folders,
164 .sess_subscribe_folder = mhdriver_cached_subscribe_folder,
165 .sess_unsubscribe_folder = mhdriver_cached_unsubscribe_folder,
166
167 .sess_append_message = mhdriver_cached_append_message,
168 .sess_copy_message = mhdriver_cached_copy_message,
169 .sess_move_message = mhdriver_cached_move_message,
170
171 .sess_get_messages_list = mhdriver_cached_get_messages_list,
172 .sess_get_envelopes_list = mhdriver_cached_get_envelopes_list,
173 .sess_remove_message = mhdriver_cached_remove_message,
174#if 0
175 .sess_search_messages = maildriver_generic_search_messages,
176#endif
177
178 .sess_get_message = mhdriver_cached_get_message,
179 .sess_get_message_by_uid = mhdriver_cached_get_message_by_uid,
180};
181
182mailsession_driver * mh_cached_session_driver =
183&local_mh_cached_session_driver;
184
185#define ENV_NAME "env.db"
186#define FLAGS_NAME "flags.db"
187
188
189static inline struct mh_cached_session_state_data *
190get_cached_data(mailsession * session)
191{
192 return session->sess_data;
193}
194
195static inline mailsession * get_ancestor(mailsession * session)
196{
197 return get_cached_data(session)->mh_ancestor;
198}
199
200static inline struct mh_session_state_data *
201get_ancestor_data(mailsession * session)
202{
203 return get_ancestor(session)->sess_data;
204}
205
206static inline struct mailmh *
207get_mh_session(mailsession * session)
208{
209 return get_ancestor_data(session)->mh_session;
210}
211
212static inline struct mailmh_folder *
213get_mh_cur_folder(mailsession * session)
214{
215 return get_ancestor_data(session)->mh_cur_folder;
216}
217
218
219#define FILENAME_MAX_UID "max-uid"
220
221/* write max uid current value */
222
223static int write_max_uid_value(mailsession * session)
224{
225 int r;
226 char filename[PATH_MAX];
227 FILE * f;
228 int res;
229 struct mh_cached_session_state_data * cached_data;
230 struct mh_session_state_data * ancestor_data;
231 int fd;
232
233 MMAPString * mmapstr;
234 size_t cur_token;
235
236 cached_data = get_cached_data(session);
237 ancestor_data = get_ancestor_data(session);
238
239 if (cached_data->mh_quoted_mb == NULL)
240 return MAIL_ERROR_BAD_STATE;
241
242 snprintf(filename, PATH_MAX, "%s/%s/%s",
243 cached_data->mh_cache_directory,
244 cached_data->mh_quoted_mb, FILENAME_MAX_UID);
245
246 fd = creat(filename, S_IRUSR | S_IWUSR);
247 if (fd < 0) {
248 res = MAIL_ERROR_FILE;
249 goto err;
250 }
251
252 f = fdopen(fd, "w");
253 if (f == NULL) {
254 close(fd);
255 res = MAIL_ERROR_FILE;
256 goto err;
257 }
258
259 mmapstr = mmap_string_new("");
260 if (mmapstr == NULL) {
261 res = MAIL_ERROR_MEMORY;
262 goto close;
263 }
264
265 r = mail_serialize_clear(mmapstr, &cur_token);
266 if (r != MAIL_NO_ERROR) {
267 res = r;
268 goto free_mmapstr;
269 }
270
271 r = mailimf_cache_int_write(mmapstr, &cur_token,
272 ancestor_data->mh_cur_folder->fl_max_index);
273 if (r != MAIL_NO_ERROR) {
274 res = r;
275 goto free_mmapstr;
276 }
277
278 fwrite(mmapstr->str, 1, mmapstr->len, f);
279
280 mmap_string_free(mmapstr);
281 fclose(f);
282
283 return MAIL_NO_ERROR;
284
285 free_mmapstr:
286 mmap_string_free(mmapstr);
287 close:
288 fclose(f);
289 err:
290 return res;
291}
292
293static int read_max_uid_value(mailsession * session)
294{
295 int r;
296 char filename[PATH_MAX];
297 FILE * f;
298 uint32_t written_uid;
299 int res;
300 struct mh_cached_session_state_data * cached_data;
301 struct mh_session_state_data * ancestor_data;
302
303 MMAPString * mmapstr;
304 size_t cur_token;
305 char buf[sizeof(uint32_t)];
306 size_t read_size;
307
308 cached_data = get_cached_data(session);
309 ancestor_data = get_ancestor_data(session);
310
311 snprintf(filename, PATH_MAX, "%s/%s/%s",
312 cached_data->mh_cache_directory,
313 cached_data->mh_quoted_mb, FILENAME_MAX_UID);
314
315 f = fopen(filename, "r");
316 if (f == NULL) {
317 res = MAIL_ERROR_FILE;
318 goto err;
319 }
320
321 read_size = fread(buf, 1, sizeof(uint32_t), f);
322
323 mmapstr = mmap_string_new_len(buf, read_size);
324 if (mmapstr == NULL) {
325 res = MAIL_ERROR_MEMORY;
326 goto close;
327 }
328
329 cur_token = 0;
330
331 r = mailimf_cache_int_read(mmapstr, &cur_token, &written_uid);
332 if (r != MAIL_NO_ERROR) {
333 fclose(f);
334 res = r;
335 goto free_mmapstr;
336 }
337
338 mmap_string_free(mmapstr);
339 fclose(f);
340
341 if (written_uid > ancestor_data->mh_cur_folder->fl_max_index)
342 ancestor_data->mh_cur_folder->fl_max_index = written_uid;
343
344 return MAIL_NO_ERROR;
345
346 free_mmapstr:
347 mmap_string_free(mmapstr);
348 close:
349 fclose(f);
350 err:
351 return res;
352}
353
354
355static int mhdriver_cached_initialize(mailsession * session)
356{
357 struct mh_cached_session_state_data * data;
358
359 data = malloc(sizeof(* data));
360 if (data == NULL)
361 goto err;
362
363 data->mh_flags_store = mail_flags_store_new();
364 if (data->mh_flags_store == NULL)
365 goto free;
366
367 data->mh_ancestor = mailsession_new(mh_session_driver);
368 if (data->mh_ancestor == NULL)
369 goto free_store;
370
371 data->mh_quoted_mb = NULL;
372
373 session->sess_data = data;
374
375 return MAIL_NO_ERROR;
376
377 free_store:
378 mail_flags_store_free(data->mh_flags_store);
379 free:
380 free(data);
381 err:
382 return MAIL_ERROR_MEMORY;
383}
384
385static void free_state(struct mh_cached_session_state_data * mh_data)
386{
387 if (mh_data->mh_quoted_mb) {
388 free(mh_data->mh_quoted_mb);
389 mh_data->mh_quoted_mb = NULL;
390 }
391}
392
393static int mh_flags_store_process(char * flags_directory, char * quoted_mb,
394 struct mail_flags_store * flags_store)
395{
396 char filename_flags[PATH_MAX];
397 struct mail_cache_db * cache_db_flags;
398 MMAPString * mmapstr;
399 unsigned int i;
400 int r;
401 int res;
402
403 if (carray_count(flags_store->fls_tab) == 0)
404 return MAIL_NO_ERROR;
405
406 if (quoted_mb == NULL)
407 return MAIL_NO_ERROR;
408
409 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
410 flags_directory, quoted_mb, FLAGS_NAME);
411
412 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
413 if (r < 0) {
414 res = MAIL_ERROR_FILE;
415 goto err;
416 }
417
418 mmapstr = mmap_string_new("");
419 if (mmapstr == NULL) {
420 res = MAIL_ERROR_MEMORY;
421 goto close_db_flags;
422 }
423
424 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
425 mailmessage * msg;
426
427 msg = carray_get(flags_store->fls_tab, i);
428
429 r = mhdriver_write_cached_flags(cache_db_flags, mmapstr,
430 msg->msg_uid, msg->msg_flags);
431 }
432
433 mmap_string_free(mmapstr);
434 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
435
436 mail_flags_store_clear(flags_store);
437
438 return MAIL_NO_ERROR;
439
440 close_db_flags:
441 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
442 err:
443 return res;
444}
445
446static void mhdriver_cached_uninitialize(mailsession * session)
447{
448 struct mh_cached_session_state_data * data;
449
450 data = get_cached_data(session);
451
452 mh_flags_store_process(data->mh_flags_directory, data->mh_quoted_mb,
453 data->mh_flags_store);
454
455 mail_flags_store_free(data->mh_flags_store);
456
457 free_state(data);
458 mailsession_free(data->mh_ancestor);
459 free(data);
460
461 session->sess_data = NULL;
462}
463
464static int mhdriver_cached_parameters(mailsession * session,
465 int id, void * value)
466{
467 struct mh_cached_session_state_data * cached_data;
468 int r;
469
470 cached_data = get_cached_data(session);
471
472 switch (id) {
473 case MHDRIVER_CACHED_SET_CACHE_DIRECTORY:
474 strncpy(cached_data->mh_cache_directory, value, PATH_MAX);
475 cached_data->mh_cache_directory[PATH_MAX - 1] = '\0';
476
477 r = generic_cache_create_dir(cached_data->mh_cache_directory);
478 if (r != MAIL_NO_ERROR)
479 return r;
480
481 return MAIL_NO_ERROR;
482
483 case MHDRIVER_CACHED_SET_FLAGS_DIRECTORY:
484 strncpy(cached_data->mh_flags_directory, value, PATH_MAX);
485 cached_data->mh_flags_directory[PATH_MAX - 1] = '\0';
486
487 r = generic_cache_create_dir(cached_data->mh_flags_directory);
488 if (r != MAIL_NO_ERROR)
489 return r;
490
491 return MAIL_NO_ERROR;
492 }
493
494 return MAIL_ERROR_INVAL;
495}
496
497static int mhdriver_cached_connect_path(mailsession * session, char * path)
498{
499 return mailsession_connect_path(get_ancestor(session), path);
500}
501
502static int mhdriver_cached_logout(mailsession * session)
503{
504 int r;
505 struct mh_cached_session_state_data * cached_data;
506
507 r = write_max_uid_value(session);
508
509 cached_data = get_cached_data(session);
510
511 mh_flags_store_process(cached_data->mh_flags_directory,
512 cached_data->mh_quoted_mb,
513 cached_data->mh_flags_store);
514
515 return mailsession_logout(get_ancestor(session));
516}
517
518static int mhdriver_cached_check_folder(mailsession * session)
519{
520 struct mh_cached_session_state_data * cached_data;
521
522 cached_data = get_cached_data(session);
523
524 mh_flags_store_process(cached_data->mh_flags_directory,
525 cached_data->mh_quoted_mb,
526 cached_data->mh_flags_store);
527
528 return MAIL_NO_ERROR;
529}
530
531/* folders operations */
532
533static int mhdriver_cached_build_folder_name(mailsession * session, char * mb,
534 char * name, char ** result)
535{
536 return mailsession_build_folder_name(get_ancestor(session),
537 mb, name, result);
538}
539
540static int mhdriver_cached_create_folder(mailsession * session, char * mb)
541{
542 return mailsession_create_folder(get_ancestor(session), mb);
543}
544
545static int mhdriver_cached_delete_folder(mailsession * session, char * mb)
546{
547 return mailsession_delete_folder(get_ancestor(session), mb);
548}
549
550static int mhdriver_cached_rename_folder(mailsession * session, char * mb,
551 char * new_name)
552{
553 return mailsession_rename_folder(get_ancestor(session), mb, new_name);
554}
555
556static int get_cache_directory(mailsession * session,
557 char * path, char ** result)
558{
559 char * quoted_mb;
560 char dirname[PATH_MAX];
561 int res;
562 int r;
563 struct mh_cached_session_state_data * cached_data;
564
565 cached_data = get_cached_data(session);
566
567 quoted_mb = maildriver_quote_mailbox(path);
568 if (quoted_mb == NULL) {
569 res = MAIL_ERROR_MEMORY;
570 goto err;
571 }
572
573 snprintf(dirname, PATH_MAX, "%s/%s",
574 cached_data->mh_cache_directory, quoted_mb);
575
576 r = generic_cache_create_dir(dirname);
577 if (r != MAIL_NO_ERROR) {
578 res = r;
579 goto free;
580 }
581
582 snprintf(dirname, PATH_MAX, "%s/%s",
583 cached_data->mh_flags_directory, quoted_mb);
584
585 r = generic_cache_create_dir(dirname);
586 if (r != MAIL_NO_ERROR) {
587 res = r;
588 goto free;
589 }
590
591 * result = quoted_mb;
592
593 return MAIL_NO_ERROR;
594
595 free:
596 free(quoted_mb);
597 err:
598 return res;
599}
600
601static int mhdriver_cached_select_folder(mailsession * session, char * mb)
602{
603 int r;
604 int res;
605 char * quoted_mb;
606 struct mh_cached_session_state_data * cached_data;
607
608 cached_data = get_cached_data(session);
609
610 mh_flags_store_process(cached_data->mh_flags_directory,
611 cached_data->mh_quoted_mb,
612 cached_data->mh_flags_store);
613
614 r = get_cache_directory(session, mb, &quoted_mb);
615 if (r != MAIL_NO_ERROR) {
616 res = r;
617 goto err;
618 }
619
620 r = mailsession_select_folder(get_ancestor(session), mb);
621 if (r != MAIL_NO_ERROR) {
622 res = r;
623 goto free;
624 }
625
626 r = write_max_uid_value(session);
627
628 free_state(cached_data);
629 cached_data->mh_quoted_mb = quoted_mb;
630
631 r = read_max_uid_value(session);
632
633 return MAIL_NO_ERROR;
634
635 free:
636 free(quoted_mb);
637 err:
638 return res;
639}
640
641static int mhdriver_cached_expunge_folder(mailsession * session)
642{
643 struct mailmh_folder * folder;
644 int res;
645 char filename_flags[PATH_MAX];
646 struct mail_cache_db * cache_db_flags;
647 MMAPString * mmapstr;
648 struct mh_cached_session_state_data * cached_data;
649 unsigned int i;
650 int r;
651
652 cached_data = get_cached_data(session);
653 if (cached_data->mh_quoted_mb == NULL) {
654 res = MAIL_ERROR_BAD_STATE;
655 goto err;
656 }
657
658 mh_flags_store_process(cached_data->mh_flags_directory,
659 cached_data->mh_quoted_mb,
660 cached_data->mh_flags_store);
661
662 folder = get_mh_cur_folder(session);
663 if (folder == NULL) {
664 res = MAIL_ERROR_BAD_STATE;
665 goto err;
666 }
667
668 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
669 cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME);
670
671 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
672 if (r < 0) {
673 res = MAIL_ERROR_FILE;
674 goto err;
675 }
676
677 mmapstr = mmap_string_new("");
678 if (mmapstr == NULL) {
679 res = MAIL_ERROR_MEMORY;
680 goto close_db_flags;
681 }
682
683 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) {
684 struct mailmh_msg_info * mh_info;
685 struct mail_flags * flags;
686
687 mh_info = carray_get(folder->fl_msgs_tab, i);
688 if (mh_info == NULL)
689 continue;
690
691 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
692 session, mh_info->msg_index, &flags);
693 if (r != MAIL_NO_ERROR)
694 continue;
695
696 if (flags->fl_flags & MAIL_FLAG_DELETED) {
697 r = mailmh_folder_remove_message(folder, mh_info->msg_index);
698 }
699
700 mail_flags_free(flags);
701 }
702
703 mmap_string_free(mmapstr);
704 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
705
706 mailmh_folder_update(folder);
707
708 return MAIL_NO_ERROR;
709
710 close_db_flags:
711 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
712 err:
713 return res;
714}
715
716
717static int mhdriver_cached_status_folder(mailsession * session, char * mb,
718 uint32_t * result_messages,
719 uint32_t * result_recent,
720 uint32_t * result_unseen)
721{
722 struct mailmh_folder * folder;
723 int res;
724 char filename_flags[PATH_MAX];
725 struct mail_cache_db * cache_db_flags;
726 MMAPString * mmapstr;
727 struct mh_cached_session_state_data * cached_data;
728 unsigned int i;
729 int r;
730 uint32_t count;
731 uint32_t recent;
732 uint32_t unseen;
733
734 r = mhdriver_cached_select_folder(session, mb);
735 if (r != MAIL_NO_ERROR) {
736 res = r;
737 goto err;
738 }
739
740 count = 0;
741 recent = 0;
742 unseen = 0;
743
744 folder = get_mh_cur_folder(session);
745 if (folder == NULL) {
746 res = MAIL_ERROR_BAD_STATE;
747 goto err;
748 }
749
750 cached_data = get_cached_data(session);
751 if (cached_data->mh_quoted_mb == NULL) {
752 res = MAIL_ERROR_BAD_STATE;
753 goto err;
754 }
755
756 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
757 cached_data->mh_flags_directory,
758 cached_data->mh_quoted_mb, FLAGS_NAME);
759
760 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
761 if (r < 0) {
762 res = MAIL_ERROR_FILE;
763 goto err;
764 }
765
766 mmapstr = mmap_string_new("");
767 if (mmapstr == NULL) {
768 res = MAIL_ERROR_MEMORY;
769 goto close_db_flags;
770 }
771
772 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) {
773 struct mailmh_msg_info * mh_info;
774 struct mail_flags * flags;
775
776 mh_info = carray_get(folder->fl_msgs_tab, i);
777 if (mh_info == NULL)
778 continue;
779
780 count ++;
781
782 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
783 session, mh_info->msg_index,
784 &flags);
785
786 if (r != MAIL_NO_ERROR) {
787 recent ++;
788 unseen ++;
789 continue;
790 }
791
792 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
793 recent ++;
794 }
795 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
796 unseen ++;
797 }
798 mail_flags_free(flags);
799 }
800
801 mmap_string_free(mmapstr);
802 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
803
804 * result_messages = count;
805 * result_recent = recent;
806 * result_unseen = unseen;
807
808 return MAIL_NO_ERROR;
809
810 close_db_flags:
811 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
812 err:
813 return res;
814}
815
816static int mhdriver_cached_messages_number(mailsession * session, char * mb,
817 uint32_t * result)
818{
819 return mailsession_messages_number(get_ancestor(session), mb, result);
820}
821
822static int mhdriver_cached_recent_number(mailsession * session, char * mb,
823 uint32_t * result)
824{
825 uint32_t messages;
826 uint32_t recent;
827 uint32_t unseen;
828 int r;
829
830 r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen);
831 if (r != MAIL_NO_ERROR)
832 return r;
833
834 * result = recent;
835
836 return MAIL_NO_ERROR;
837}
838
839
840static int mhdriver_cached_unseen_number(mailsession * session, char * mb,
841 uint32_t * result)
842{
843 uint32_t messages;
844 uint32_t recent;
845 uint32_t unseen;
846 int r;
847
848 r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen);
849 if (r != MAIL_NO_ERROR)
850 return r;
851
852 * result = recent;
853
854 return MAIL_NO_ERROR;
855}
856
857
858static int mhdriver_cached_list_folders(mailsession * session, char * mb,
859 struct mail_list ** result)
860{
861 return mailsession_list_folders(get_ancestor(session), mb, result);
862}
863
864static int mhdriver_cached_lsub_folders(mailsession * session, char * mb,
865 struct mail_list ** result)
866{
867 return mailsession_lsub_folders(get_ancestor(session), mb, result);
868}
869
870static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb)
871{
872 return mailsession_subscribe_folder(get_ancestor(session), mb);
873}
874
875static int mhdriver_cached_unsubscribe_folder(mailsession * session,
876 char * mb)
877{
878 return mailsession_unsubscribe_folder(get_ancestor(session), mb);
879}
880
881/* messages operations */
882
883static int mhdriver_cached_append_message(mailsession * session,
884 char * message, size_t size)
885{
886 return mailsession_append_message(get_ancestor(session), message, size);
887}
888
889static int mhdriver_cached_copy_message(mailsession * session,
890 uint32_t num, char * mb)
891{
892 return mailsession_copy_message(get_ancestor(session), num, mb);
893}
894
895static int mhdriver_cached_remove_message(mailsession * session, uint32_t num)
896{
897 return mailsession_remove_message(get_ancestor(session), num);
898}
899
900static int mhdriver_cached_move_message(mailsession * session,
901 uint32_t num, char * mb)
902{
903 return mailsession_move_message(get_ancestor(session), num, mb);
904}
905
906static int
907mhdriver_cached_get_messages_list(mailsession * session,
908 struct mailmessage_list ** result)
909{
910 struct mailmh_folder * folder;
911 int res;
912
913 folder = get_mh_cur_folder(session);
914 if (folder == NULL) {
915 res = MAIL_ERROR_BAD_STATE;
916 goto err;
917 }
918
919 return mh_get_messages_list(folder, session,
920 mh_cached_message_driver, result);
921
922 err:
923 return res;
924}
925
926
927
928static int
929get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
930 mailsession * session, uint32_t num,
931 struct mailimf_fields ** result)
932{
933 int r;
934 char keyname[PATH_MAX];
935 struct mailimf_fields * fields;
936 int res;
937 struct mailmh_folder * folder;
938 struct mailmh_msg_info * msg_info;
939 chashdatum key;
940 chashdatum data;
941
942 folder = get_mh_cur_folder(session);
943
944#if 0
945 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num);
946 if (msg_info == NULL)
947 return MAIL_ERROR_CACHE_MISS;
948#endif
949 key.data = &num;
950 key.len = sizeof(num);
951 r = chash_get(folder->fl_msgs_hash, &key, &data);
952 if (r < 0)
953 return MAIL_ERROR_CACHE_MISS;
954 msg_info = data.data;
955
956 snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope",
957 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size);
958
959 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
960 if (r != MAIL_NO_ERROR) {
961 res = r;
962 goto err;
963 }
964
965 * result = fields;
966
967 return MAIL_NO_ERROR;
968
969 err:
970 return res;
971}
972
973static int
974write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
975 mailsession * session, uint32_t num,
976 struct mailimf_fields * fields)
977{
978 int r;
979 char keyname[PATH_MAX];
980 int res;
981 struct mailmh_folder * folder;
982 chashdatum key;
983 chashdatum data;
984 struct mailmh_msg_info * msg_info;
985
986 folder = get_mh_cur_folder(session);
987#if 0
988 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num);
989 if (msg_info == NULL) {
990 res = MAIL_ERROR_CACHE_MISS;
991 goto err;
992 }
993#endif
994 key.data = &num;
995 key.len = sizeof(num);
996 r = chash_get(folder->fl_msgs_hash, &key, &data);
997 if (r < 0)
998 return MAIL_ERROR_CACHE_MISS;
999 msg_info = data.data;
1000
1001 snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope",
1002 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size);
1003
1004 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
1005 if (r != MAIL_NO_ERROR) {
1006 res = r;
1007 goto err;
1008 }
1009
1010 return MAIL_NO_ERROR;
1011
1012 err:
1013 return res;
1014}
1015
1016static int
1017mhdriver_cached_get_envelopes_list(mailsession * session,
1018 struct mailmessage_list * env_list)
1019{
1020 int r;
1021 unsigned int i;
1022 char filename_env[PATH_MAX];
1023 char filename_flags[PATH_MAX];
1024 struct mail_cache_db * cache_db_env;
1025 struct mail_cache_db * cache_db_flags;
1026 MMAPString * mmapstr;
1027 int res;
1028 struct mh_cached_session_state_data * cached_data;
1029
1030 cached_data = get_cached_data(session);
1031 if (cached_data->mh_quoted_mb == NULL) {
1032 res = MAIL_ERROR_BAD_STATE;
1033 goto err;
1034 }
1035
1036 mh_flags_store_process(cached_data->mh_flags_directory,
1037 cached_data->mh_quoted_mb,
1038 cached_data->mh_flags_store);
1039
1040 mmapstr = mmap_string_new("");
1041 if (mmapstr == NULL) {
1042 res = MAIL_ERROR_MEMORY;
1043 goto err;
1044 }
1045
1046 snprintf(filename_env, PATH_MAX, "%s/%s/%s",
1047 cached_data->mh_cache_directory,
1048 cached_data->mh_quoted_mb, ENV_NAME);
1049
1050 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1051 if (r < 0) {
1052 res = MAIL_ERROR_MEMORY;
1053 goto free_mmapstr;
1054 }
1055
1056 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
1057 cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME);
1058
1059 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1060 if (r < 0) {
1061 res = MAIL_ERROR_MEMORY;
1062 goto close_db_env;
1063 }
1064
1065 /* fill with cached */
1066
1067 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1068 mailmessage * msg;
1069 struct mailimf_fields * fields;
1070 struct mail_flags * flags;
1071
1072 msg = carray_get(env_list->msg_tab, i);
1073
1074 if (msg->msg_fields == NULL) {
1075 r = get_cached_envelope(cache_db_env, mmapstr,
1076 msg->msg_session, msg->msg_index, &fields);
1077 if (r == MAIL_NO_ERROR) {
1078 msg->msg_cached = TRUE;
1079 msg->msg_fields = fields;
1080 }
1081 }
1082
1083 if (msg->msg_flags == NULL) {
1084 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
1085 session, msg->msg_index, &flags);
1086 if (r == MAIL_NO_ERROR) {
1087 msg->msg_flags = flags;
1088 }
1089 }
1090 }
1091
1092 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1093 mail_cache_db_close_unlock(filename_env, cache_db_env);
1094
1095 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
1096
1097 if (r != MAIL_NO_ERROR) {
1098 res = r;
1099 goto free_mmapstr;
1100 }
1101
1102 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1103 if (r < 0) {
1104 res = MAIL_ERROR_MEMORY;
1105 goto free_mmapstr;
1106 }
1107
1108 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1109 if (r < 0) {
1110 res = MAIL_ERROR_MEMORY;
1111 goto close_db_env;
1112 }
1113
1114 /* add flags */
1115
1116 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1117 mailmessage * msg;
1118
1119 msg = carray_get(env_list->msg_tab, i);
1120
1121 if (msg->msg_flags == NULL)
1122 msg->msg_flags = mail_flags_new_empty();
1123 }
1124
1125 /* must write cache */
1126
1127 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1128 mailmessage * msg;
1129
1130 msg = carray_get(env_list->msg_tab, i);
1131
1132 if (msg->msg_fields != NULL) {
1133 if (!msg->msg_cached) {
1134 r = write_cached_envelope(cache_db_env, mmapstr,
1135 session, msg->msg_index, msg->msg_fields);
1136 }
1137 }
1138
1139 if (msg->msg_flags != NULL) {
1140 r = mhdriver_write_cached_flags(cache_db_flags, mmapstr,
1141 msg->msg_uid, msg->msg_flags);
1142 }
1143 }
1144
1145 /* flush cache */
1146
1147 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
1148
1149 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1150 mail_cache_db_close_unlock(filename_env, cache_db_env);
1151
1152 mmap_string_free(mmapstr);
1153
1154 return MAIL_NO_ERROR;
1155
1156 close_db_env:
1157 mail_cache_db_close_unlock(filename_env, cache_db_env);
1158 free_mmapstr:
1159 mmap_string_free(mmapstr);
1160 err:
1161 return res;
1162}
1163
1164static int mhdriver_cached_get_message(mailsession * session,
1165 uint32_t num, mailmessage ** result)
1166{
1167 mailmessage * msg_info;
1168 int r;
1169
1170 msg_info = mailmessage_new();
1171 if (msg_info == NULL)
1172 return MAIL_ERROR_MEMORY;
1173
1174 r = mailmessage_init(msg_info, session, mh_cached_message_driver, num, 0);
1175 if (r != MAIL_NO_ERROR)
1176 return r;
1177
1178 * result = msg_info;
1179
1180 return MAIL_NO_ERROR;
1181}
1182
1183static int mhdriver_cached_get_message_by_uid(mailsession * session,
1184 const char * uid,
1185 mailmessage ** result)
1186{
1187 uint32_t index;
1188 char *p;
1189 struct mailmh_msg_info * mh_msg_info;
1190 struct mailmh_folder * folder;
1191 time_t mtime;
1192 char * mtime_p;
1193 chashdatum key;
1194 chashdatum data;
1195 int r;
1196
1197 if (uid == NULL)
1198 return MAIL_ERROR_INVAL;
1199
1200 index = strtoul(uid, &p, 10);
1201 if (p == uid || * p != '-')
1202 return MAIL_ERROR_INVAL;
1203
1204 folder = get_mh_cur_folder(session);
1205
1206 mh_msg_info = NULL;
1207 key.data = &index;
1208 key.len = sizeof(index);
1209 r = chash_get(folder->fl_msgs_hash, &key, &data);
1210 if (r < 0)
1211 return MAIL_ERROR_MSG_NOT_FOUND;
1212
1213 mh_msg_info = data.data;
1214
1215 mtime_p = p + 1;
1216
1217 mtime = strtoul(mtime_p, &p, 10);
1218 if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) {
1219 size_t size;
1220 char *size_p;
1221
1222 size_p = p + 1;
1223 size = strtoul(size_p, &p, 10);
1224 if ((* p == '\0') && (size == mh_msg_info->msg_size))
1225 return mhdriver_cached_get_message(session, index, result);
1226 }
1227 else if (*p != '-') {
1228 return MAIL_ERROR_INVAL;
1229 }
1230
1231 return MAIL_ERROR_MSG_NOT_FOUND;
1232}
diff --git a/kmicromail/libetpan/generic/mhdriver_cached.h b/kmicromail/libetpan/generic/mhdriver_cached.h
new file mode 100644
index 0000000..4a07e7d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached.h
@@ -0,0 +1,52 @@
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#ifndef MHDRIVER_CACHED_H
37
38#define MHDRIVER_CACHED_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * mh_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_cached_message.c b/kmicromail/libetpan/generic/mhdriver_cached_message.c
new file mode 100644
index 0000000..f716fb9
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached_message.c
@@ -0,0 +1,338 @@
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 "mhdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "mhdriver_tools.h"
40#include "mhdriver_cached.h"
41#include "mailmh.h"
42#include "generic_cache.h"
43
44#include "mail_cache_db.h"
45
46#include <unistd.h>
47#include <sys/mman.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <string.h>
52#include <stdlib.h>
53
54static int mh_prefetch(mailmessage * msg_info);
55
56static void mh_prefetch_free(struct generic_message_t * msg);
57
58static int mh_initialize(mailmessage * msg_info);
59
60static int mh_fetch_size(mailmessage * msg_info,
61 size_t * result);
62
63static int mh_get_flags(mailmessage * msg_info,
64 struct mail_flags ** result);
65
66static void mh_uninitialize(mailmessage * msg_info);
67
68static void mh_flush(mailmessage * msg_info);
69
70static void mh_check(mailmessage * msg_info);
71
72static int mh_fetch_header(mailmessage * msg_info,
73 char ** result,
74 size_t * result_len);
75
76static mailmessage_driver local_mh_cached_message_driver = {
77 .msg_name = "mh-cached",
78
79 .msg_initialize = mh_initialize,
80 .msg_uninitialize = mh_uninitialize,
81
82 .msg_flush = mh_flush,
83 .msg_check = mh_check,
84
85 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
86
87 .msg_fetch = mailmessage_generic_fetch,
88 .msg_fetch_header = mh_fetch_header,
89 .msg_fetch_body = mailmessage_generic_fetch_body,
90 .msg_fetch_size = mh_fetch_size,
91 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
92 .msg_fetch_section = mailmessage_generic_fetch_section,
93 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
94 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
95 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
96 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
97
98 .msg_get_flags = mh_get_flags,
99};
100
101mailmessage_driver * mh_cached_message_driver =
102&local_mh_cached_message_driver;
103
104static inline struct mh_cached_session_state_data *
105get_cached_session_data(mailmessage * msg)
106{
107 return msg->msg_session->sess_data;
108}
109
110static inline mailsession * get_ancestor_session(mailmessage * msg)
111{
112 return get_cached_session_data(msg)->mh_ancestor;
113}
114
115static inline struct mh_session_state_data *
116get_ancestor_session_data(mailmessage * msg)
117{
118 return get_ancestor_session(msg)->sess_data;
119}
120
121static inline struct mailmh *
122get_mh_session(mailmessage * msg)
123{
124 return get_ancestor_session_data(msg)->mh_session;
125}
126
127static inline struct mailmh_folder *
128get_mh_cur_folder(mailmessage * msg)
129{
130 return get_ancestor_session_data(msg)->mh_cur_folder;
131}
132
133static int mh_prefetch(mailmessage * msg_info)
134{
135 struct generic_message_t * msg;
136 int r;
137 char * msg_content;
138 size_t msg_length;
139
140 r = mhdriver_fetch_message(get_ancestor_session(msg_info),
141 msg_info->msg_index, &msg_content, &msg_length);
142 if (r != MAIL_NO_ERROR)
143 return r;
144
145 msg = msg_info->msg_data;
146
147 msg->msg_message = msg_content;
148 msg->msg_length = msg_length;
149
150 return MAIL_NO_ERROR;
151}
152
153static void mh_prefetch_free(struct generic_message_t * msg)
154{
155 if (msg->msg_message != NULL) {
156 mmap_string_unref(msg->msg_message);
157 msg->msg_message = NULL;
158 }
159}
160
161static int mh_initialize(mailmessage * msg_info)
162{
163 struct generic_message_t * msg;
164 int r;
165 char * uid;
166 char static_uid[PATH_MAX];
167 struct mailmh_msg_info * mh_msg_info;
168 chashdatum key;
169 chashdatum data;
170 struct mailmh_folder * folder;
171
172 folder = get_mh_cur_folder(msg_info);
173
174 key.data = &msg_info->msg_index;
175 key.len = sizeof(msg_info->msg_index);
176 r = chash_get(folder->fl_msgs_hash, &key, &data);
177 if (r < 0)
178 return MAIL_ERROR_INVAL;
179
180 mh_msg_info = data.data;
181
182 snprintf(static_uid, PATH_MAX, "%u-%lu-%u", msg_info->msg_index,
183 mh_msg_info->msg_mtime, mh_msg_info->msg_size);
184 uid = strdup(static_uid);
185 if (uid == NULL)
186 return MAIL_ERROR_MEMORY;
187
188 r = mailmessage_generic_initialize(msg_info);
189 if (r != MAIL_NO_ERROR) {
190 free(uid);
191 return r;
192 }
193
194 msg = msg_info->msg_data;
195 msg->msg_prefetch = mh_prefetch;
196 msg->msg_prefetch_free = mh_prefetch_free;
197 msg_info->msg_uid = uid;
198
199 return MAIL_NO_ERROR;
200}
201
202static void mh_uninitialize(mailmessage * msg_info)
203{
204 mailmessage_generic_uninitialize(msg_info);
205}
206
207
208#define FLAGS_NAME "flags.db"
209
210static void mh_flush(mailmessage * msg_info)
211{
212 mailmessage_generic_flush(msg_info);
213}
214
215static void mh_check(mailmessage * msg_info)
216{
217 int r;
218
219 if (msg_info->msg_flags != NULL) {
220 r = mail_flags_store_set(get_cached_session_data(msg_info)->mh_flags_store,
221 msg_info);
222 /* ignore errors */
223 }
224}
225
226static int mh_fetch_size(mailmessage * msg_info,
227 size_t * result)
228{
229 int r;
230 size_t size;
231
232 r = mhdriver_fetch_size(get_ancestor_session(msg_info),
233 msg_info->msg_index, &size);
234 if (r != MAIL_NO_ERROR)
235 return r;
236
237 * result = size;
238
239 return MAIL_NO_ERROR;
240}
241
242static int mh_get_flags(mailmessage * msg_info,
243 struct mail_flags ** result)
244{
245 int r;
246 struct mail_flags * flags;
247 struct mail_cache_db * cache_db_flags;
248 char filename_flags[PATH_MAX];
249 int res;
250 struct mh_cached_session_state_data * cached_data;
251 MMAPString * mmapstr;
252
253 if (msg_info->msg_flags != NULL) {
254 * result = msg_info->msg_flags;
255
256 return MAIL_NO_ERROR;
257 }
258
259 cached_data = get_cached_session_data(msg_info);
260
261 flags = mail_flags_store_get(cached_data->mh_flags_store,
262 msg_info->msg_index);
263
264 if (flags == NULL) {
265 if (cached_data->mh_quoted_mb == NULL) {
266 res = MAIL_ERROR_BAD_STATE;
267 goto err;
268 }
269
270 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
271 cached_data->mh_flags_directory,
272 cached_data->mh_quoted_mb, FLAGS_NAME);
273
274 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
275 if (r < 0) {
276 res = MAIL_ERROR_MEMORY;
277 goto err;
278 }
279
280 mmapstr = mmap_string_new("");
281 if (mmapstr == NULL) {
282 res = MAIL_ERROR_MEMORY;
283 goto close_db_flags;
284 }
285
286 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
287 msg_info->msg_session, msg_info->msg_index, &flags);
288 if (r != MAIL_NO_ERROR) {
289 flags = mail_flags_new_empty();
290 if (flags == NULL) {
291 res = MAIL_ERROR_MEMORY;
292 goto free_mmapstr;
293 }
294 }
295
296 mmap_string_free(mmapstr);
297 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
298 }
299
300 msg_info->msg_flags = flags;
301
302 * result = flags;
303
304 return MAIL_NO_ERROR;
305
306 free_mmapstr:
307 mmap_string_free(mmapstr);
308 close_db_flags:
309 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
310 err:
311 return res;
312}
313
314static int mh_fetch_header(mailmessage * msg_info,
315 char ** result,
316 size_t * result_len)
317{
318 struct generic_message_t * msg;
319 int r;
320 char * msg_content;
321 size_t msg_length;
322
323 msg = msg_info->msg_data;
324 if (msg->msg_message != NULL) {
325 return mailmessage_generic_fetch_header(msg_info, result, result_len);
326 }
327 else {
328 r = mhdriver_fetch_header(get_ancestor_session(msg_info),
329 msg_info->msg_index, &msg_content, &msg_length);
330 if (r != MAIL_NO_ERROR)
331 return r;
332
333 * result = msg_content;
334 * result_len = msg_length;
335
336 return MAIL_NO_ERROR;
337 }
338}
diff --git a/kmicromail/libetpan/generic/mhdriver_cached_message.h b/kmicromail/libetpan/generic/mhdriver_cached_message.h
new file mode 100644
index 0000000..f3ed089
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached_message.h
@@ -0,0 +1,52 @@
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#ifndef MHDRIVER_CACHED_MESSAGE_H
37
38#define MHDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mh_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_message.c b/kmicromail/libetpan/generic/mhdriver_message.c
new file mode 100644
index 0000000..2c023e7
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_message.c
@@ -0,0 +1,212 @@
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 "mhdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "mhdriver_tools.h"
40#include "mhdriver.h"
41#include "mailmh.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 mh_prefetch(mailmessage * msg_info);
52
53static void mh_prefetch_free(struct generic_message_t * msg);
54
55static int mh_initialize(mailmessage * msg_info);
56
57static int mh_fetch_size(mailmessage * msg_info,
58 size_t * result);
59
60static int mh_fetch_header(mailmessage * msg_info,
61 char ** result,
62 size_t * result_len);
63
64static mailmessage_driver local_mh_message_driver = {
65 .msg_name = "mh",
66
67 .msg_initialize = mh_initialize,
68 .msg_uninitialize = mailmessage_generic_uninitialize,
69
70 .msg_flush = mailmessage_generic_flush,
71 .msg_check = NULL,
72
73 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
74
75 .msg_fetch = mailmessage_generic_fetch,
76 .msg_fetch_header = mh_fetch_header,
77 .msg_fetch_body = mailmessage_generic_fetch_body,
78 .msg_fetch_size = mh_fetch_size,
79 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
80 .msg_fetch_section = mailmessage_generic_fetch_section,
81 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
82 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
83 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
84 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
85
86 .msg_get_flags = NULL,
87};
88
89mailmessage_driver * mh_message_driver = &local_mh_message_driver;
90
91static int mh_prefetch(mailmessage * msg_info)
92{
93 struct generic_message_t * msg;
94 int r;
95 char * msg_content;
96 size_t msg_length;
97
98 r = mhdriver_fetch_message(msg_info->msg_session, msg_info->msg_index,
99 &msg_content, &msg_length);
100 if (r != MAIL_NO_ERROR)
101 return r;
102
103 msg = msg_info->msg_data;
104
105 msg->msg_message = msg_content;
106 msg->msg_length = msg_length;
107
108 return MAIL_NO_ERROR;
109}
110
111static void mh_prefetch_free(struct generic_message_t * msg)
112{
113 if (msg->msg_message != NULL) {
114 mmap_string_unref(msg->msg_message);
115 msg->msg_message = NULL;
116 }
117}
118
119static inline struct mh_session_state_data * get_data(mailmessage * msg)
120{
121 return msg->msg_session->sess_data;
122}
123
124static inline struct mailmh_folder * get_mh_cur_folder(mailmessage * msg)
125{
126 return get_data(msg)->mh_cur_folder;
127}
128
129static int mh_initialize(mailmessage * msg_info)
130{
131 struct generic_message_t * msg;
132 int r;
133 char * uid;
134 char static_uid[PATH_MAX];
135 struct mailmh_msg_info * mh_msg_info;
136 chashdatum key;
137 chashdatum value;
138
139 key.data = &msg_info->msg_index;
140 key.len = sizeof(msg_info->msg_index);
141 r = chash_get(get_mh_cur_folder(msg_info)->fl_msgs_hash, &key, &value);
142 if (r < 0)
143 return MAIL_ERROR_INVAL;
144
145 mh_msg_info = value.data;
146
147 snprintf(static_uid, PATH_MAX, "%u-%lu-%u", msg_info->msg_index,
148 mh_msg_info->msg_mtime, mh_msg_info->msg_size);
149 uid = strdup(static_uid);
150 if (uid == NULL)
151 return MAIL_ERROR_MEMORY;
152
153 r = mailmessage_generic_initialize(msg_info);
154 if (r != MAIL_NO_ERROR) {
155 free(uid);
156 return r;
157 }
158
159 msg = msg_info->msg_data;
160 msg->msg_prefetch = mh_prefetch;
161 msg->msg_prefetch_free = mh_prefetch_free;
162 msg_info->msg_uid = uid;
163
164 return MAIL_NO_ERROR;
165}
166
167
168static int mh_fetch_size(mailmessage * msg_info,
169 size_t * result)
170{
171 int r;
172 size_t size;
173
174 r = mhdriver_fetch_size(msg_info->msg_session, msg_info->msg_index, &size);
175 if (r != MAIL_NO_ERROR)
176 return r;
177
178 * result = size;
179
180 return MAIL_NO_ERROR;
181}
182
183
184
185
186static int mh_fetch_header(mailmessage * msg_info,
187 char ** result,
188 size_t * result_len)
189{
190 struct generic_message_t * msg;
191 int r;
192 char * msg_content;
193 size_t msg_length;
194
195 msg = msg_info->msg_data;
196 if (msg->msg_message != NULL) {
197
198 r = mailmessage_generic_fetch_header(msg_info, result, result_len);
199 return r;
200 }
201 else {
202 r = mhdriver_fetch_header(msg_info->msg_session, msg_info->msg_index,
203 &msg_content, &msg_length);
204 if (r != MAIL_NO_ERROR)
205 return r;
206
207 * result = msg_content;
208 * result_len = msg_length;
209
210 return MAIL_NO_ERROR;
211 }
212}
diff --git a/kmicromail/libetpan/generic/mhdriver_message.h b/kmicromail/libetpan/generic/mhdriver_message.h
new file mode 100644
index 0000000..a7cb2cf
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_message.h
@@ -0,0 +1,52 @@
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#ifndef MHDRIVER_MESSAGE_H
37
38#define MHDRIVER_MESSAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mh_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_tools.c b/kmicromail/libetpan/generic/mhdriver_tools.c
new file mode 100644
index 0000000..cb863fa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_tools.c
@@ -0,0 +1,475 @@
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 "mhdriver_tools.h"
37
38#include "mailmessage.h"
39#include "mhdriver.h"
40#include "mhdriver_cached.h"
41#include "maildriver_types.h"
42#include "mailmh.h"
43#include "generic_cache.h"
44#include "imfcache.h"
45#include "mail_cache_db.h"
46
47#include <unistd.h>
48#include <sys/mman.h>
49#include <sys/types.h>
50#include <sys/stat.h>
51#include <fcntl.h>
52#include <string.h>
53#include <stdlib.h>
54
55int mhdriver_mh_error_to_mail_error(int error)
56{
57 switch (error) {
58 case MAILMH_NO_ERROR:
59 return MAIL_NO_ERROR;
60
61 case MAILMH_ERROR_FOLDER:
62 return MAIL_NO_ERROR;
63
64 case MAILMH_ERROR_MEMORY:
65 return MAIL_ERROR_MEMORY;
66
67 case MAILMH_ERROR_FILE:
68 return MAIL_ERROR_FILE;
69
70 case MAILMH_ERROR_COULD_NOT_ALLOC_MSG:
71 return MAIL_ERROR_APPEND;
72
73 case MAILMH_ERROR_RENAME:
74 return MAIL_ERROR_RENAME;
75
76 case MAILMH_ERROR_MSG_NOT_FOUND:
77 return MAIL_ERROR_MSG_NOT_FOUND;
78
79 default:
80 return MAIL_ERROR_INVAL;
81 }
82}
83
84
85static inline struct mh_session_state_data * get_data(mailsession * session)
86{
87 return session->sess_data;
88}
89
90static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session)
91{
92 return get_data(session)->mh_cur_folder;
93}
94
95static inline struct mh_cached_session_state_data *
96cached_get_data(mailsession * session)
97{
98 return session->sess_data;
99}
100
101
102static inline mailsession * cached_get_ancestor(mailsession * session)
103{
104 return cached_get_data(session)->mh_ancestor;
105}
106
107static inline struct mh_session_state_data *
108cached_get_ancestor_data(mailsession * session)
109{
110 return get_data(cached_get_ancestor(session));
111}
112
113static inline struct mailmh_folder *
114cached_get_mh_cur_folder(mailsession * session)
115{
116 return get_mh_cur_folder(cached_get_ancestor(session));
117}
118
119int mhdriver_fetch_message(mailsession * session, uint32_t index,
120 char ** result, size_t * result_len)
121{
122 size_t size;
123 size_t cur_token;
124 struct mailmh_folder * folder;
125 int fd;
126 MMAPString * mmapstr;
127 char * str;
128 int res;
129 int r;
130
131 folder = get_mh_cur_folder(session);
132 if (folder == NULL) {
133 res = MAIL_ERROR_BAD_STATE;
134 goto err;
135 }
136
137 r = mailmh_folder_get_message_fd(folder, index, O_RDONLY, &fd);
138
139 switch (r) {
140 case MAILMH_NO_ERROR:
141 break;
142
143 default:
144 res = mhdriver_mh_error_to_mail_error(r);
145 goto close;
146 }
147
148 r = mhdriver_fetch_size(session, index, &size);
149
150 switch (r) {
151 case MAILMH_NO_ERROR:
152 break;
153
154 default:
155 res = mhdriver_mh_error_to_mail_error(r);
156 goto close;
157 }
158
159 str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
160 if (str == MAP_FAILED) {
161 res = MAIL_ERROR_FETCH;
162 goto close;
163 }
164
165 /* strip "From " header for broken implementations */
166 /* XXX - called twice, make a function */
167 cur_token = 0;
168 if (strncmp("From ", str, size) == 0) {
169 cur_token += 5;
170
171 while (str[cur_token] != '\n') {
172 if (cur_token >= size)
173 break;
174 cur_token ++;
175 }
176 }
177
178 mmapstr = mmap_string_new_len(str + cur_token, size - cur_token);
179 if (mmapstr == NULL) {
180 res = MAIL_ERROR_MEMORY;
181 goto unmap;
182 }
183
184 if (mmap_string_ref(mmapstr) != 0) {
185 res = MAIL_ERROR_MEMORY;
186 goto free_str;
187 }
188
189 munmap(str, size);
190 close(fd);
191
192 * result = mmapstr->str;
193 * result_len = mmapstr->len;
194
195 return MAIL_NO_ERROR;
196
197 free_str:
198 mmap_string_free(mmapstr);
199 unmap:
200 munmap(str, size);
201 close:
202 close(fd);
203 err:
204 return res;
205}
206
207
208int mhdriver_fetch_header(mailsession * session, uint32_t index,
209 char ** result, size_t * result_len)
210{
211 size_t size;
212 size_t cur_token;
213 size_t begin;
214 struct mailmh_folder * folder;
215 int fd;
216 MMAPString * mmapstr;
217 char * str;
218 int res;
219 int r;
220
221 folder = get_mh_cur_folder(session);
222 if (folder == NULL) {
223 res = MAIL_ERROR_BAD_STATE;
224 goto err;
225 }
226
227 r = mailmh_folder_get_message_fd(folder, index, O_RDONLY, &fd);
228
229 switch (r) {
230 case MAILMH_NO_ERROR:
231 break;
232
233 default:
234 res = mhdriver_mh_error_to_mail_error(r);
235 goto close;
236 }
237
238 r = mhdriver_fetch_size(session, index, &size);
239
240 switch (r) {
241 case MAILMH_NO_ERROR:
242 break;
243
244 default:
245 res = mhdriver_mh_error_to_mail_error(r);
246 goto close;
247 }
248
249 str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
250 if (str == MAP_FAILED) {
251 res = MAIL_ERROR_FETCH;
252 goto close;
253 }
254
255 /* strip "From " header for broken implementations */
256 cur_token = 0;
257 if (size > 5) {
258 if (strncmp("From ", str, size) == 0) {
259 cur_token += 5;
260
261 while (str[cur_token] != '\n') {
262 if (cur_token >= size)
263 break;
264 cur_token ++;
265 }
266 }
267 }
268
269 begin = cur_token;
270
271 while (1) {
272 r = mailimf_ignore_field_parse(str, size, &cur_token);
273 if (r == MAILIMF_NO_ERROR) {
274 /* do nothing */
275 }
276 else
277 break;
278 }
279 mailimf_crlf_parse(str, size, &cur_token);
280
281 mmapstr = mmap_string_new_len(str + begin, cur_token - begin);
282 if (mmapstr == NULL) {
283 res = MAIL_ERROR_MEMORY;
284 goto unmap;
285 }
286
287 if (mmap_string_ref(mmapstr) != 0) {
288 res = MAIL_ERROR_MEMORY;
289 goto free_str;
290 }
291
292 munmap(str, size);
293 close(fd);
294
295 * result = mmapstr->str;
296 * result_len = mmapstr->len;
297
298 return MAIL_NO_ERROR;
299
300 free_str:
301 mmap_string_free(mmapstr);
302 unmap:
303 munmap(str, size);
304 close:
305 close(fd);
306 err:
307 return res;
308}
309
310
311int mhdriver_fetch_size(mailsession * session, uint32_t index,
312 size_t * result)
313{
314 struct mailmh_folder * folder;
315 int r;
316 struct stat buf;
317 char * name;
318
319 folder = get_mh_cur_folder(session);
320 if (folder == NULL)
321 return MAIL_ERROR_FETCH;
322
323 r = mailmh_folder_get_message_filename(folder, index, &name);
324
325 switch (r) {
326 case MAILMH_NO_ERROR:
327 break;
328
329 default:
330 return mhdriver_mh_error_to_mail_error(r);
331 }
332
333 r = stat(name, &buf);
334 free(name);
335 if (r == -1)
336 return MAIL_ERROR_FETCH;
337
338 * result = buf.st_size;
339
340 return MAIL_NO_ERROR;
341}
342
343int
344mhdriver_get_cached_flags(struct mail_cache_db * cache_db,
345 MMAPString * mmapstr,
346 mailsession * session,
347 uint32_t num,
348 struct mail_flags ** result)
349{
350 int r;
351 char keyname[PATH_MAX];
352 struct mail_flags * flags;
353 int res;
354 struct mailmh_msg_info * msg_info;
355 chashdatum key;
356 chashdatum data;
357 struct mailmh_folder * folder;
358
359 folder = cached_get_mh_cur_folder(session);
360#if 0
361 msg_info = cinthash_find(mh_data->cur_folder->fl_msgs_hash, num);
362 if (msg_info == NULL)
363 return MAIL_ERROR_CACHE_MISS;
364#endif
365 key.data = &num;
366 key.len = sizeof(num);
367 r = chash_get(folder->fl_msgs_hash, &key, &data);
368 if (r < 0)
369 return MAIL_ERROR_CACHE_MISS;
370 msg_info = data.data;
371
372 snprintf(keyname, PATH_MAX, "%u-%u-%u-flags",
373 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size);
374
375 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
376 if (r != MAIL_NO_ERROR) {
377 res = r;
378 goto err;
379 }
380
381 * result = flags;
382
383 return MAIL_NO_ERROR;
384
385 err:
386 return res;
387}
388
389int
390mhdriver_write_cached_flags(struct mail_cache_db * cache_db,
391 MMAPString * mmapstr,
392 char * uid,
393 struct mail_flags * flags)
394{
395 int r;
396 char keyname[PATH_MAX];
397 int res;
398
399 snprintf(keyname, PATH_MAX, "%s-flags", uid);
400
401 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
402 if (r != MAIL_NO_ERROR) {
403 res = r;
404 goto err;
405 }
406
407 return MAIL_NO_ERROR;
408
409 err:
410 return res;
411}
412
413
414int mh_get_messages_list(struct mailmh_folder * folder,
415 mailsession * session, mailmessage_driver * driver,
416 struct mailmessage_list ** result)
417{
418 unsigned int i;
419 struct mailmessage_list * env_list;
420 int r;
421 carray * tab;
422 int res;
423
424 tab = carray_new(128);
425 if (tab == NULL) {
426 res = MAIL_ERROR_MEMORY;
427 goto err;
428 }
429
430 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) {
431 struct mailmh_msg_info * mh_info;
432 mailmessage * msg;
433
434 mh_info = carray_get(folder->fl_msgs_tab, i);
435 if (mh_info == NULL)
436 continue;
437
438 msg = mailmessage_new();
439 if (msg == NULL) {
440 res = MAIL_ERROR_MEMORY;
441 goto free_list;
442 }
443
444 r = mailmessage_init(msg, session, driver,
445 mh_info->msg_index, mh_info->msg_size);
446 if (r != MAIL_NO_ERROR) {
447 res = r;
448 goto free_list;
449 }
450
451 r = carray_add(tab, msg, NULL);
452 if (r < 0) {
453 mailmessage_free(msg);
454 res = MAIL_ERROR_MEMORY;
455 goto free_list;
456 }
457 }
458
459 env_list = mailmessage_list_new(tab);
460 if (env_list == NULL) {
461 res = MAIL_ERROR_MEMORY;
462 goto free_list;
463 }
464
465 * result = env_list;
466
467 return MAIL_NO_ERROR;
468
469 free_list:
470 for(i = 0 ; i < carray_count(tab) ; i ++)
471 mailmessage_free(carray_get(tab, i));
472 carray_free(tab);
473 err:
474 return res;
475}
diff --git a/kmicromail/libetpan/generic/mhdriver_tools.h b/kmicromail/libetpan/generic/mhdriver_tools.h
new file mode 100644
index 0000000..0d805c1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_tools.h
@@ -0,0 +1,80 @@
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#ifndef MHDRIVER_TOOLS_H
37
38#define MHDRIVER_TOOLS_H
39
40#include "maildriver_types.h"
41#include "mail_cache_db_types.h"
42#include "mailmh.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48int mhdriver_mh_error_to_mail_error(int error);
49
50int mhdriver_fetch_message(mailsession * session, uint32_t index,
51 char ** result, size_t * result_len);
52
53int mhdriver_fetch_header(mailsession * session, uint32_t index,
54 char ** result, size_t * result_len);
55
56int mhdriver_fetch_size(mailsession * session, uint32_t index,
57 size_t * result);
58
59int
60mhdriver_get_cached_flags(struct mail_cache_db * cache_db,
61 MMAPString * mmapstr,
62 mailsession * session,
63 uint32_t num,
64 struct mail_flags ** result);
65
66int
67mhdriver_write_cached_flags(struct mail_cache_db * cache_db,
68 MMAPString * mmapstr,
69 char * uid,
70 struct mail_flags * flags);
71
72int mh_get_messages_list(struct mailmh_folder * folder,
73 mailsession * session, mailmessage_driver * driver,
74 struct mailmessage_list ** result);
75
76#ifdef __cplusplus
77}
78#endif
79
80#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_types.h b/kmicromail/libetpan/generic/mhdriver_types.h
new file mode 100644
index 0000000..09c6cc6
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_types.h
@@ -0,0 +1,100 @@
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#ifndef MHDRIVER_TYPES_H
37
38#define MHDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/mailmh.h>
44#include <libetpan/clist.h>
45#include <libetpan/generic_cache_types.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52struct mh_session_state_data {
53 struct mailmh * mh_session;
54
55 struct mailmh_folder * mh_cur_folder;
56
57 clist * mh_subscribed_list;
58};
59
60enum {
61 MHDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
62 MHDRIVER_CACHED_SET_FLAGS_DIRECTORY,
63};
64
65struct mh_cached_session_state_data {
66 mailsession * mh_ancestor;
67 char * mh_quoted_mb;
68 char mh_cache_directory[PATH_MAX];
69 char mh_flags_directory[PATH_MAX];
70 struct mail_flags_store * mh_flags_store;
71};
72
73/* mh storage */
74
75/*
76 mh_mailstorage is the state data specific to the MH storage.
77
78 - pathname is the root path of the MH storage.
79
80 - cached if this value is != 0, a persistant cache will be
81 stored on local system.
82
83 - cache_directory is the location of the cache.
84
85 - flags_directory is the location of the flags.
86*/
87
88struct mh_mailstorage {
89 char * mh_pathname;
90
91 int mh_cached;
92 char * mh_cache_directory;
93 char * mh_flags_directory;
94};
95
96#ifdef __cplusplus
97}
98#endif
99
100#endif
diff --git a/kmicromail/libetpan/generic/mhstorage.c b/kmicromail/libetpan/generic/mhstorage.c
new file mode 100644
index 0000000..32fc26b
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhstorage.c
@@ -0,0 +1,192 @@
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 "mhstorage.h"
37
38#include "mhdriver.h"
39#include "mhdriver_cached.h"
40#include "mail.h"
41
42#include <stdlib.h>
43#include <string.h>
44
45/* mh storage */
46
47static int mh_mailstorage_connect(struct mailstorage * storage);
48static int mh_mailstorage_get_folder_session(struct mailstorage * storage,
49 char * pathname, mailsession ** result);
50static void mh_mailstorage_uninitialize(struct mailstorage * storage);
51
52static mailstorage_driver mh_mailstorage_driver = {
53 .sto_name = "mh",
54 .sto_connect = mh_mailstorage_connect,
55 .sto_get_folder_session = mh_mailstorage_get_folder_session,
56 .sto_uninitialize = mh_mailstorage_uninitialize,
57};
58
59int mh_mailstorage_init(struct mailstorage * storage,
60 char * mh_pathname, int mh_cached,
61 char * mh_cache_directory, char * mh_flags_directory)
62{
63 struct mh_mailstorage * mh_storage;
64
65 mh_storage = malloc(sizeof(struct mh_mailstorage));
66 if (mh_storage == NULL)
67 goto err;
68
69 mh_storage->mh_pathname = strdup(mh_pathname);
70 if (mh_storage->mh_pathname == NULL)
71 goto free;
72
73 mh_storage->mh_cached = mh_cached;
74
75 if (mh_cached && (mh_cache_directory != NULL) &&
76 (mh_flags_directory != NULL)) {
77 mh_storage->mh_cache_directory = strdup(mh_cache_directory);
78 if (mh_storage->mh_cache_directory == NULL)
79 goto free_pathname;
80 mh_storage->mh_flags_directory = strdup(mh_flags_directory);
81 if (mh_storage->mh_flags_directory == NULL)
82 goto free_cache_directory;
83 }
84 else {
85 mh_storage->mh_cached = FALSE;
86 mh_storage->mh_cache_directory = NULL;
87 mh_storage->mh_flags_directory = NULL;
88 }
89
90 storage->sto_data = mh_storage;
91 storage->sto_driver = &mh_mailstorage_driver;
92
93 return MAIL_NO_ERROR;
94
95 free_cache_directory:
96 free(mh_storage->mh_cache_directory);
97 free_pathname:
98 free(mh_storage->mh_pathname);
99 free:
100 free(mh_storage);
101 err:
102 return MAIL_ERROR_MEMORY;
103}
104
105static void mh_mailstorage_uninitialize(struct mailstorage * storage)
106{
107 struct mh_mailstorage * mh_storage;
108
109 mh_storage = storage->sto_data;
110 if (mh_storage->mh_flags_directory != NULL)
111 free(mh_storage->mh_flags_directory);
112 if (mh_storage->mh_cache_directory != NULL)
113 free(mh_storage->mh_cache_directory);
114 free(mh_storage->mh_pathname);
115 free(mh_storage);
116
117 storage->sto_data = NULL;
118}
119
120static int mh_mailstorage_connect(struct mailstorage * storage)
121{
122 struct mh_mailstorage * mh_storage;
123 mailsession_driver * driver;
124 int r;
125 int res;
126 mailsession * session;
127
128 mh_storage = storage->sto_data;
129
130 if (mh_storage->mh_cached)
131 driver = mh_cached_session_driver;
132 else
133 driver = mh_session_driver;
134
135 session = mailsession_new(driver);
136 if (session == NULL) {
137 res = MAIL_ERROR_MEMORY;
138 goto err;
139 }
140
141 if (mh_storage->mh_cached) {
142 r = mailsession_parameters(session,
143 MHDRIVER_CACHED_SET_CACHE_DIRECTORY,
144 mh_storage->mh_cache_directory);
145 if (r != MAIL_NO_ERROR) {
146 res = r;
147 goto free;
148 }
149
150 r = mailsession_parameters(session,
151 MHDRIVER_CACHED_SET_FLAGS_DIRECTORY,
152 mh_storage->mh_flags_directory);
153 if (r != MAIL_NO_ERROR) {
154 res = r;
155 goto free;
156 }
157 }
158
159 r = mailsession_connect_path(session, mh_storage->mh_pathname);
160 switch (r) {
161 case MAIL_NO_ERROR_NON_AUTHENTICATED:
162 case MAIL_NO_ERROR_AUTHENTICATED:
163 case MAIL_NO_ERROR:
164 break;
165 default:
166 res = r;
167 goto free;
168 }
169
170 storage->sto_session = session;
171
172 return MAIL_NO_ERROR;
173
174 free:
175 mailsession_free(session);
176 err:
177 return res;
178}
179
180static int mh_mailstorage_get_folder_session(struct mailstorage * storage,
181 char * pathname, mailsession ** result)
182{
183 int r;
184
185 r = mailsession_select_folder(storage->sto_session, pathname);
186 if (r != MAIL_NO_ERROR)
187 return r;
188
189 * result = storage->sto_session;
190
191 return MAIL_NO_ERROR;
192}
diff --git a/kmicromail/libetpan/generic/mhstorage.h b/kmicromail/libetpan/generic/mhstorage.h
new file mode 100644
index 0000000..245bc81
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhstorage.h
@@ -0,0 +1,67 @@
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#ifndef MHSTORAGE_H
37
38#define MHSTORAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mh_mailstorage_init is the constructor for a MH storage
48
49 @param pathname is the filename the root path of the MH storage.
50
51 @param cached if this value is != 0, a persistant cache will be
52 stored on local system.
53
54 @param cache_directory is the location of the cache.
55
56 @param flags_directory is the location of the flags.
57*/
58
59int mh_mailstorage_init(struct mailstorage * storage,
60 char * mh_pathname, int mh_cached,
61 char * mh_cache_directory, char * mh_flags_directory);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/kmicromail/libetpan/generic/mime_message_driver.c b/kmicromail/libetpan/generic/mime_message_driver.c
new file mode 100644
index 0000000..273875e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mime_message_driver.c
@@ -0,0 +1,689 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - 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 "mime_message_driver.h"
37
38#include "libetpan-config.h"
39
40#include <sys/stat.h>
41#include <sys/types.h>
42#include <unistd.h>
43#include <sys/mman.h>
44#include <stdlib.h>
45#include <string.h>
46
47#include "mailmessage.h"
48#include "mailmessage_tools.h"
49#include "maildriver_tools.h"
50
51static FILE * get_mime_tmp_file(mailmessage * msg,
52 char * filename, size_t size)
53{
54 int fd;
55 mode_t old_mask;
56 FILE * f;
57
58 if (msg->msg_data == NULL)
59 return NULL;
60
61 snprintf(filename, size, "%s/libetpan-mime-XXXXXX",
62 (char *) msg->msg_data);
63
64 old_mask = umask(0077);
65 fd = mkstemp(filename);
66 umask(old_mask);
67 if (fd == -1)
68 return NULL;
69
70 f = fdopen(fd, "r+");
71 if (f == NULL) {
72 close(fd);
73 unlink(filename);
74 }
75
76 return f;
77}
78
79int mime_message_set_tmpdir(mailmessage * msg, char * tmpdir)
80{
81 if (msg->msg_data != NULL)
82 free(msg->msg_data);
83
84 msg->msg_data = strdup(tmpdir);
85 if (msg->msg_data == NULL)
86 return MAIL_ERROR_MEMORY;
87
88 return MAIL_NO_ERROR;
89}
90
91void mime_message_detach_mime(mailmessage * msg)
92{
93 msg->msg_mime = NULL;
94}
95
96mailmessage * mime_message_init(struct mailmime * mime)
97{
98 mailmessage * msg;
99 int r;
100
101 msg = mailmessage_new();
102 if (msg == NULL)
103 goto err;
104
105 r = mailmessage_init(msg, NULL, mime_message_driver, 0, 0);
106 if (r != MAIL_NO_ERROR)
107 goto free;
108
109 if (mime != NULL) {
110 mailmime_free(msg->msg_mime);
111 msg->msg_mime = mime;
112 }
113
114 return msg;
115
116 free:
117 mailmessage_free(msg);
118 err:
119 return NULL;
120}
121
122static int initialize(mailmessage * msg)
123{
124 struct mailmime * mime;
125 int res;
126
127 mime = mailmime_new_message_data(NULL);
128 if (mime == NULL) {
129 res = MAIL_ERROR_MEMORY;
130 goto err;
131 }
132
133 msg->msg_mime = mime;
134
135 return MAIL_NO_ERROR;
136
137 err:
138 return res;
139}
140
141static void uninitialize(mailmessage * msg)
142{
143 /* tmp dir name */
144 if (msg->msg_data != NULL)
145 free(msg->msg_data);
146
147 if (msg->msg_mime != NULL)
148 mailmime_free(msg->msg_mime);
149 msg->msg_mime = NULL;
150}
151
152static void flush(mailmessage * msg)
153{
154 /* do nothing */
155}
156
157static void check(mailmessage * msg)
158{
159 /* do nothing */
160}
161
162static void fetch_result_free(mailmessage * msg_info, char * content)
163{
164 mmap_string_unref(content);
165}
166
167static int file_to_mmapstr(FILE * f,
168 char ** result, size_t * result_len)
169{
170 int fd;
171 char * data;
172 struct stat buf;
173 MMAPString * mmapstr;
174 int res;
175 int r;
176
177 fd = fileno(f);
178 if (fd == -1) {
179 res = MAIL_ERROR_FILE;
180
181 goto err;
182 }
183
184 fflush(f);
185 r = fstat(fd, &buf);
186 if (r == -1) {
187 res = MAIL_ERROR_FILE;
188
189 goto err;
190 }
191
192 data = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
193 if (data == MAP_FAILED) {
194 res = MAIL_ERROR_FILE;
195
196 goto err;
197 }
198
199 mmapstr = mmap_string_new_len(data, buf.st_size);
200 if (mmapstr == NULL) {
201 res = MAIL_ERROR_MEMORY;
202
203 goto unmap;
204 }
205
206 munmap(data, buf.st_size);
207
208 r = mmap_string_ref(mmapstr);
209 if (r != 0) {
210 res = MAIL_ERROR_MEMORY;
211
212 goto err;
213 }
214
215 * result = mmapstr->str;
216 * result_len = mmapstr->len;
217
218 return MAIL_NO_ERROR;
219
220 unmap:
221 munmap(data, buf.st_size);
222 err:
223 return res;
224}
225
226
227static int file_body_to_mmapstr(FILE * f,
228 char ** result, size_t * result_len)
229{
230 int fd;
231 char * data;
232 struct stat buf;
233 MMAPString * mmapstr;
234 size_t cur_token;
235 int res;
236 int r;
237
238 fd = fileno(f);
239 if (fd == -1) {
240 res = MAIL_ERROR_FILE;
241
242 goto err;
243 }
244
245 fflush(f);
246 r = fstat(fd, &buf);
247 if (r == -1) {
248 res = MAIL_ERROR_FILE;
249
250 goto err;
251 }
252
253 data = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
254 if (data == MAP_FAILED) {
255 res = MAIL_ERROR_FILE;
256
257 goto err;
258 }
259
260 cur_token = 0;
261
262 /* skip header */
263
264 while (1) {
265 r = mailimf_ignore_field_parse(data,
266 buf.st_size, &cur_token);
267 if (r == MAILIMF_NO_ERROR) {
268 /* do nothing */
269 }
270 else
271 break;
272 }
273
274 r = mailimf_crlf_parse(data, buf.st_size, &cur_token);
275 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
276 res = maildriver_imf_error_to_mail_error(r);
277 goto unmap;
278 }
279
280 mmapstr = mmap_string_new_len(data + cur_token, buf.st_size - cur_token);
281 if (mmapstr == NULL) {
282 res = MAIL_ERROR_MEMORY;
283
284 goto unmap;
285 }
286
287 munmap(data, buf.st_size);
288
289 r = mmap_string_ref(mmapstr);
290 if (r != 0) {
291 res = MAIL_ERROR_MEMORY;
292
293 goto err;
294 }
295
296 * result = mmapstr->str;
297 * result_len = mmapstr->len;
298
299 return MAIL_NO_ERROR;
300
301 unmap:
302 munmap(data, buf.st_size);
303 err:
304 return res;
305}
306
307static int file_body_body_to_mmapstr(FILE * f,
308 char ** result, size_t * result_len)
309{
310 int fd;
311 char * data;
312 struct stat buf;
313 MMAPString * mmapstr;
314 size_t cur_token;
315 int res;
316 int r;
317
318 fd = fileno(f);
319 if (fd == -1) {
320 res = MAIL_ERROR_FILE;
321
322 goto err;
323 }
324
325 fflush(f);
326 r = fstat(fd, &buf);
327 if (r == -1) {
328 res = MAIL_ERROR_FILE;
329
330 goto err;
331 }
332
333 data = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
334 if (data == MAP_FAILED) {
335 res = MAIL_ERROR_FILE;
336
337 goto err;
338 }
339
340 cur_token = 0;
341
342 /* skip header */
343
344 /* MIME header */
345
346 while (1) {
347 r = mailimf_ignore_field_parse(data,
348 buf.st_size, &cur_token);
349 if (r == MAILIMF_NO_ERROR) {
350 /* do nothing */
351 }
352 else
353 break;
354 }
355
356 r = mailimf_crlf_parse(data, buf.st_size, &cur_token);
357 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
358 res = maildriver_imf_error_to_mail_error(r);
359 goto unmap;
360 }
361
362 /* headers */
363
364 while (1) {
365 r = mailimf_ignore_field_parse(data,
366 buf.st_size, &cur_token);
367 if (r == MAILIMF_NO_ERROR) {
368 /* do nothing */
369 }
370 else
371 break;
372 }
373
374 r = mailimf_crlf_parse(data, buf.st_size, &cur_token);
375 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
376 res = maildriver_imf_error_to_mail_error(r);
377 goto unmap;
378 }
379
380 mmapstr = mmap_string_new_len(data + cur_token, buf.st_size - cur_token);
381 if (mmapstr == NULL) {
382 res = MAIL_ERROR_MEMORY;
383
384 goto unmap;
385 }
386
387 munmap(data, buf.st_size);
388
389 r = mmap_string_ref(mmapstr);
390 if (r != 0) {
391 res = MAIL_ERROR_MEMORY;
392
393 goto err;
394 }
395
396 * result = mmapstr->str;
397 * result_len = mmapstr->len;
398
399 return MAIL_NO_ERROR;
400
401 unmap:
402 munmap(data, buf.st_size);
403 err:
404 return res;
405}
406
407
408
409static int fetch_section(mailmessage * msg_info,
410 struct mailmime * mime,
411 char ** result, size_t * result_len)
412{
413 int r;
414 FILE * f;
415 int res;
416 int col;
417 char filename[PATH_MAX];
418
419 if (msg_info->msg_mime == NULL)
420 return MAIL_ERROR_INVAL;
421
422 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
423 if (f == NULL) {
424 res = MAIL_ERROR_FILE;
425 goto err;
426 }
427
428 col = 0;
429 r = mailmime_write(f, &col, mime);
430 if (r != MAILIMF_NO_ERROR) {
431 res = maildriver_imf_error_to_mail_error(r);
432 goto close;
433 }
434
435 if (mime->mm_parent == NULL)
436 r = file_to_mmapstr(f, result, result_len);
437 else
438 r = file_body_to_mmapstr(f, result, result_len);
439
440 if (r != MAIL_NO_ERROR) {
441 res = r;
442 goto close;
443 }
444
445 fclose(f);
446 unlink(filename);
447
448 return MAIL_NO_ERROR;
449
450 close:
451 fclose(f);
452 unlink(filename);
453 err:
454 return res;
455}
456
457
458static int fetch_section_header(mailmessage * msg_info,
459 struct mailmime * mime,
460 char ** result, size_t * result_len)
461{
462 int r;
463 FILE * f;
464 int res;
465 int col;
466 char filename[PATH_MAX];
467
468 if (msg_info->msg_mime == NULL)
469 return MAIL_ERROR_INVAL;
470
471 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
472 if (f == NULL) {
473 res = MAIL_ERROR_FILE;
474 goto err;
475 }
476
477 col = 0;
478 if (mime->mm_type == MAILMIME_MESSAGE) {
479 if (mime->mm_data.mm_message.mm_fields != NULL) {
480 r = mailimf_fields_write(f, &col, mime->mm_data.mm_message.mm_fields);
481 if (r != MAILIMF_NO_ERROR) {
482 res = maildriver_imf_error_to_mail_error(r);
483 goto close;
484 }
485 mailimf_string_write(f, &col, "\r\n", 2);
486 }
487 }
488
489 r = file_to_mmapstr(f, result, result_len);
490 if (r != MAIL_NO_ERROR) {
491 res = r;
492 goto close;
493 }
494
495 fclose(f);
496 unlink(filename);
497
498 return MAIL_NO_ERROR;
499
500 close:
501 fclose(f);
502 unlink(filename);
503 err:
504 return res;
505}
506
507
508static int fetch_section_mime(mailmessage * msg_info,
509 struct mailmime * mime,
510 char ** result, size_t * result_len)
511{
512 int r;
513 FILE * f;
514 int res;
515 int col;
516 char filename[PATH_MAX];
517
518 if (msg_info->msg_mime == NULL)
519 return MAIL_ERROR_INVAL;
520
521 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
522 if (f == NULL) {
523 res = MAIL_ERROR_FILE;
524 goto err;
525 }
526
527 col = 0;
528 if (mime->mm_content_type != NULL) {
529 r = mailmime_content_write(f, &col, mime->mm_content_type);
530 if (r != MAILIMF_NO_ERROR) {
531 res = maildriver_imf_error_to_mail_error(r);
532 goto close;
533 }
534 }
535 if (mime->mm_mime_fields != NULL) {
536 r = mailmime_fields_write(f, &col, mime->mm_mime_fields);
537 if (r != MAILIMF_NO_ERROR) {
538 res = maildriver_imf_error_to_mail_error(r);
539 goto close;
540 }
541 }
542 mailimf_string_write(f, &col, "\r\n", 2);
543
544 r = file_to_mmapstr(f, result, result_len);
545 if (r != MAIL_NO_ERROR) {
546 res = r;
547 goto close;
548 }
549
550 fclose(f);
551 unlink(filename);
552
553 return MAIL_NO_ERROR;
554
555 close:
556 fclose(f);
557 unlink(filename);
558 err:
559 return res;
560}
561
562
563
564static int fetch_section_body(mailmessage * msg_info,
565 struct mailmime * mime,
566 char ** result, size_t * result_len)
567{
568 int r;
569 FILE * f;
570 int res;
571 int col;
572 char filename[PATH_MAX];
573
574 if (msg_info->msg_mime == NULL)
575 return MAIL_ERROR_INVAL;
576
577 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
578 if (f == NULL) {
579 res = MAIL_ERROR_FILE;
580 goto err;
581 }
582
583 col = 0;
584 if (mime->mm_mime_fields != NULL) {
585 r = mailmime_write(f, &col, mime);
586 if (r != MAILIMF_NO_ERROR) {
587 res = maildriver_imf_error_to_mail_error(r);
588 goto close;
589 }
590 }
591
592 if (mime->mm_type == MAILMIME_MESSAGE)
593 r = file_body_body_to_mmapstr(f, result, result_len);
594 else
595 r = file_body_to_mmapstr(f, result, result_len);
596
597 if (r != MAIL_NO_ERROR) {
598 res = r;
599 goto close;
600 }
601
602 fclose(f);
603 unlink(filename);
604
605 return MAIL_NO_ERROR;
606
607 close:
608 fclose(f);
609 unlink(filename);
610 err:
611 return res;
612}
613
614
615static int get_bodystructure(mailmessage * msg_info,
616 struct mailmime ** result)
617{
618 if (msg_info->msg_mime == NULL)
619 return MAIL_ERROR_INVAL;
620
621 * result = msg_info->msg_mime;
622
623 return MAIL_NO_ERROR;
624}
625
626
627static int fetch(mailmessage * msg_info,
628 char ** result, size_t * result_len)
629{
630 return fetch_section(msg_info, msg_info->msg_mime, result, result_len);
631}
632
633static int fetch_header(mailmessage * msg_info,
634 char ** result, size_t * result_len)
635{
636 return fetch_section_header(msg_info,
637 msg_info->msg_mime, result, result_len);
638}
639
640static int fetch_body(mailmessage * msg_info,
641 char ** result, size_t * result_len)
642{
643 return fetch_section_body(msg_info, msg_info->msg_mime, result, result_len);
644}
645
646
647static int fetch_size(mailmessage * msg_info,
648 size_t * result)
649{
650 char * msg;
651 int r;
652
653 r = fetch(msg_info, &msg, result);
654 if (r != MAIL_NO_ERROR) {
655 return r;
656 }
657
658 fetch_result_free(msg_info, msg);
659
660 return MAIL_NO_ERROR;
661}
662
663
664static mailmessage_driver local_mime_message_driver = {
665 .msg_name = "mime",
666
667 .msg_initialize = initialize,
668 .msg_uninitialize = uninitialize,
669
670 .msg_flush = flush,
671 .msg_check = check,
672
673 .msg_fetch_result_free = fetch_result_free,
674
675 .msg_fetch = fetch,
676 .msg_fetch_header = fetch_header,
677 .msg_fetch_body = fetch_body,
678 .msg_fetch_size = fetch_size,
679 .msg_get_bodystructure = get_bodystructure,
680 .msg_fetch_section = fetch_section,
681 .msg_fetch_section_header = fetch_section_header,
682 .msg_fetch_section_mime = fetch_section_mime,
683 .msg_fetch_section_body = fetch_section_body,
684 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
685
686 .msg_get_flags = NULL,
687};
688
689mailmessage_driver * mime_message_driver = &local_mime_message_driver;
diff --git a/kmicromail/libetpan/generic/mime_message_driver.h b/kmicromail/libetpan/generic/mime_message_driver.h
new file mode 100644
index 0000000..ffcdd5c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mime_message_driver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - 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#ifndef MIME_MESSAGE_DRIVER_H
37
38#define MIME_MESSAGE_DRIVER_H
39
40#include <libetpan/mailmessage.h>
41
42#define LIBETPAN_MIME_MESSAGE
43
44extern mailmessage_driver * mime_message_driver;
45
46mailmessage * mime_message_init(struct mailmime * mime);
47
48void mime_message_detach_mime(mailmessage * msg);
49
50int mime_message_set_tmpdir(mailmessage * msg, char * tmpdir);
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver.c b/kmicromail/libetpan/generic/nntpdriver.c
new file mode 100644
index 0000000..fde5f1a
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver.c
@@ -0,0 +1,1170 @@
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 "nntpdriver.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mail.h"
42#include "mailmessage.h"
43#include "nntpdriver_tools.h"
44#include "maildriver_tools.h"
45#include "nntpdriver_message.h"
46
47static int nntpdriver_initialize(mailsession * session);
48
49static void nntpdriver_uninitialize(mailsession * session);
50
51static int nntpdriver_parameters(mailsession * session,
52 int id, void * value);
53
54static int nntpdriver_connect_stream(mailsession * session, mailstream * s);
55
56static int nntpdriver_login(mailsession * session,
57 char * userid, char * password);
58
59static int nntpdriver_logout(mailsession * session);
60
61static int nntpdriver_status_folder(mailsession * session, char * mb,
62 uint32_t * result_messages,
63 uint32_t * result_recent,
64 uint32_t * result_unseen);
65
66static int nntpdriver_messages_number(mailsession * session, char * mb,
67 uint32_t * result);
68
69static int nntpdriver_append_message(mailsession * session,
70 char * message, size_t size);
71
72static int
73nntpdriver_get_envelopes_list(mailsession * session,
74 struct mailmessage_list * env_list);
75
76
77static int nntpdriver_get_messages_list(mailsession * session,
78 struct mailmessage_list ** result);
79
80static int nntpdriver_list_folders(mailsession * session, char * mb,
81 struct mail_list ** result);
82
83static int nntpdriver_lsub_folders(mailsession * session, char * mb,
84 struct mail_list ** result);
85
86static int nntpdriver_subscribe_folder(mailsession * session, char * mb);
87
88static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb);
89
90static int nntpdriver_get_message(mailsession * session,
91 uint32_t num, mailmessage ** result);
92
93static int nntpdriver_get_message_by_uid(mailsession * session,
94 const char * uid,
95 mailmessage ** result);
96
97static int nntpdriver_noop(mailsession * session);
98
99static mailsession_driver local_nntp_session_driver = {
100 .sess_name = "nntp",
101
102 .sess_initialize = nntpdriver_initialize,
103 .sess_uninitialize = nntpdriver_uninitialize,
104
105 .sess_parameters = nntpdriver_parameters,
106
107 .sess_connect_stream = nntpdriver_connect_stream,
108 .sess_connect_path = NULL,
109 .sess_starttls = NULL,
110 .sess_login = nntpdriver_login,
111 .sess_logout = nntpdriver_logout,
112 .sess_noop = nntpdriver_noop,
113
114 .sess_build_folder_name = NULL,
115 .sess_create_folder = NULL,
116 .sess_delete_folder = NULL,
117 .sess_rename_folder = NULL,
118 .sess_check_folder = NULL,
119 .sess_examine_folder = NULL,
120 .sess_select_folder = nntpdriver_select_folder,
121 .sess_expunge_folder = NULL,
122 .sess_status_folder = nntpdriver_status_folder,
123 .sess_messages_number = nntpdriver_messages_number,
124 .sess_recent_number = nntpdriver_messages_number,
125 .sess_unseen_number = nntpdriver_messages_number,
126 .sess_list_folders = nntpdriver_list_folders,
127 .sess_lsub_folders = nntpdriver_lsub_folders,
128 .sess_subscribe_folder = nntpdriver_subscribe_folder,
129 .sess_unsubscribe_folder = nntpdriver_unsubscribe_folder,
130
131 .sess_append_message = nntpdriver_append_message,
132 .sess_copy_message = NULL,
133 .sess_move_message = NULL,
134
135 .sess_get_messages_list = nntpdriver_get_messages_list,
136 .sess_get_envelopes_list = nntpdriver_get_envelopes_list,
137 .sess_remove_message = NULL,
138#if 0
139 .sess_search_messages = maildriver_generic_search_messages,
140#endif
141
142 .sess_get_message = nntpdriver_get_message,
143 .sess_get_message_by_uid = nntpdriver_get_message_by_uid,
144};
145
146
147mailsession_driver * nntp_session_driver = &local_nntp_session_driver;
148
149static inline struct nntp_session_state_data *
150get_data(mailsession * session)
151{
152 return session->sess_data;
153}
154
155static inline newsnntp * get_nntp_session(mailsession * session)
156{
157 return get_data(session)->nntp_session;
158}
159
160static int nntpdriver_initialize(mailsession * session)
161{
162 struct nntp_session_state_data * data;
163 newsnntp * nntp;
164
165 nntp = newsnntp_new(0, NULL);
166 if (nntp == NULL)
167 goto err;
168
169 data = malloc(sizeof(* data));
170 if (data == NULL)
171 goto free;
172
173 data->nntp_session = nntp;
174
175 data->nntp_userid = NULL;
176 data->nntp_password = NULL;
177
178 data->nntp_group_info = NULL;
179 data->nntp_group_name = NULL;
180
181 data->nntp_subscribed_list = clist_new();
182 if (data->nntp_subscribed_list == NULL)
183 goto free_data;
184
185 data->nntp_max_articles = 0;
186
187 data->nntp_mode_reader = FALSE;
188
189 session->sess_data = data;
190
191 return MAIL_NO_ERROR;
192
193 free_data:
194 free(data);
195 free:
196 newsnntp_free(nntp);
197 err:
198 return MAIL_ERROR_MEMORY;
199}
200
201static void nntpdriver_uninitialize(mailsession * session)
202{
203 struct nntp_session_state_data * data;
204
205 data = get_data(session);
206
207 clist_foreach(data->nntp_subscribed_list, (clist_func) free, NULL);
208 clist_free(data->nntp_subscribed_list);
209
210 if (data->nntp_group_info != NULL)
211 newsnntp_group_free(data->nntp_group_info);
212
213 if (data->nntp_group_name != NULL)
214 free(data->nntp_group_name);
215
216 if (data->nntp_userid != NULL)
217 free(data->nntp_userid);
218
219 if (data->nntp_password != NULL)
220 free(data->nntp_password);
221
222 newsnntp_free(data->nntp_session);
223 free(data);
224
225 session->sess_data = NULL;
226}
227
228
229static int nntpdriver_parameters(mailsession * session,
230 int id, void * value)
231{
232 struct nntp_session_state_data * data;
233
234 data = get_data(session);
235
236 switch (id) {
237 case NNTPDRIVER_SET_MAX_ARTICLES:
238 {
239 uint32_t * param;
240
241 param = value;
242
243 data->nntp_max_articles = * param;
244 return MAIL_NO_ERROR;
245 }
246 }
247
248 return MAIL_ERROR_INVAL;
249}
250
251
252static int add_to_list(mailsession * session, char * mb)
253{
254 char * new_mb;
255 int r;
256 struct nntp_session_state_data * data;
257
258 data = get_data(session);
259
260 new_mb = strdup(mb);
261 if (new_mb == NULL)
262 return -1;
263
264 r = clist_append(data->nntp_subscribed_list, new_mb);
265 if (r < 0) {
266 free(mb);
267 return -1;
268 }
269
270 return 0;
271}
272
273static int remove_from_list(mailsession * session, char * mb)
274{
275 clistiter * cur;
276 struct nntp_session_state_data * data;
277
278 data = get_data(session);
279
280 for(cur = clist_begin(data->nntp_subscribed_list) ; cur != NULL ;
281 cur = clist_next(cur)) {
282 char * cur_name;
283
284 cur_name = clist_content(cur);
285 if (strcmp(cur_name, mb) == 0) {
286 clist_delete(data->nntp_subscribed_list, cur);
287 free(cur_name);
288 return 0;
289 }
290 }
291
292 return -1;
293}
294
295
296static int nntpdriver_connect_stream(mailsession * session, mailstream * s)
297{
298 int r;
299
300 r = newsnntp_connect(get_nntp_session(session), s);
301
302 switch (r) {
303 case NEWSNNTP_NO_ERROR:
304 return MAIL_NO_ERROR_NON_AUTHENTICATED;
305
306 default:
307 return nntpdriver_nntp_error_to_mail_error(r);
308 }
309}
310
311static int nntpdriver_login(mailsession * session,
312 char * userid, char * password)
313{
314 struct nntp_session_state_data * data;
315 char * new_userid;
316 char * new_password;
317
318 data = get_data(session);
319
320 if (userid != NULL) {
321 new_userid = strdup(userid);
322 if (new_userid == NULL)
323 goto err;
324 }
325 else
326 new_userid = NULL;
327
328 if (password != NULL) {
329 new_password = strdup(password);
330 if (new_password == NULL)
331 goto free_uid;
332 }
333 else
334 new_password = NULL;
335
336 data->nntp_userid = new_userid;
337 data->nntp_password = new_password;
338
339 return MAIL_NO_ERROR;
340
341 free_uid:
342 if (new_userid != NULL)
343 free(new_userid);
344 err:
345 return MAIL_ERROR_MEMORY;
346}
347
348static int nntpdriver_logout(mailsession * session)
349{
350 int r;
351
352 r = newsnntp_quit(get_nntp_session(session));
353
354 return nntpdriver_nntp_error_to_mail_error(r);
355}
356
357
358static int nntpdriver_status_folder(mailsession * session, char * mb,
359 uint32_t * result_messages,
360 uint32_t * result_recent,
361 uint32_t * result_unseen)
362{
363 uint32_t count;
364 int r;
365
366 r = nntpdriver_select_folder(session, mb);
367 if (r != MAIL_NO_ERROR)
368 return r;
369
370 r = nntpdriver_messages_number(session, mb, &count);
371 if (r != MAIL_NO_ERROR)
372 return r;
373
374 * result_messages = count;
375 * result_recent = count;
376 * result_unseen = count;
377
378 return MAIL_NO_ERROR;
379}
380
381static int nntpdriver_messages_number(mailsession * session, char * mb,
382 uint32_t * result)
383{
384 int r;
385 struct nntp_session_state_data * data;
386
387 if (mb != NULL) {
388 r = nntpdriver_select_folder(session, mb);
389 if (r != MAIL_NO_ERROR)
390 return r;
391 }
392
393 data = get_data(session);
394
395 if (data->nntp_group_info == NULL)
396 return MAIL_ERROR_FOLDER_NOT_FOUND;
397
398 * result = data->nntp_group_info->grp_last -
399 data->nntp_group_info->grp_first + 1;
400
401 return MAIL_NO_ERROR;
402}
403
404static int nntpdriver_list_folders(mailsession * session, char * mb,
405 struct mail_list ** result)
406{
407 int r;
408 clist * group_list;
409 newsnntp * nntp;
410 clistiter * cur;
411 char * new_mb;
412 int done;
413 clist * list;
414 struct mail_list * ml;
415 int res;
416
417 nntp = get_nntp_session(session);
418
419 new_mb = NULL;
420 if ((mb != NULL) && (*mb != '\0')) {
421 new_mb = malloc(strlen(mb) + 3);
422 if (new_mb == NULL) {
423 res = MAIL_ERROR_MEMORY;
424 goto err;
425 }
426 strcpy(new_mb, mb);
427 strcat(new_mb, ".*");
428 }
429
430 done = FALSE;
431 do {
432 if (new_mb != NULL)
433 r = newsnntp_list_active(nntp, new_mb, &group_list);
434 else
435 r = newsnntp_list(nntp, &group_list);
436
437 switch (r) {
438 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
439 r = nntpdriver_authenticate_user(session);
440 if (r != MAIL_NO_ERROR) {
441 res = r;
442 goto err;
443 }
444 break;
445
446 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
447 r = nntpdriver_authenticate_password(session);
448 if (r != MAIL_NO_ERROR) {
449 res = r;
450 goto err;
451 }
452 break;
453
454 case NEWSNNTP_NO_ERROR:
455 if (new_mb != NULL)
456 free(new_mb);
457 done = TRUE;
458 break;
459
460 default:
461 if (new_mb != NULL)
462 free(new_mb);
463 return nntpdriver_nntp_error_to_mail_error(r);
464 }
465 }
466 while (!done);
467
468 list = clist_new();
469 if (list == NULL) {
470 res = MAIL_ERROR_MEMORY;
471 goto err;
472 }
473
474 for(cur = clist_begin(group_list) ; cur != NULL ;
475 cur = clist_next(cur)) {
476 struct newsnntp_group_info * info;
477 char * new_name;
478
479 info = clist_content(cur);
480 new_name = strdup(info->grp_name);
481 if (new_name == NULL) {
482 res = MAIL_ERROR_MEMORY;
483 goto free_list;
484 }
485
486 r = clist_append(list, new_name);
487 if (r < 0) {
488 free(new_name);
489 res = MAIL_ERROR_MEMORY;
490 goto free_list;
491 }
492 }
493
494 ml = mail_list_new(list);
495 if (ml == NULL) {
496 res = MAIL_ERROR_MEMORY;
497 goto free_list;
498 }
499
500 newsnntp_list_free(group_list);
501
502 * result = ml;
503
504 return MAIL_NO_ERROR;
505
506 free_list:
507 clist_foreach(list, (clist_func) free, NULL);
508 clist_free(list);
509 newsnntp_list_free(group_list);
510 err:
511 return res;
512}
513
514static int nntpdriver_lsub_folders(mailsession * session, char * mb,
515 struct mail_list ** result)
516{
517 clist * subscribed;
518 clist * lsub_result;
519 clistiter * cur;
520 struct mail_list * lsub;
521 size_t length;
522 int res;
523 int r;
524 struct nntp_session_state_data * data;
525
526 length = strlen(mb);
527
528 data = get_data(session);
529
530 subscribed = data->nntp_subscribed_list;
531 lsub_result = clist_new();
532 if (lsub_result == NULL) {
533 res = MAIL_ERROR_MEMORY;
534 goto err;
535 }
536
537 for(cur = clist_begin(subscribed) ; cur != NULL ;
538 cur = clist_next(cur)) {
539 char * cur_mb;
540 char * new_mb;
541
542 cur_mb = clist_content(cur);
543
544 if (strncmp(mb, cur_mb, length) == 0) {
545 new_mb = strdup(cur_mb);
546 if (new_mb == NULL) {
547 res = MAIL_ERROR_MEMORY;
548 goto free_list;
549 }
550
551 r = clist_append(lsub_result, new_mb);
552 if (r < 0) {
553 free(new_mb);
554 res = MAIL_ERROR_MEMORY;
555 goto free_list;
556 }
557 }
558 }
559
560 lsub = mail_list_new(lsub_result);
561 if (lsub == NULL) {
562 res = MAIL_ERROR_MEMORY;
563 goto free_list;
564 }
565
566 * result = lsub;
567
568 return MAIL_NO_ERROR;
569
570 free_list:
571 clist_foreach(lsub_result, (clist_func) free, NULL);
572 clist_free(lsub_result);
573 err:
574 return res;
575}
576
577static int nntpdriver_subscribe_folder(mailsession * session, char * mb)
578{
579 int r;
580
581 r = add_to_list(session, mb);
582 if (r < 0)
583 return MAIL_ERROR_SUBSCRIBE;
584
585 return MAIL_NO_ERROR;
586}
587
588static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb)
589{
590 int r;
591
592 r = remove_from_list(session, mb);
593 if (r < 0)
594 return MAIL_ERROR_UNSUBSCRIBE;
595
596 return MAIL_NO_ERROR;
597}
598
599
600
601/* messages operations */
602
603static int nntpdriver_append_message(mailsession * session,
604 char * message, size_t size)
605{
606 int r;
607 struct nntp_session_state_data * data;
608
609 data = get_data(session);
610
611 do {
612 r = newsnntp_post(get_nntp_session(session), message, size);
613 switch (r) {
614 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
615 r = nntpdriver_authenticate_user(session);
616 if (r != MAIL_NO_ERROR)
617 return r;
618 break;
619
620 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
621 r = nntpdriver_authenticate_password(session);
622 if (r != MAIL_NO_ERROR)
623 return r;
624 break;
625
626 default:
627 return nntpdriver_nntp_error_to_mail_error(r);
628 }
629 }
630 while (1);
631}
632
633
634static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item,
635 struct mailimf_fields ** result);
636
637
638static int
639nntpdriver_get_envelopes_list(mailsession * session,
640 struct mailmessage_list * env_list)
641{
642 newsnntp * nntp;
643 int r;
644 struct nntp_session_state_data * data;
645 clist * list;
646 int done;
647 clistiter * cur;
648 uint32_t first_seq;
649 unsigned int i;
650
651 nntp = get_nntp_session(session);
652
653 data = get_data(session);
654
655 if (data->nntp_group_info == NULL)
656 return MAIL_ERROR_BAD_STATE;
657
658 first_seq = data->nntp_group_info->grp_first;
659
660 if (carray_count(env_list->msg_tab) > 0) {
661 mailmessage * msg;
662
663 msg = carray_get(env_list->msg_tab, 0);
664
665 first_seq = msg->msg_index;
666 }
667
668 if (carray_count(env_list->msg_tab) > 0) {
669 i = carray_count(env_list->msg_tab) - 1;
670 while (1) {
671 mailmessage * msg;
672
673 msg = carray_get(env_list->msg_tab, i);
674
675 if (msg->msg_fields != NULL) {
676 first_seq = msg->msg_index + 1;
677 break;
678 }
679
680 if (i == 0)
681 break;
682
683 i --;
684 }
685 }
686
687 if (first_seq > data->nntp_group_info->grp_last) {
688 list = NULL;
689 }
690 else {
691 done = FALSE;
692 do {
693 r = newsnntp_xover_range(nntp, first_seq,
694 data->nntp_group_info->grp_last, &list);
695
696 switch (r) {
697 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
698 r = nntpdriver_authenticate_user(session);
699 if (r != MAIL_NO_ERROR)
700 return r;
701 break;
702
703 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
704 r = nntpdriver_authenticate_password(session);
705 if (r != MAIL_NO_ERROR)
706 return r;
707 break;
708
709 case NEWSNNTP_NO_ERROR:
710 done = TRUE;
711 break;
712
713 default:
714 return nntpdriver_nntp_error_to_mail_error(r);
715 }
716 }
717 while (!done);
718 }
719
720#if 0
721 i = 0;
722 j = 0;
723
724 if (list != NULL) {
725 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
726 struct newsnntp_xover_resp_item * item;
727 struct mailimf_fields * fields;
728
729 item = clist_content(cur);
730
731 while (i < carray_count(env_list->msg_tab)) {
732 mailmessage * info;
733
734 info = carray_get(env_list->msg_tab, i);
735
736 if (item->ovr_article == info->msg_index) {
737
738 if (info->fields == NULL) {
739 r = xover_resp_to_fields(item, &fields);
740 if (r == MAIL_NO_ERROR) {
741 info->fields = fields;
742 }
743
744 info->size = item->ovr_size;
745
746 carray_set(env_list->msg_tab, j, info);
747 j ++;
748 i ++;
749 break;
750 }
751 else {
752 carray_set(env_list->msg_tab, j, info);
753 j ++;
754 }
755 }
756 else {
757 if (info->fields != NULL) {
758 carray_set(env_list->msg_tab, j, info);
759 j ++;
760 }
761 else {
762 if (info->flags != NULL) {
763 info->flags->flags &= ~MAIL_FLAG_NEW;
764 info->flags->flags |= MAIL_FLAG_SEEN | MAIL_FLAG_DELETED;
765 mailmessage_check(info);
766 }
767 mailmessage_free(info);
768 carray_set(env_list->msg_tab, i, NULL);
769 }
770 }
771
772 i ++;
773 }
774 }
775 }
776
777 while (i < carray_count(env_list->msg_tab)) {
778 mailmessage * info;
779
780 info = carray_get(env_list->msg_tab, i);
781 if (info->fields != NULL) {
782 carray_set(env_list->msg_tab, j, info);
783 j ++;
784 }
785 else {
786 if (info->flags != NULL) {
787 info->flags->flags &= ~MAIL_FLAG_NEW;
788 info->flags->flags |= MAIL_FLAG_SEEN | MAIL_FLAG_DELETED;
789 mailmessage_check(info);
790 }
791 mailmessage_free(info);
792 carray_set(env_list->msg_tab, i, NULL);
793 }
794
795 i ++;
796 }
797
798 r = carray_set_size(env_list->msg_tab, j);
799 if (r < 0) {
800 if (list != NULL)
801 newsnntp_xover_resp_list_free(list);
802 return MAIL_ERROR_MEMORY;
803 }
804#endif
805 i = 0;
806
807 if (list != NULL) {
808 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
809 struct newsnntp_xover_resp_item * item;
810 struct mailimf_fields * fields;
811
812 item = clist_content(cur);
813
814 while (i < carray_count(env_list->msg_tab)) {
815 mailmessage * info;
816
817 info = carray_get(env_list->msg_tab, i);
818
819 if (item->ovr_article == info->msg_index) {
820
821 if (info->msg_fields == NULL) {
822 r = xover_resp_to_fields(item, &fields);
823 if (r == MAIL_NO_ERROR) {
824 info->msg_fields = fields;
825 }
826
827 info->msg_size = item->ovr_size;
828
829 i ++;
830 break;
831 }
832 }
833#if 0
834 else if ((info->fields == NULL) && (info->flags != NULL)) {
835 info->flags->flags &= ~MAIL_FLAG_NEW;
836 info->flags->flags |= MAIL_FLAG_CANCELLED;
837 mailmessage_check(info);
838 }
839#endif
840
841 i ++;
842 }
843 }
844 }
845
846#if 0
847 while (i < env_list->msg_tab->len) {
848 mailmessage * info;
849
850 info = carray_get(env_list->msg_tab, i);
851 if ((info->fields == NULL) && (info->flags != NULL)) {
852 info->flags->flags &= ~MAIL_FLAG_NEW;
853 info->flags->flags |= MAIL_FLAG_CANCELLED;
854 mailmessage_check(info);
855 }
856
857 i ++;
858 }
859#endif
860
861 if (list != NULL)
862 newsnntp_xover_resp_list_free(list);
863
864 return MAIL_NO_ERROR;
865}
866
867
868static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item,
869 struct mailimf_fields ** result)
870{
871 size_t cur_token;
872 clist * list;
873 int r;
874 struct mailimf_fields * fields;
875 int res;
876
877 list = clist_new();
878 if (list == NULL) {
879 res = MAIL_ERROR_MEMORY;
880 goto err;
881 }
882
883 if (item->ovr_subject != NULL) {
884 char * subject_str;
885 struct mailimf_subject * subject;
886 struct mailimf_field * field;
887
888 subject_str = strdup(item->ovr_subject);
889 if (subject_str == NULL) {
890 res = MAIL_ERROR_MEMORY;
891 goto free_list;
892 }
893
894 subject = mailimf_subject_new(subject_str);
895 if (subject == NULL) {
896 free(subject_str);
897 res = MAIL_ERROR_MEMORY;
898 goto free_list;
899 }
900
901 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
902 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
903 NULL, NULL, NULL,
904 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
905 NULL, subject, NULL, NULL, NULL);
906 if (field == NULL) {
907 mailimf_subject_free(subject);
908 res = MAIL_ERROR_MEMORY;
909 goto free_list;
910 }
911
912 r = clist_append(list, field);
913 if (r < 0) {
914 mailimf_field_free(field);
915 res = MAIL_ERROR_MEMORY;
916 goto free_list;
917 }
918 }
919
920 if (item->ovr_author != NULL) {
921 struct mailimf_mailbox_list * mb_list;
922 struct mailimf_from * from;
923 struct mailimf_field * field;
924
925 cur_token = 0;
926 r = mailimf_mailbox_list_parse(item->ovr_author, strlen(item->ovr_author),
927 &cur_token, &mb_list);
928 switch (r) {
929 case MAILIMF_NO_ERROR:
930 from = mailimf_from_new(mb_list);
931 if (from == NULL) {
932 mailimf_mailbox_list_free(mb_list);
933 res = MAIL_ERROR_MEMORY;
934 goto free_list;
935 }
936
937 field = mailimf_field_new(MAILIMF_FIELD_FROM,
938 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
939 NULL, NULL, from,
940 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
941 NULL, NULL, NULL, NULL, NULL);
942 if (field == NULL) {
943 mailimf_from_free(from);
944 res = MAIL_ERROR_MEMORY;
945 goto free_list;
946 }
947
948 r = clist_append(list, field);
949 if (r < 0) {
950 mailimf_field_free(field);
951 res = MAIL_ERROR_MEMORY;
952 goto free_list;
953 }
954 break;
955
956 case MAILIMF_ERROR_PARSE:
957 break;
958
959 default:
960 res = maildriver_imf_error_to_mail_error(r);
961 goto free_list;
962 }
963 }
964
965 if (item->ovr_date != NULL) {
966 struct mailimf_date_time * date_time;
967 struct mailimf_orig_date * orig_date;
968 struct mailimf_field * field;
969
970 cur_token = 0;
971 r = mailimf_date_time_parse(item->ovr_date, strlen(item->ovr_date),
972 &cur_token, &date_time);
973 switch (r) {
974 case MAILIMF_NO_ERROR:
975 orig_date = mailimf_orig_date_new(date_time);
976 if (orig_date == NULL) {
977 mailimf_date_time_free(date_time);
978 res = MAIL_ERROR_MEMORY;
979 goto free_list;
980 }
981
982 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
983 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
984 NULL, orig_date, NULL,
985 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
986 NULL, NULL, NULL, NULL, NULL);
987 if (field == NULL) {
988 mailimf_orig_date_free(orig_date);
989 res = MAIL_ERROR_MEMORY;
990 goto free_list;
991 }
992
993 r = clist_append(list, field);
994 if (r < 0) {
995 mailimf_field_free(field);
996 res = MAIL_ERROR_MEMORY;
997 goto free_list;
998 }
999 break;
1000
1001 case MAILIMF_ERROR_PARSE:
1002 break;
1003
1004 default:
1005 res = maildriver_imf_error_to_mail_error(r);
1006 goto free_list;
1007 }
1008 }
1009
1010 if (item->ovr_message_id != NULL) {
1011 char * msgid_str;
1012 struct mailimf_message_id * msgid;
1013 struct mailimf_field * field;
1014
1015 cur_token = 0;
1016 r = mailimf_msg_id_parse(item->ovr_message_id, strlen(item->ovr_message_id),
1017 &cur_token, &msgid_str);
1018
1019 switch (r) {
1020 case MAILIMF_NO_ERROR:
1021 msgid = mailimf_message_id_new(msgid_str);
1022 if (msgid == NULL) {
1023 mailimf_msg_id_free(msgid_str);
1024 res = MAIL_ERROR_MEMORY;
1025 goto free_list;
1026 }
1027
1028 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
1029 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1030 NULL, NULL, NULL,
1031 NULL, NULL, NULL, NULL, NULL, msgid, NULL,
1032 NULL, NULL, NULL, NULL, NULL);
1033
1034 r = clist_append(list, field);
1035 if (r < 0) {
1036 mailimf_field_free(field);
1037 res = MAIL_ERROR_MEMORY;
1038 goto free_list;
1039 }
1040 break;
1041
1042 case MAILIMF_ERROR_PARSE:
1043 break;
1044
1045 default:
1046 res = maildriver_imf_error_to_mail_error(r);
1047 goto free_list;
1048 }
1049 }
1050
1051 if (item->ovr_references != NULL) {
1052 clist * msgid_list;
1053 struct mailimf_references * references;
1054 struct mailimf_field * field;
1055
1056 cur_token = 0;
1057
1058 r = mailimf_msg_id_list_parse(item->ovr_references, strlen(item->ovr_references),
1059 &cur_token, &msgid_list);
1060
1061 switch (r) {
1062 case MAILIMF_NO_ERROR:
1063 references = mailimf_references_new(msgid_list);
1064 if (references == NULL) {
1065 clist_foreach(msgid_list,
1066 (clist_func) mailimf_msg_id_free, NULL);
1067 clist_free(msgid_list);
1068 res = MAIL_ERROR_MEMORY;
1069 goto free_list;
1070 }
1071
1072 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
1073 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1074 NULL, NULL, NULL,
1075 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1076 references, NULL, NULL, NULL, NULL);
1077
1078 r = clist_append(list, field);
1079 if (r < 0) {
1080 mailimf_field_free(field);
1081 res = MAIL_ERROR_MEMORY;
1082 goto free_list;
1083 }
1084
1085 case MAILIMF_ERROR_PARSE:
1086 break;
1087
1088 default:
1089 res = maildriver_imf_error_to_mail_error(r);
1090 goto free_list;
1091 }
1092 }
1093
1094 fields = mailimf_fields_new(list);
1095 if (fields == NULL) {
1096 res = MAIL_ERROR_MEMORY;
1097 goto free_list;
1098 }
1099
1100 * result = fields;
1101
1102 return MAIL_NO_ERROR;
1103
1104 free_list:
1105 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
1106 clist_free(list);
1107 err:
1108 return res;
1109}
1110
1111
1112/* get messages list with group info */
1113
1114static int nntpdriver_get_messages_list(mailsession * session,
1115 struct mailmessage_list ** result)
1116{
1117 return nntp_get_messages_list(session, session, nntp_message_driver, result);
1118
1119}
1120
1121static int nntpdriver_get_message(mailsession * session,
1122 uint32_t num, mailmessage ** result)
1123{
1124 mailmessage * msg_info;
1125 int r;
1126
1127 msg_info = mailmessage_new();
1128 if (msg_info == NULL)
1129 return MAIL_ERROR_MEMORY;
1130
1131 r = mailmessage_init(msg_info, session, nntp_message_driver, num, 0);
1132 if (r != MAIL_NO_ERROR) {
1133 mailmessage_free(msg_info);
1134 return r;
1135 }
1136
1137 * result = msg_info;
1138
1139 return MAIL_NO_ERROR;
1140}
1141
1142static int nntpdriver_noop(mailsession * session)
1143{
1144 newsnntp * nntp;
1145 int r;
1146 struct tm tm;
1147
1148 nntp = get_nntp_session(session);
1149
1150 r = newsnntp_date(nntp, &tm);
1151
1152 return nntpdriver_nntp_error_to_mail_error(r);
1153}
1154
1155static int nntpdriver_get_message_by_uid(mailsession * session,
1156 const char * uid,
1157 mailmessage ** result)
1158{
1159 uint32_t num;
1160 char * p;
1161
1162 if (uid == NULL)
1163 return MAIL_ERROR_INVAL;
1164
1165 num = strtoul(uid, &p, 10);
1166 if ((p == uid) || (* p != '\0'))
1167 return MAIL_ERROR_INVAL;
1168
1169 return nntpdriver_get_message(session, num, result);
1170 }
diff --git a/kmicromail/libetpan/generic/nntpdriver.h b/kmicromail/libetpan/generic/nntpdriver.h
new file mode 100644
index 0000000..45bfeab
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver.h
@@ -0,0 +1,52 @@
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#ifndef NNTPDRIVER_H
37
38#define NNTPDRIVER_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * nntp_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached.c b/kmicromail/libetpan/generic/nntpdriver_cached.c
new file mode 100644
index 0000000..1f8a8af
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached.c
@@ -0,0 +1,1048 @@
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 "nntpdriver_cached.h"
37
38#include "libetpan-config.h"
39
40#include <string.h>
41#include <stdio.h>
42#include <sys/types.h>
43#include <sys/stat.h>
44#include <fcntl.h>
45#include <unistd.h>
46#include <stdlib.h>
47
48#include "mail_cache_db.h"
49
50#include "mail.h"
51#include "mailmessage.h"
52#include "maildriver_tools.h"
53#include "nntpdriver.h"
54#include "maildriver.h"
55#include "newsnntp.h"
56#include "generic_cache.h"
57#include "imfcache.h"
58#include "maillock.h"
59#include "nntpdriver_cached_message.h"
60#include "nntpdriver_tools.h"
61
62static int nntpdriver_cached_initialize(mailsession * session);
63
64static void nntpdriver_cached_uninitialize(mailsession * session);
65
66static int nntpdriver_cached_parameters(mailsession * session,
67 int id, void * value);
68
69static int nntpdriver_cached_connect_stream(mailsession * session,
70 mailstream * s);
71
72static int nntpdriver_cached_login(mailsession * session,
73 char * userid, char * password);
74
75static int nntpdriver_cached_logout(mailsession * session);
76
77static int nntpdriver_cached_check_folder(mailsession * session);
78
79static int nntpdriver_cached_select_folder(mailsession * session, char * mb);
80
81static int nntpdriver_cached_status_folder(mailsession * session,
82 char * mb,
83 uint32_t * result_messages,
84 uint32_t * result_recent,
85 uint32_t * result_unseen);
86
87static int nntpdriver_cached_messages_number(mailsession * session, char * mb,
88 uint32_t * result);
89
90static int nntpdriver_cached_recent_number(mailsession * session, char * mb,
91 uint32_t * result);
92
93static int nntpdriver_cached_unseen_number(mailsession * session, char * mb,
94 uint32_t * result);
95
96static int nntpdriver_cached_append_message(mailsession * session,
97 char * message, size_t size);
98
99static int
100nntpdriver_cached_get_envelopes_list(mailsession * session,
101 struct mailmessage_list * env_list);
102
103
104static int
105nntpdriver_cached_get_messages_list(mailsession * session,
106 struct mailmessage_list ** result);
107
108static int nntpdriver_cached_list_folders(mailsession * session, char * mb,
109 struct mail_list ** result);
110
111static int nntpdriver_cached_lsub_folders(mailsession * session, char * mb,
112 struct mail_list ** result);
113
114static int nntpdriver_cached_subscribe_folder(mailsession * session,
115 char * mb);
116
117static int nntpdriver_cached_unsubscribe_folder(mailsession * session,
118 char * mb);
119
120static int nntpdriver_cached_get_message(mailsession * session,
121 uint32_t num, mailmessage ** result);
122
123static int nntpdriver_cached_noop(mailsession * session);
124
125static int nntpdriver_cached_get_message_by_uid(mailsession * session,
126 const char * uid,
127 mailmessage ** result);
128
129static mailsession_driver local_nntp_cached_session_driver = {
130 .sess_name = "nntp-cached",
131
132 .sess_initialize = nntpdriver_cached_initialize,
133 .sess_uninitialize = nntpdriver_cached_uninitialize,
134
135 .sess_parameters = nntpdriver_cached_parameters,
136
137 .sess_connect_stream = nntpdriver_cached_connect_stream,
138 .sess_connect_path = NULL,
139 .sess_starttls = NULL,
140 .sess_login = nntpdriver_cached_login,
141 .sess_logout = nntpdriver_cached_logout,
142 .sess_noop = nntpdriver_cached_noop,
143
144 .sess_build_folder_name = NULL,
145 .sess_create_folder = NULL,
146 .sess_delete_folder = NULL,
147 .sess_rename_folder = NULL,
148 .sess_check_folder = nntpdriver_cached_check_folder,
149 .sess_examine_folder = NULL,
150 .sess_select_folder = nntpdriver_cached_select_folder,
151 .sess_expunge_folder = NULL,
152 .sess_status_folder = nntpdriver_cached_status_folder,
153 .sess_messages_number = nntpdriver_cached_messages_number,
154 .sess_recent_number = nntpdriver_cached_recent_number,
155 .sess_unseen_number = nntpdriver_cached_unseen_number,
156 .sess_list_folders = nntpdriver_cached_list_folders,
157 .sess_lsub_folders = nntpdriver_cached_lsub_folders,
158 .sess_subscribe_folder = nntpdriver_cached_subscribe_folder,
159 .sess_unsubscribe_folder = nntpdriver_cached_unsubscribe_folder,
160
161 .sess_append_message = nntpdriver_cached_append_message,
162 .sess_copy_message = NULL,
163 .sess_move_message = NULL,
164
165 .sess_get_messages_list = nntpdriver_cached_get_messages_list,
166 .sess_get_envelopes_list = nntpdriver_cached_get_envelopes_list,
167 .sess_remove_message = NULL,
168#if 0
169 .sess_search_messages = maildriver_generic_search_messages,
170#endif
171
172 .sess_get_message = nntpdriver_cached_get_message,
173 .sess_get_message_by_uid = nntpdriver_cached_get_message_by_uid,
174};
175
176
177mailsession_driver * nntp_cached_session_driver =
178&local_nntp_cached_session_driver;
179
180#define ENV_NAME "env.db"
181#define FLAGS_NAME "flags.db"
182
183
184
185static void read_article_seq(mailsession * session,
186 uint32_t * pfirst, uint32_t * plast);
187
188static void write_article_seq(mailsession * session,
189 uint32_t first, uint32_t last);
190
191
192static inline struct nntp_cached_session_state_data *
193get_cached_data(mailsession * session)
194{
195 return session->sess_data;
196}
197
198static inline mailsession * get_ancestor(mailsession * session)
199{
200 return get_cached_data(session)->nntp_ancestor;
201}
202
203static inline struct nntp_session_state_data *
204get_ancestor_data(mailsession * session)
205{
206 return get_ancestor(session)->sess_data;
207}
208
209static inline newsnntp * get_nntp_session(mailsession * session)
210{
211 return get_ancestor_data(session)->nntp_session;
212}
213
214static int nntpdriver_cached_initialize(mailsession * session)
215{
216 struct nntp_cached_session_state_data * data;
217
218 data = malloc(sizeof(* data));
219 if (data == NULL)
220 goto err;
221
222 data->nntp_flags_store = mail_flags_store_new();
223 if (data->nntp_flags_store == NULL)
224 goto free;
225
226 data->nntp_ancestor = mailsession_new(nntp_session_driver);
227 if (data->nntp_ancestor == NULL)
228 goto free_store;
229
230 session->sess_data = data;
231
232 return MAIL_NO_ERROR;
233
234 free_store:
235 mail_flags_store_free(data->nntp_flags_store);
236 free:
237 free(data);
238 err:
239 return MAIL_ERROR_MEMORY;
240}
241
242static int nntp_flags_store_process(char * flags_directory, char * group_name,
243 struct mail_flags_store * flags_store)
244{
245 char filename_flags[PATH_MAX];
246 struct mail_cache_db * cache_db_flags;
247 MMAPString * mmapstr;
248 unsigned int i;
249 int r;
250 int res;
251
252 if (carray_count(flags_store->fls_tab) == 0)
253 return MAIL_NO_ERROR;
254
255 if (group_name == NULL)
256 return MAIL_NO_ERROR;
257
258 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
259 flags_directory, group_name, FLAGS_NAME);
260
261 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
262 if (r < 0) {
263 res = MAIL_ERROR_FILE;
264 goto err;
265 }
266
267 mmapstr = mmap_string_new("");
268 if (mmapstr == NULL) {
269 res = MAIL_ERROR_MEMORY;
270 goto close_db_flags;
271 }
272
273 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
274 mailmessage * msg;
275
276 msg = carray_get(flags_store->fls_tab, i);
277
278 r = nntpdriver_write_cached_flags(cache_db_flags, mmapstr,
279 msg->msg_index, msg->msg_flags);
280 }
281
282 mmap_string_free(mmapstr);
283 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
284
285 mail_flags_store_clear(flags_store);
286
287 return MAIL_NO_ERROR;
288
289 close_db_flags:
290 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
291 err:
292 return res;
293}
294
295static void nntpdriver_cached_uninitialize(mailsession * session)
296{
297 struct nntp_cached_session_state_data * cached_data;
298 struct nntp_session_state_data * ancestor_data;
299
300 cached_data = get_cached_data(session);
301 ancestor_data = get_ancestor_data(session);
302
303 nntp_flags_store_process(cached_data->nntp_flags_directory,
304 ancestor_data->nntp_group_name,
305 cached_data->nntp_flags_store);
306
307 mail_flags_store_free(cached_data->nntp_flags_store);
308
309 mailsession_free(cached_data->nntp_ancestor);
310 free(cached_data);
311
312 session->sess_data = NULL;
313}
314
315static int nntpdriver_cached_parameters(mailsession * session,
316 int id, void * value)
317{
318 struct nntp_cached_session_state_data * cached_data;
319 int r;
320
321 cached_data = get_cached_data(session);
322
323 switch (id) {
324 case NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY:
325 strncpy(cached_data->nntp_cache_directory, value, PATH_MAX);
326 cached_data->nntp_cache_directory[PATH_MAX - 1] = '\0';
327
328 r = generic_cache_create_dir(cached_data->nntp_cache_directory);
329 if (r != MAIL_NO_ERROR)
330 return r;
331
332 return MAIL_NO_ERROR;
333
334 case NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY:
335 strncpy(cached_data->nntp_flags_directory, value, PATH_MAX);
336 cached_data->nntp_flags_directory[PATH_MAX - 1] = '\0';
337
338 r = generic_cache_create_dir(cached_data->nntp_flags_directory);
339 if (r != MAIL_NO_ERROR)
340 return r;
341
342 return MAIL_NO_ERROR;
343
344 default:
345 return mailsession_parameters(get_ancestor(session), id, value);
346 }
347}
348
349static int nntpdriver_cached_connect_stream(mailsession * session,
350 mailstream * s)
351{
352 return mailsession_connect_stream(get_ancestor(session), s);
353}
354
355static int nntpdriver_cached_login(mailsession * session,
356 char * userid, char * password)
357{
358 return mailsession_login(get_ancestor(session), userid, password);
359}
360
361static int nntpdriver_cached_logout(mailsession * session)
362{
363 struct nntp_cached_session_state_data * cached_data;
364 struct nntp_session_state_data * ancestor_data;
365
366 cached_data = get_cached_data(session);
367 ancestor_data = get_ancestor_data(session);
368
369 nntp_flags_store_process(cached_data->nntp_flags_directory,
370 ancestor_data->nntp_group_name,
371 cached_data->nntp_flags_store);
372
373 return mailsession_logout(get_ancestor(session));
374}
375
376static int nntpdriver_cached_select_folder(mailsession * session, char * mb)
377{
378 int r;
379 struct nntp_session_state_data * ancestor_data;
380 struct nntp_cached_session_state_data * cached_data;
381 int res;
382 char key[PATH_MAX];
383
384 cached_data = get_cached_data(session);
385 ancestor_data = get_ancestor_data(session);
386
387 nntp_flags_store_process(cached_data->nntp_flags_directory,
388 ancestor_data->nntp_group_name,
389 cached_data->nntp_flags_store);
390
391 r = mailsession_select_folder(get_ancestor(session), mb);
392 if (r != MAIL_NO_ERROR)
393 return r;
394
395 if (ancestor_data->nntp_group_name == NULL)
396 return MAIL_ERROR_BAD_STATE;
397
398 snprintf(key, PATH_MAX, "%s/%s", cached_data->nntp_cache_directory,
399 ancestor_data->nntp_group_name);
400
401 r = generic_cache_create_dir(key);
402 if (r != MAIL_NO_ERROR) {
403 res = r;
404 goto err;
405 }
406
407 snprintf(key, PATH_MAX, "%s/%s", cached_data->nntp_flags_directory,
408 ancestor_data->nntp_group_name);
409
410 r = generic_cache_create_dir(key);
411 if (r != MAIL_NO_ERROR) {
412 res = r;
413 goto err;
414 }
415
416 return MAIL_NO_ERROR;
417
418 err:
419 return res;
420}
421
422static int nntpdriver_cached_check_folder(mailsession * session)
423{
424 struct nntp_session_state_data * ancestor_data;
425 struct nntp_cached_session_state_data * cached_data;
426
427 cached_data = get_cached_data(session);
428 ancestor_data = get_ancestor_data(session);
429
430 nntp_flags_store_process(cached_data->nntp_flags_directory,
431 ancestor_data->nntp_group_name,
432 cached_data->nntp_flags_store);
433
434 return MAIL_NO_ERROR;
435}
436
437
438static int nntpdriver_cached_status_folder(mailsession * session,
439 char * mb, uint32_t * result_messages, uint32_t * result_recent,
440 uint32_t * result_unseen)
441{
442 int res;
443 struct nntp_cached_session_state_data * cached_data;
444 struct nntp_session_state_data * ancestor_data;
445 char filename_flags[PATH_MAX];
446 struct mail_cache_db * cache_db_flags;
447 MMAPString * mmapstr;
448 uint32_t i;
449 int r;
450 uint32_t recent;
451 uint32_t unseen;
452 uint32_t first;
453 uint32_t last;
454 uint32_t count;
455 uint32_t additionnal;
456
457 r = nntpdriver_cached_select_folder(session, mb);
458 if (r != MAIL_NO_ERROR) {
459 res = r;
460 goto err;
461 }
462
463 read_article_seq(session, &first, &last);
464
465 count = 0;
466 recent = 0;
467 unseen = 0;
468
469 ancestor_data = get_ancestor_data(session);
470 cached_data = get_cached_data(session);
471 if (ancestor_data->nntp_group_name == NULL) {
472 res = MAIL_ERROR_BAD_STATE;
473 goto err;
474 }
475
476 if (ancestor_data->nntp_group_info->grp_first > first)
477 first = ancestor_data->nntp_group_info->grp_first;
478 if (last < first)
479 last = ancestor_data->nntp_group_info->grp_last;
480
481 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
482 cached_data->nntp_flags_directory,
483 ancestor_data->nntp_group_name, FLAGS_NAME);
484
485 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
486 if (r < 0) {
487 res = MAIL_ERROR_MEMORY;
488 goto err;
489 }
490
491 mmapstr = mmap_string_new("");
492 if (mmapstr == NULL) {
493 res = MAIL_ERROR_MEMORY;
494 goto close_db_flags;
495 }
496
497 for(i = first ; i <= last ; i++) {
498 struct mail_flags * flags;
499
500 r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
501 i, &flags);
502 if (r == MAIL_NO_ERROR) {
503 if ((flags->fl_flags & MAIL_FLAG_CANCELLED) != 0) {
504 continue;
505 }
506
507 count ++;
508 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
509 recent ++;
510 }
511 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
512 unseen ++;
513 }
514 mail_flags_free(flags);
515 }
516 }
517
518 if ((count == 0) && (first != last)) {
519 count = last - first + 1;
520 recent = count;
521 unseen = count;
522 }
523
524 additionnal = ancestor_data->nntp_group_info->grp_last - last;
525 recent += additionnal;
526 unseen += additionnal;
527
528 mmap_string_free(mmapstr);
529 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
530
531 * result_messages = count;
532 * result_recent = recent;
533 * result_unseen = unseen;
534
535 return MAIL_NO_ERROR;
536
537 close_db_flags:
538 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
539 err:
540 return res;
541}
542
543static int nntpdriver_cached_messages_number(mailsession * session,
544 char * mb,
545 uint32_t * result)
546{
547 uint32_t messages;
548 uint32_t recent;
549 uint32_t unseen;
550 int r;
551
552 r = nntpdriver_cached_status_folder(session, mb,
553 &messages, &recent, &unseen);
554 if (r != MAIL_NO_ERROR)
555 return r;
556
557 * result = messages;
558
559 return MAIL_NO_ERROR;
560}
561
562static int nntpdriver_cached_recent_number(mailsession * session,
563 char * mb,
564 uint32_t * result)
565{
566 uint32_t messages;
567 uint32_t recent;
568 uint32_t unseen;
569 int r;
570
571 r = nntpdriver_cached_status_folder(session, mb,
572 &messages, &recent, &unseen);
573 if (r != MAIL_NO_ERROR)
574 return r;
575
576 * result = recent;
577
578 return MAIL_NO_ERROR;
579}
580
581static int nntpdriver_cached_unseen_number(mailsession * session,
582 char * mb,
583 uint32_t * result)
584{
585 uint32_t messages;
586 uint32_t recent;
587 uint32_t unseen;
588 int r;
589
590 r = nntpdriver_cached_status_folder(session, mb,
591 &messages, &recent, &unseen);
592 if (r != MAIL_NO_ERROR)
593 return r;
594
595 * result = unseen;
596
597 return MAIL_NO_ERROR;
598}
599
600static int nntpdriver_cached_list_folders(mailsession * session, char * mb,
601 struct mail_list ** result)
602{
603 return mailsession_list_folders(get_ancestor(session), mb, result);
604}
605
606static int nntpdriver_cached_lsub_folders(mailsession * session, char * mb,
607 struct mail_list ** result)
608{
609 return mailsession_lsub_folders(get_ancestor(session), mb, result);
610}
611
612static int nntpdriver_cached_subscribe_folder(mailsession * session,
613 char * mb)
614{
615 return mailsession_subscribe_folder(get_ancestor(session), mb);
616}
617
618static int nntpdriver_cached_unsubscribe_folder(mailsession * session,
619 char * mb)
620{
621 return mailsession_unsubscribe_folder(get_ancestor(session), mb);
622}
623
624
625
626/* messages operations */
627
628static int nntpdriver_cached_append_message(mailsession * session,
629 char * message, size_t size)
630{
631 return mailsession_append_message(get_ancestor(session), message, size);
632}
633
634
635
636static int
637get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
638 mailsession * session, uint32_t num,
639 struct mailimf_fields ** result)
640{
641 char keyname[PATH_MAX];
642 int r;
643 struct mailimf_fields * fields;
644 int res;
645
646 snprintf(keyname, PATH_MAX, "%i-envelope", num);
647
648 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
649 if (r != MAIL_NO_ERROR) {
650 res = r;
651 goto err;
652 }
653
654 * result = fields;
655
656 return MAIL_NO_ERROR;
657
658 err:
659 return res;
660}
661
662static int
663write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
664 mailsession * session, uint32_t num,
665 struct mailimf_fields * fields)
666{
667 int r;
668 int res;
669 char keyname[PATH_MAX];
670
671 snprintf(keyname, PATH_MAX, "%i-envelope", num);
672
673 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
674 if (r != MAIL_NO_ERROR) {
675 res = r;
676 goto err;
677 }
678
679 return MAIL_NO_ERROR;
680
681 err:
682 return res;
683}
684
685#define SEQ_FILENAME "articles-seq"
686
687static void read_article_seq(mailsession * session,
688 uint32_t * pfirst, uint32_t * plast)
689{
690 FILE * f;
691 struct nntp_session_state_data * ancestor_data;
692 uint32_t first;
693 uint32_t last;
694 char seq_filename[PATH_MAX];
695 struct nntp_cached_session_state_data * cached_data;
696 int r;
697
698 first = 0;
699 last = 0;
700
701 cached_data = get_cached_data(session);
702 ancestor_data = get_ancestor_data(session);
703
704 if (ancestor_data->nntp_group_name == NULL)
705 return;
706
707 snprintf(seq_filename, PATH_MAX, "%s/%s/%s",
708 cached_data->nntp_cache_directory,
709 ancestor_data->nntp_group_name, SEQ_FILENAME);
710 f = fopen(seq_filename, "r");
711
712 if (f != NULL) {
713 int fd;
714
715 fd = fileno(f);
716
717 r = maillock_read_lock(seq_filename, fd);
718 if (r == 0) {
719 MMAPString * mmapstr;
720 size_t cur_token;
721 char buf[sizeof(uint32_t) * 2];
722 size_t read_size;
723
724 read_size = fread(buf, 1, sizeof(uint32_t) * 2, f);
725 mmapstr = mmap_string_new_len(buf, read_size);
726 if (mmapstr != NULL) {
727 cur_token = 0;
728 r = mailimf_cache_int_read(mmapstr, &cur_token, &first);
729 r = mailimf_cache_int_read(mmapstr, &cur_token, &last);
730
731 mmap_string_free(mmapstr);
732 }
733
734 maillock_read_unlock(seq_filename, fd);
735 }
736 fclose(f);
737 }
738
739 * pfirst = first;
740 * plast = last;
741}
742
743static void write_article_seq(mailsession * session,
744 uint32_t first, uint32_t last)
745{
746 FILE * f;
747 struct nntp_session_state_data * ancestor_data;
748 char seq_filename[PATH_MAX];
749 struct nntp_cached_session_state_data * cached_data;
750 int r;
751 int fd;
752
753 cached_data = get_cached_data(session);
754 ancestor_data = get_ancestor_data(session);
755
756 if (ancestor_data->nntp_group_name == NULL)
757 return;
758
759 snprintf(seq_filename, PATH_MAX, "%s/%s/%s",
760 cached_data->nntp_cache_directory,
761 ancestor_data->nntp_group_name, SEQ_FILENAME);
762
763 fd = creat(seq_filename, S_IRUSR | S_IWUSR);
764 if (fd < 0)
765 return;
766
767 f = fdopen(fd, "w");
768 if (f != NULL) {
769 r = maillock_write_lock(seq_filename, fd);
770 if (r == 0) {
771 MMAPString * mmapstr;
772 size_t cur_token;
773
774 mmapstr = mmap_string_new("");
775 if (mmapstr != NULL) {
776 r = mail_serialize_clear(mmapstr, &cur_token);
777 if (r == MAIL_NO_ERROR) {
778 r = mailimf_cache_int_write(mmapstr, &cur_token, first);
779 r = mailimf_cache_int_write(mmapstr, &cur_token, last);
780
781 fwrite(mmapstr->str, 1, mmapstr->len, f);
782 }
783
784 mmap_string_free(mmapstr);
785 }
786
787 maillock_write_unlock(seq_filename, fd);
788 }
789 fclose(f);
790 }
791 else
792 close(fd);
793}
794
795
796static void get_uid_from_filename(char * filename)
797{
798 char * p;
799
800 if (strcmp(filename, SEQ_FILENAME) == 0)
801 * filename = 0;
802
803 p = strstr(filename, "-header");
804 if (p != NULL)
805 * p = 0;
806}
807
808static int
809nntpdriver_cached_get_envelopes_list(mailsession * session,
810 struct mailmessage_list * env_list)
811{
812 int r;
813 unsigned int i;
814 struct nntp_cached_session_state_data * cached_data;
815 uint32_t first;
816 uint32_t last;
817 struct nntp_session_state_data * ancestor_data;
818 char filename_env[PATH_MAX];
819 char filename_flags[PATH_MAX];
820 struct mail_cache_db * cache_db_env;
821 struct mail_cache_db * cache_db_flags;
822 MMAPString * mmapstr;
823 int res;
824 char cache_dir[PATH_MAX];
825
826 cached_data = get_cached_data(session);
827 ancestor_data = get_ancestor_data(session);
828
829 nntp_flags_store_process(cached_data->nntp_flags_directory,
830 ancestor_data->nntp_group_name,
831 cached_data->nntp_flags_store);
832
833 if (ancestor_data->nntp_group_name == NULL) {
834 res = MAIL_ERROR_BAD_STATE;
835 goto err;
836 }
837
838 /* read articles sequence */
839
840 read_article_seq(session, &first, &last);
841
842 mmapstr = mmap_string_new("");
843 if (mmapstr == NULL) {
844 res = MAIL_ERROR_MEMORY;
845 goto err;
846 }
847
848 snprintf(filename_env, PATH_MAX, "%s/%s/%s",
849 cached_data->nntp_cache_directory,
850 ancestor_data->nntp_group_name, ENV_NAME);
851
852 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
853 if (r < 0) {
854 res = MAIL_ERROR_MEMORY;
855 goto free_mmapstr;
856 }
857
858 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
859 cached_data->nntp_flags_directory,
860 ancestor_data->nntp_group_name, FLAGS_NAME);
861
862 /* fill with cached */
863
864 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
865 mailmessage * msg;
866 struct mailimf_fields * fields;
867
868 msg = carray_get(env_list->msg_tab, i);
869
870 if ((msg->msg_index < first) || (msg->msg_index > last))
871 continue;
872
873 if (msg->msg_fields == NULL) {
874 r = get_cached_envelope(cache_db_env, mmapstr,
875 session, msg->msg_index, &fields);
876 if (r == MAIL_NO_ERROR) {
877 msg->msg_fields = fields;
878 msg->msg_cached = TRUE;
879 }
880 }
881 }
882
883 mail_cache_db_close_unlock(filename_env, cache_db_env);
884
885 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
886
887 if (r != MAIL_NO_ERROR) {
888 res = r;
889 goto free_mmapstr;
890 }
891
892 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
893 if (r < 0) {
894 res = MAIL_ERROR_MEMORY;
895 goto free_mmapstr;
896 }
897
898 /* add flags */
899
900 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
901 mailmessage * msg;
902
903 msg = carray_get(env_list->msg_tab, i);
904
905 if (msg->msg_flags == NULL) {
906 struct mail_flags * flags;
907
908 r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
909 msg->msg_index, &flags);
910 if (r == MAIL_NO_ERROR) {
911 msg->msg_flags = flags;
912 }
913 else {
914 msg->msg_flags = mail_flags_new_empty();
915 if (msg->msg_fields == NULL) {
916 msg->msg_flags->fl_flags |= MAIL_FLAG_CANCELLED;
917 mailmessage_check(msg);
918 }
919 }
920 }
921 }
922
923 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
924
925 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
926 if (r < 0) {
927 res = MAIL_ERROR_MEMORY;
928 goto free_mmapstr;
929 }
930
931 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
932 if (r < 0) {
933 res = MAIL_ERROR_MEMORY;
934 goto close_db_env;
935 }
936
937 /* must write cache */
938
939 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
940 mailmessage * msg;
941
942 msg = carray_get(env_list->msg_tab, i);
943
944 if (msg->msg_fields != NULL) {
945 if (!msg->msg_cached) {
946 r = write_cached_envelope(cache_db_env, mmapstr,
947 session, msg->msg_index, msg->msg_fields);
948 }
949 }
950
951 if (msg->msg_flags != NULL) {
952 r = nntpdriver_write_cached_flags(cache_db_flags, mmapstr,
953 msg->msg_index, msg->msg_flags);
954 }
955 }
956
957 first = 0;
958 last = 0;
959 if (carray_count(env_list->msg_tab) > 0) {
960 mailmessage * msg;
961
962 msg = carray_get(env_list->msg_tab, 0);
963 first = msg->msg_index;
964
965 msg = carray_get(env_list->msg_tab, carray_count(env_list->msg_tab) - 1);
966 last = msg->msg_index;
967 }
968
969 /* write articles sequence */
970
971 write_article_seq(session, first, last);
972
973 /* flush cache */
974
975 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
976
977 /* remove cache files */
978
979 snprintf(cache_dir, PATH_MAX, "%s/%s",
980 cached_data->nntp_cache_directory, ancestor_data->nntp_group_name);
981
982 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
983 mail_cache_db_close_unlock(filename_env, cache_db_env);
984 mmap_string_free(mmapstr);
985
986 maildriver_message_cache_clean_up(cache_dir, env_list,
987 get_uid_from_filename);
988
989 return MAIL_NO_ERROR;
990
991 close_db_env:
992 mail_cache_db_close_unlock(filename_env, cache_db_env);
993 free_mmapstr:
994 mmap_string_free(mmapstr);
995 err:
996 return res;
997}
998
999static int
1000nntpdriver_cached_get_messages_list(mailsession * session,
1001 struct mailmessage_list ** result)
1002{
1003 return nntp_get_messages_list(get_ancestor(session), session,
1004 nntp_cached_message_driver, result);
1005}
1006
1007static int nntpdriver_cached_get_message(mailsession * session,
1008 uint32_t num, mailmessage ** result)
1009{
1010 mailmessage * msg_info;
1011 int r;
1012
1013 msg_info = mailmessage_new();
1014 if (msg_info == NULL)
1015 return MAIL_ERROR_MEMORY;
1016
1017 r = mailmessage_init(msg_info, session, nntp_cached_message_driver, num, 0);
1018 if (r != MAIL_NO_ERROR) {
1019 mailmessage_free(msg_info);
1020 return r;
1021 }
1022
1023 * result = msg_info;
1024
1025 return MAIL_NO_ERROR;
1026}
1027
1028static int nntpdriver_cached_noop(mailsession * session)
1029{
1030 return mailsession_noop(get_ancestor(session));
1031}
1032
1033static int nntpdriver_cached_get_message_by_uid(mailsession * session,
1034 const char * uid,
1035 mailmessage ** result)
1036{
1037 uint32_t num;
1038 char * p;
1039
1040 if (uid == NULL)
1041 return MAIL_ERROR_INVAL;
1042
1043 num = strtoul(uid, &p, 10);
1044 if ((p == uid) || (* p != '\0'))
1045 return MAIL_ERROR_INVAL;
1046
1047 return nntpdriver_cached_get_message(session, num, result);
1048}
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached.h b/kmicromail/libetpan/generic/nntpdriver_cached.h
new file mode 100644
index 0000000..feb576b
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached.h
@@ -0,0 +1,52 @@
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#ifndef NNTPDRIVER_CACHED_H
37
38#define NNTPDRIVER_CACHED_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * nntp_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached_message.c b/kmicromail/libetpan/generic/nntpdriver_cached_message.c
new file mode 100644
index 0000000..a2bb6f7
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached_message.c
@@ -0,0 +1,365 @@
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 "nntpdriver_cached_message.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mail_cache_db.h"
42
43#include "mailmessage.h"
44#include "mailmessage_tools.h"
45#include "nntpdriver.h"
46#include "nntpdriver_tools.h"
47#include "nntpdriver_cached.h"
48#include "nntpdriver_message.h"
49#include "generic_cache.h"
50
51static int nntp_prefetch(mailmessage * msg_info);
52
53static void nntp_prefetch_free(struct generic_message_t * msg);
54
55static int nntp_initialize(mailmessage * msg_info);
56
57static int nntp_fetch_header(mailmessage * msg_info,
58 char ** result,
59 size_t * result_len);
60
61static int nntp_fetch_size(mailmessage * msg_info,
62 size_t * result);
63
64static void nntp_uninitialize(mailmessage * msg_info);
65
66static void nntp_flush(mailmessage * msg_info);
67
68static void nntp_check(mailmessage * msg_info);
69
70static int nntp_get_flags(mailmessage * msg_info,
71 struct mail_flags ** result);
72
73static mailmessage_driver local_nntp_cached_message_driver = {
74 .msg_name = "nntp-cached",
75
76 .msg_initialize = nntp_initialize,
77 .msg_uninitialize = nntp_uninitialize,
78
79 .msg_flush = nntp_flush,
80 .msg_check = nntp_check,
81
82 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
83
84 .msg_fetch = mailmessage_generic_fetch,
85 .msg_fetch_header = nntp_fetch_header,
86 .msg_fetch_body = mailmessage_generic_fetch_body,
87 .msg_fetch_size = nntp_fetch_size,
88 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
89 .msg_fetch_section = mailmessage_generic_fetch_section,
90 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
91 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
92 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
93 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
94
95 .msg_get_flags = nntp_get_flags,
96};
97
98mailmessage_driver * nntp_cached_message_driver =
99&local_nntp_cached_message_driver;
100
101static inline struct nntp_cached_session_state_data *
102get_cached_session_data(mailmessage * msg)
103{
104 return msg->msg_session->sess_data;
105}
106
107static inline mailsession * get_ancestor_session(mailmessage * msg)
108{
109 return get_cached_session_data(msg)->nntp_ancestor;
110}
111
112static inline struct nntp_session_state_data *
113get_ancestor_session_data(mailmessage * msg)
114{
115 return get_ancestor_session(msg)->sess_data;
116}
117
118static inline newsnntp *
119get_nntp_session(mailmessage * msg)
120{
121 return get_ancestor_session_data(msg)->nntp_session;
122}
123
124static int nntp_prefetch(mailmessage * msg_info)
125{
126 char * msg_content;
127 size_t msg_length;
128 struct generic_message_t * msg;
129 int r;
130 struct nntp_cached_session_state_data * cached_data;
131 struct nntp_session_state_data * ancestor_data;
132 char filename[PATH_MAX];
133
134 /* we try the cached message */
135
136 cached_data = get_cached_session_data(msg_info);
137
138 ancestor_data = get_ancestor_session_data(msg_info);
139
140 snprintf(filename, PATH_MAX, "%s/%s/%i", cached_data->nntp_cache_directory,
141 ancestor_data->nntp_group_name, msg_info->msg_index);
142
143 r = generic_cache_read(filename, &msg_content, &msg_length);
144 if (r == MAIL_NO_ERROR) {
145 msg = msg_info->msg_data;
146
147 msg->msg_message = msg_content;
148 msg->msg_length = msg_length;
149
150 return MAIL_NO_ERROR;
151 }
152
153 /* we get the message through the network */
154
155 r = nntpdriver_article(get_ancestor_session(msg_info),
156 msg_info->msg_index, &msg_content,
157 &msg_length);
158
159 if (r != MAIL_NO_ERROR)
160 return r;
161
162 /* we write the message cache */
163
164 generic_cache_store(filename, msg_content, msg_length);
165
166 msg = msg_info->msg_data;
167
168 msg->msg_message = msg_content;
169 msg->msg_length = msg_length;
170
171 return MAIL_NO_ERROR;
172}
173
174static void nntp_prefetch_free(struct generic_message_t * msg)
175{
176 if (msg->msg_message != NULL) {
177 mmap_string_unref(msg->msg_message);
178 msg->msg_message = NULL;
179 }
180}
181
182static int nntp_initialize(mailmessage * msg_info)
183{
184 struct generic_message_t * msg;
185 int r;
186 char * uid;
187 char static_uid[20];
188
189 snprintf(static_uid, 20, "%u", msg_info->msg_index);
190 uid = strdup(static_uid);
191 if (uid == NULL)
192 return MAIL_ERROR_MEMORY;
193
194 r = mailmessage_generic_initialize(msg_info);
195 if (r != MAIL_NO_ERROR) {
196 free(uid);
197 return r;
198 }
199
200 msg = msg_info->msg_data;
201 msg->msg_prefetch = nntp_prefetch;
202 msg->msg_prefetch_free = nntp_prefetch_free;
203 msg_info->msg_uid = uid;
204
205 return MAIL_NO_ERROR;
206}
207
208
209static void nntp_uninitialize(mailmessage * msg_info)
210{
211 mailmessage_generic_uninitialize(msg_info);
212}
213
214#define FLAGS_NAME "flags.db"
215
216static void nntp_flush(mailmessage * msg_info)
217{
218 mailmessage_generic_flush(msg_info);
219}
220
221
222static void nntp_check(mailmessage * msg_info)
223{
224 int r;
225
226 if (msg_info->msg_flags != NULL) {
227 r = mail_flags_store_set(get_cached_session_data(msg_info)->nntp_flags_store,
228 msg_info);
229 /* ignore errors */
230 }
231}
232
233static int nntp_fetch_header(mailmessage * msg_info,
234 char ** result,
235 size_t * result_len)
236{
237 struct generic_message_t * msg;
238 char * headers;
239 size_t headers_length;
240 struct nntp_cached_session_state_data * cached_data;
241 struct nntp_session_state_data * ancestor_data;
242 int r;
243 char filename[PATH_MAX];
244
245 msg = msg_info->msg_data;
246
247 if (msg->msg_message != NULL)
248 return mailmessage_generic_fetch_header(msg_info,
249 result, result_len);
250
251 /* we try the cached message */
252
253 cached_data = get_cached_session_data(msg_info);
254
255 ancestor_data = get_ancestor_session_data(msg_info);
256
257 snprintf(filename, PATH_MAX, "%s/%s/%i-header",
258 cached_data->nntp_cache_directory,
259 ancestor_data->nntp_group_name, msg_info->msg_index);
260
261 r = generic_cache_read(filename, &headers, &headers_length);
262 if (r == MAIL_NO_ERROR) {
263 * result = headers;
264 * result_len = headers_length;
265
266 return MAIL_NO_ERROR;
267 }
268
269 /* we get the message through the network */
270
271 r = nntpdriver_head(get_ancestor_session(msg_info), msg_info->msg_index,
272 &headers, &headers_length);
273 if (r != MAIL_NO_ERROR)
274 return r;
275
276 /* we write the message cache */
277
278 generic_cache_store(filename, headers, headers_length);
279
280 * result = headers;
281 * result_len = headers_length;
282
283 return MAIL_NO_ERROR;
284}
285
286static int nntp_fetch_size(mailmessage * msg_info,
287 size_t * result)
288{
289 return nntpdriver_size(get_ancestor_session(msg_info),
290 msg_info->msg_index, result);
291}
292
293static int nntp_get_flags(mailmessage * msg_info,
294 struct mail_flags ** result)
295{
296 int r;
297 struct mail_flags * flags;
298 struct mail_cache_db * cache_db_flags;
299 char filename_flags[PATH_MAX];
300 int res;
301 MMAPString * mmapstr;
302
303 if (msg_info->msg_flags != NULL) {
304 * result = msg_info->msg_flags;
305
306 return MAIL_NO_ERROR;
307 }
308
309 flags = mail_flags_store_get(get_cached_session_data(msg_info)->nntp_flags_store, msg_info->msg_index);
310
311 if (flags == NULL) {
312 struct nntp_cached_session_state_data * cached_data;
313 struct nntp_session_state_data * ancestor_data;
314
315 cached_data = get_cached_session_data(msg_info);
316
317 ancestor_data = get_ancestor_session_data(msg_info);
318 if (ancestor_data->nntp_group_name == NULL) {
319 res = MAIL_ERROR_BAD_STATE;
320 goto err;
321 }
322
323 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
324 cached_data->nntp_flags_directory,
325 ancestor_data->nntp_group_name, FLAGS_NAME);
326
327 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
328 if (r < 0) {
329 res = MAIL_ERROR_MEMORY;
330 goto err;
331 }
332
333 mmapstr = mmap_string_new("");
334 if (mmapstr == NULL) {
335 res = MAIL_ERROR_MEMORY;
336 goto close_db_flags;
337 }
338
339 r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
340 msg_info->msg_index, &flags);
341 if (r != MAIL_NO_ERROR) {
342 flags = mail_flags_new_empty();
343 if (flags == NULL) {
344 res = MAIL_ERROR_MEMORY;
345 goto free_mmapstr;
346 }
347 }
348
349 mmap_string_free(mmapstr);
350 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
351 }
352
353 msg_info->msg_flags = flags;
354
355 * result = flags;
356
357 return MAIL_NO_ERROR;
358
359 free_mmapstr:
360 mmap_string_free(mmapstr);
361 close_db_flags:
362 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
363 err:
364 return res;
365}
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached_message.h b/kmicromail/libetpan/generic/nntpdriver_cached_message.h
new file mode 100644
index 0000000..c12f479
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached_message.h
@@ -0,0 +1,52 @@
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 <libetpan/mailmessage_types.h>
37
38#ifndef NNTPDRIVER_CACHED_MESSAGE_H
39
40#define NNTPDRIVER_CACHED_MESSAGE_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * nntp_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_message.c b/kmicromail/libetpan/generic/nntpdriver_message.c
new file mode 100644
index 0000000..47b11ec
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_message.c
@@ -0,0 +1,169 @@
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 "nntpdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "nntpdriver_tools.h"
40#include "nntpdriver.h"
41#include "newsnntp.h"
42#include <string.h>
43#include <stdlib.h>
44
45static int nntp_prefetch(mailmessage * msg_info);
46
47static void nntp_prefetch_free(struct generic_message_t * msg);
48
49static int nntp_initialize(mailmessage * msg_info);
50
51static int nntp_fetch_header(mailmessage * msg_info,
52 char ** result,
53 size_t * result_len);
54
55static int nntp_fetch_size(mailmessage * msg_info,
56 size_t * result);
57
58static mailmessage_driver local_nntp_message_driver = {
59 .msg_name = "nntp",
60
61 .msg_initialize = nntp_initialize,
62 .msg_uninitialize = mailmessage_generic_uninitialize,
63
64 .msg_flush = mailmessage_generic_flush,
65 .msg_check = NULL,
66
67 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
68
69 .msg_fetch = mailmessage_generic_fetch,
70 .msg_fetch_header = nntp_fetch_header,
71 .msg_fetch_body = mailmessage_generic_fetch_body,
72 .msg_fetch_size = nntp_fetch_size,
73 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
74 .msg_fetch_section = mailmessage_generic_fetch_section,
75 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
76 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
77 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
78 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
79
80 .msg_get_flags = NULL,
81};
82
83mailmessage_driver * nntp_message_driver = &local_nntp_message_driver;
84
85static int nntp_prefetch(mailmessage * msg_info)
86{
87 char * msg_content;
88 size_t msg_length;
89 struct generic_message_t * msg;
90 int r;
91
92 r = nntpdriver_article(msg_info->msg_session, msg_info->msg_index,
93 &msg_content, &msg_length);
94 if (r != MAIL_NO_ERROR)
95 return r;
96
97 msg = msg_info->msg_data;
98
99 msg->msg_message = msg_content;
100 msg->msg_length = msg_length;
101
102 return MAIL_NO_ERROR;
103}
104
105static void nntp_prefetch_free(struct generic_message_t * msg)
106{
107 if (msg->msg_message != NULL) {
108 mmap_string_unref(msg->msg_message);
109 msg->msg_message = NULL;
110 }
111}
112
113static int nntp_initialize(mailmessage * msg_info)
114{
115 struct generic_message_t * msg;
116 int r;
117 char * uid;
118 char static_uid[20];
119
120 snprintf(static_uid, 20, "%u", msg_info->msg_index);
121 uid = strdup(static_uid);
122 if (uid == NULL)
123 return MAIL_ERROR_MEMORY;
124
125 r = mailmessage_generic_initialize(msg_info);
126 if (r != MAIL_NO_ERROR) {
127 free(uid);
128 return r;
129 }
130
131 msg = msg_info->msg_data;
132 msg->msg_prefetch = nntp_prefetch;
133 msg->msg_prefetch_free = nntp_prefetch_free;
134 msg_info->msg_uid = uid;
135
136 return MAIL_NO_ERROR;
137}
138
139static int nntp_fetch_header(mailmessage * msg_info,
140 char ** result,
141 size_t * result_len)
142{
143 struct generic_message_t * msg;
144 char * headers;
145 size_t headers_length;
146 int r;
147
148 msg = msg_info->msg_data;
149
150 if (msg->msg_message != NULL)
151 return mailmessage_generic_fetch_header(msg_info,
152 result, result_len);
153
154 r = nntpdriver_head(msg_info->msg_session, msg_info->msg_index,
155 &headers, &headers_length);
156 if (r != MAIL_NO_ERROR)
157 return r;
158
159 * result = headers;
160 * result_len = headers_length;
161
162 return MAIL_NO_ERROR;
163}
164
165static int nntp_fetch_size(mailmessage * msg_info,
166 size_t * result)
167{
168 return nntpdriver_size(msg_info->msg_session, msg_info->msg_index, result);
169}
diff --git a/kmicromail/libetpan/generic/nntpdriver_message.h b/kmicromail/libetpan/generic/nntpdriver_message.h
new file mode 100644
index 0000000..3b12a2d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_message.h
@@ -0,0 +1,52 @@
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#ifndef NNTPDRIVER_MESSAGE_H
37
38#define NNTPDRIVER_MESSAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/nntpdriver_types.h>
45
46extern mailmessage_driver * nntp_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_tools.c b/kmicromail/libetpan/generic/nntpdriver_tools.c
new file mode 100644
index 0000000..26be916
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_tools.c
@@ -0,0 +1,563 @@
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 "nntpdriver_tools.h"
37
38#include "mail.h"
39#include "nntpdriver.h"
40#include "nntpdriver_cached.h"
41#include "newsnntp.h"
42#include "maildriver_types.h"
43#include "generic_cache.h"
44#include "imfcache.h"
45#include "mailmessage.h"
46#include "mail_cache_db.h"
47
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <unistd.h>
52#include <string.h>
53#include <stdlib.h>
54
55int nntpdriver_nntp_error_to_mail_error(int error)
56{
57 switch (error) {
58 case NEWSNNTP_NO_ERROR:
59 return MAIL_NO_ERROR;
60
61 case NEWSNNTP_ERROR_STREAM:
62 return MAIL_ERROR_STREAM;
63
64 case NEWSNNTP_ERROR_UNEXPECTED:
65 return MAIL_ERROR_PROGRAM_ERROR;
66
67 case NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED:
68 return MAIL_ERROR_FOLDER_NOT_FOUND;
69
70 case NEWSNNTP_ERROR_NO_ARTICLE_SELECTED:
71 case NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER:
72 case NEWSNNTP_ERROR_ARTICLE_NOT_FOUND:
73 return MAIL_ERROR_MSG_NOT_FOUND;
74
75 case NEWSNNTP_ERROR_UNEXPECTED_RESPONSE:
76 case NEWSNNTP_ERROR_INVALID_RESPONSE:
77 return MAIL_ERROR_PARSE;
78
79 case NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP:
80 return MAIL_ERROR_FOLDER_NOT_FOUND;
81
82 case NEWSNNTP_ERROR_POSTING_NOT_ALLOWED:
83 return MAIL_ERROR_READONLY;
84
85 case NEWSNNTP_ERROR_POSTING_FAILED:
86 return MAIL_ERROR_APPEND;
87
88 case NEWSNNTP_ERROR_PROGRAM_ERROR:
89 return MAIL_ERROR_PROGRAM_ERROR;
90
91 case NEWSNNTP_ERROR_NO_PERMISSION:
92 return MAIL_ERROR_NO_PERMISSION;
93
94 case NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD:
95 case NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED:
96 return MAIL_ERROR_COMMAND_NOT_SUPPORTED;
97
98 case NEWSNNTP_ERROR_CONNECTION_REFUSED:
99 return MAIL_ERROR_CONNECT;
100
101 case NEWSNNTP_ERROR_MEMORY:
102 return MAIL_ERROR_MEMORY;
103
104 case NEWSNNTP_ERROR_AUTHENTICATION_REJECTED:
105 return MAIL_ERROR_LOGIN;
106
107 case NEWSNNTP_ERROR_BAD_STATE:
108 return MAIL_ERROR_BAD_STATE;
109
110 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
111 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
112 default:
113 return MAIL_ERROR_INVAL;
114 }
115}
116
117static inline struct nntp_session_state_data *
118session_get_data(mailsession * session)
119{
120 return session->sess_data;
121}
122
123static inline newsnntp * session_get_nntp_session(mailsession * session)
124{
125 return session_get_data(session)->nntp_session;
126}
127
128static inline struct nntp_cached_session_state_data *
129cached_session_get_data(mailsession * session)
130{
131 return session->sess_data;
132}
133
134static inline mailsession * cached_session_get_ancestor(mailsession * session)
135{
136 return cached_session_get_data(session)->nntp_ancestor;
137}
138
139static inline struct nntp_session_state_data *
140cached_session_get_ancestor_data(mailsession * session)
141{
142 return session_get_data(cached_session_get_ancestor(session));
143}
144
145static inline newsnntp * cached_session_get_nntp_session(mailsession * session)
146{
147 return session_get_nntp_session(cached_session_get_ancestor(session));
148}
149
150
151int nntpdriver_authenticate_password(mailsession * session)
152{
153 struct nntp_session_state_data * data;
154 int r;
155
156 data = session_get_data(session);
157
158 if (data->nntp_password == NULL)
159 return MAIL_ERROR_LOGIN;
160
161 r = newsnntp_authinfo_password(session_get_nntp_session(session),
162 data->nntp_password);
163
164 return nntpdriver_nntp_error_to_mail_error(r);
165}
166
167int nntpdriver_mode_reader(mailsession * session)
168{
169 int done;
170 int r;
171
172 done = FALSE;
173
174 do {
175 r = newsnntp_mode_reader(session_get_nntp_session(session));
176
177 switch (r) {
178 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
179 r = nntpdriver_authenticate_user(session);
180 if (r != MAIL_NO_ERROR)
181 return r;
182 break;
183
184 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
185 r = nntpdriver_authenticate_password(session);
186 if (r != MAIL_NO_ERROR)
187 return r;
188 break;
189
190 case NEWSNNTP_NO_ERROR:
191 done = TRUE;
192 break;
193
194 default:
195 done = TRUE;
196 break;
197 }
198 }
199 while (!done);
200
201 return MAIL_NO_ERROR;
202}
203
204int nntpdriver_authenticate_user(mailsession * session)
205{
206 struct nntp_session_state_data * data;
207 int r;
208
209 data = session_get_data(session);
210
211 if (data->nntp_userid == NULL)
212 return MAIL_ERROR_LOGIN;
213
214 r = newsnntp_authinfo_username(session_get_nntp_session(session),
215 data->nntp_userid);
216
217 switch (r) {
218 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
219 return nntpdriver_authenticate_password(session);
220
221 default:
222 return nntpdriver_nntp_error_to_mail_error(r);
223 }
224}
225
226int nntpdriver_article(mailsession * session, uint32_t index,
227 char ** result,
228 size_t * result_len)
229{
230 char * msg_content;
231 size_t msg_length;
232 int r;
233 int done;
234
235 done = FALSE;
236 do {
237 r = newsnntp_article(session_get_nntp_session(session),
238 index, &msg_content, &msg_length);
239
240 switch (r) {
241 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
242 r = nntpdriver_authenticate_user(session);
243 if (r != MAIL_NO_ERROR)
244 return r;
245 break;
246
247 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
248 r = nntpdriver_authenticate_password(session);
249 if (r != MAIL_NO_ERROR)
250 return r;
251 break;
252
253 case NEWSNNTP_NO_ERROR:
254 done = TRUE;
255 break;
256
257 default:
258 return nntpdriver_nntp_error_to_mail_error(r);
259 }
260 }
261 while (!done);
262
263 * result = msg_content;
264 * result_len = msg_length;
265
266 return MAIL_NO_ERROR;
267}
268
269int nntpdriver_head(mailsession * session, uint32_t index,
270 char ** result,
271 size_t * result_len)
272{
273 char * headers;
274 size_t headers_length;
275 int r;
276 int done;
277
278 done = FALSE;
279 do {
280 r = newsnntp_head(session_get_nntp_session(session),
281 index, &headers, &headers_length);
282
283 switch (r) {
284 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
285 r = nntpdriver_authenticate_user(session);
286 if (r != MAIL_NO_ERROR)
287 return r;
288 break;
289
290 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
291 r = nntpdriver_authenticate_password(session);
292 if (r != MAIL_NO_ERROR)
293 return r;
294 break;
295
296 case NEWSNNTP_NO_ERROR:
297 done = TRUE;
298 break;
299
300 default:
301 return nntpdriver_nntp_error_to_mail_error(r);
302 }
303 }
304 while (!done);
305
306 * result = headers;
307 * result_len = headers_length;
308
309 return MAIL_NO_ERROR;
310}
311
312int nntpdriver_size(mailsession * session, uint32_t index,
313 size_t * result)
314{
315 newsnntp * nntp;
316 struct newsnntp_xover_resp_item * item;
317 int r;
318 int done;
319
320 nntp = session_get_nntp_session(session);
321
322 done = FALSE;
323 do {
324 r = newsnntp_xover_single(nntp, index, &item);
325 switch (r) {
326 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
327 r = nntpdriver_authenticate_user(session);
328 if (r != MAIL_NO_ERROR)
329 return r;
330 break;
331
332 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
333 r = nntpdriver_authenticate_password(session);
334 if (r != MAIL_NO_ERROR)
335 return r;
336 break;
337
338 case NEWSNNTP_NO_ERROR:
339 done = TRUE;
340 break;
341
342 default:
343 return nntpdriver_nntp_error_to_mail_error(r);
344 }
345 }
346 while (!done);
347
348 * result = item->ovr_size;
349
350 xover_resp_item_free(item);
351
352 return MAIL_NO_ERROR;
353}
354
355int
356nntpdriver_get_cached_flags(struct mail_cache_db * cache_db,
357 MMAPString * mmapstr,
358 uint32_t num,
359 struct mail_flags ** result)
360{
361 int r;
362 char keyname[PATH_MAX];
363 struct mail_flags * flags;
364 int res;
365
366 snprintf(keyname, PATH_MAX, "%u-flags", num);
367
368 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
369 if (r != MAIL_NO_ERROR) {
370 res = r;
371 goto err;
372 }
373
374 * result = flags;
375
376 return MAIL_NO_ERROR;
377
378 err:
379 return res;
380}
381
382int
383nntpdriver_write_cached_flags(struct mail_cache_db * cache_db,
384 MMAPString * mmapstr,
385 uint32_t num,
386 struct mail_flags * flags)
387{
388 int r;
389 char keyname[PATH_MAX];
390 int res;
391
392 snprintf(keyname, PATH_MAX, "%u-flags", num);
393
394 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
395 if (r != MAIL_NO_ERROR) {
396 res = r;
397 goto err;
398 }
399
400 return MAIL_NO_ERROR;
401
402 err:
403 return res;
404}
405
406
407
408int nntpdriver_select_folder(mailsession * session, char * mb)
409{
410 int r;
411 struct newsnntp_group_info * info;
412 newsnntp * nntp_session;
413 struct nntp_session_state_data * data;
414 char * new_name;
415 int done;
416
417 data = session_get_data(session);
418
419 if (!data->nntp_mode_reader) {
420 r = nntpdriver_mode_reader(session);
421 if (r != MAIL_NO_ERROR)
422 return r;
423
424 data->nntp_mode_reader = TRUE;
425 }
426
427 if (data->nntp_group_name != NULL)
428 if (strcmp(data->nntp_group_name, mb) == 0)
429 return MAIL_NO_ERROR;
430
431 nntp_session = session_get_nntp_session(session);
432
433 done = FALSE;
434 do {
435 r = newsnntp_group(nntp_session, mb, &info);
436
437 switch (r) {
438 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
439 r = nntpdriver_authenticate_user(session);
440 if (r != MAIL_NO_ERROR)
441 return r;
442 break;
443
444 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
445 r = nntpdriver_authenticate_password(session);
446 if (r != MAIL_NO_ERROR)
447 return r;
448 break;
449
450 case NEWSNNTP_NO_ERROR:
451 done = TRUE;
452 break;
453
454 default:
455 return nntpdriver_nntp_error_to_mail_error(r);
456 }
457
458 }
459 while (!done);
460
461 new_name = strdup(mb);
462 if (new_name == NULL)
463 return MAIL_ERROR_MEMORY;
464
465 if (data->nntp_group_name != NULL)
466 free(data->nntp_group_name);
467 data->nntp_group_name = new_name;
468 if (data->nntp_group_info != NULL)
469 newsnntp_group_free(data->nntp_group_info);
470 data->nntp_group_info = info;
471
472 return MAIL_NO_ERROR;
473}
474
475
476int nntp_get_messages_list(mailsession * nntp_session,
477 mailsession * session,
478 mailmessage_driver * driver,
479 struct mailmessage_list ** result)
480{
481 carray * tab;
482 struct mailmessage_list * env_list;
483 uint32_t i;
484 int res;
485 int r;
486 struct nntp_session_state_data * data;
487 struct newsnntp_group_info * group_info;
488 uint32_t max;
489 unsigned int cur;
490
491 data = session_get_data(nntp_session);
492
493 if (data->nntp_group_name == NULL) {
494 res = MAIL_ERROR_BAD_STATE;
495 goto err;
496 }
497
498 r = nntpdriver_select_folder(nntp_session, data->nntp_group_name);
499 if (r != MAIL_NO_ERROR) {
500 res = r;
501 goto err;
502 }
503
504 group_info = data->nntp_group_info;
505
506 if (group_info == NULL) {
507 res = MAIL_ERROR_BAD_STATE;
508 goto err;
509 }
510
511 max = group_info->grp_first;
512 if (data->nntp_max_articles != 0) {
513 if (group_info->grp_last - data->nntp_max_articles + 1 > max)
514 max = group_info->grp_last - data->nntp_max_articles + 1;
515 }
516
517 tab = carray_new(128);
518 if (tab == NULL) {
519 res = MAIL_ERROR_MEMORY;
520 goto err;
521 }
522
523 for(i = max ; i <= group_info->grp_last ; i++) {
524 mailmessage * msg;
525
526 msg = mailmessage_new();
527 if (msg == NULL) {
528 res = MAIL_ERROR_MEMORY;
529 goto free_list;
530 }
531
532 r = mailmessage_init(msg, session, driver, i, 0);
533 if (r != MAIL_NO_ERROR) {
534 mailmessage_free(msg);
535 res = r;
536 goto free_list;
537 }
538
539 r = carray_add(tab, msg, NULL);
540 if (r < 0) {
541 mailmessage_free(msg);
542 res = MAIL_ERROR_MEMORY;
543 goto free_list;
544 }
545 }
546
547 env_list = mailmessage_list_new(tab);
548 if (env_list == NULL) {
549 res = MAIL_ERROR_MEMORY;
550 goto free_list;
551 }
552
553 * result = env_list;
554
555 return MAIL_NO_ERROR;
556
557 free_list:
558 for(cur = 0 ; cur < carray_count(tab) ; cur ++)
559 mailmessage_free(carray_get(tab, cur));
560 carray_free(tab);
561 err:
562 return res;
563}
diff --git a/kmicromail/libetpan/generic/nntpdriver_tools.h b/kmicromail/libetpan/generic/nntpdriver_tools.h
new file mode 100644
index 0000000..6b8aca5
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_tools.h
@@ -0,0 +1,88 @@
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#ifndef NNTPDRIVER_TOOLS_H
37
38#define NNTPDRIVER_TOOLS_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mail_cache_db_types.h"
45#include "nntpdriver_types.h"
46
47int nntpdriver_nntp_error_to_mail_error(int error);
48
49int nntpdriver_authenticate_password(mailsession * session);
50
51int nntpdriver_authenticate_user(mailsession * session);
52
53int nntpdriver_article(mailsession * session, uint32_t index,
54 char ** result, size_t * result_len);
55
56int nntpdriver_head(mailsession * session, uint32_t index,
57 char ** result,
58 size_t * result_len);
59
60int nntpdriver_size(mailsession * session, uint32_t index,
61 size_t * result);
62
63int
64nntpdriver_get_cached_flags(struct mail_cache_db * cache_db,
65 MMAPString * mmapstr,
66 uint32_t num,
67 struct mail_flags ** result);
68
69int
70nntpdriver_write_cached_flags(struct mail_cache_db * cache_db,
71 MMAPString * mmapstr,
72 uint32_t num,
73 struct mail_flags * flags);
74
75int nntpdriver_select_folder(mailsession * session, char * mb);
76
77int nntp_get_messages_list(mailsession * nntp_session,
78 mailsession * session,
79 mailmessage_driver * driver,
80 struct mailmessage_list ** result);
81
82int nntpdriver_mode_reader(mailsession * session);
83
84#ifdef __cplusplus
85}
86#endif
87
88#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_types.h b/kmicromail/libetpan/generic/nntpdriver_types.h
new file mode 100644
index 0000000..6492788
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_types.h
@@ -0,0 +1,146 @@
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#ifndef NNTPDRIVER_TYPES_H
37
38#define NNTPDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/newsnntp.h>
44#include <libetpan/clist.h>
45#include <libetpan/generic_cache_types.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/* NNTP driver for session */
53
54enum {
55 NNTPDRIVER_SET_MAX_ARTICLES = 1,
56};
57
58struct nntp_session_state_data {
59 newsnntp * nntp_session;
60 char * nntp_userid;
61 char * nntp_password;
62
63 struct newsnntp_group_info * nntp_group_info;
64 char * nntp_group_name;
65
66 clist * nntp_subscribed_list;
67
68 uint32_t nntp_max_articles;
69
70 int nntp_mode_reader;
71};
72
73/* cached NNTP driver for session */
74
75enum {
76 /* the mapping of the parameters should be the same as for nntp */
77 NNTPDRIVER_CACHED_SET_MAX_ARTICLES = 1,
78 /* cache specific */
79 NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY,
80 NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY,
81};
82
83struct nntp_cached_session_state_data {
84 mailsession * nntp_ancestor;
85 char nntp_cache_directory[PATH_MAX];
86 char nntp_flags_directory[PATH_MAX];
87 struct mail_flags_store * nntp_flags_store;
88};
89
90
91/* nntp storage */
92
93/*
94 nntp_mailstorage is the state data specific to the IMAP4rev1 storage.
95
96 - storage this is the storage to initialize.
97
98 - servername this is the name of the NNTP server
99
100 - port is the port to connect to, on the server.
101 you give 0 to use the default port.
102
103 - connection_type is the type of socket layer to use.
104 The value can be CONNECTION_TYPE_PLAIN or CONNECTION_TYPE_TLS.
105
106 - auth_type is the authenticate mechanism to use.
107 The value can be NNTP_AUTH_TYPE_PLAIN.
108
109 - login is the login of the POP3 account.
110
111 - password is the password of the POP3 account.
112
113 - cached if this value is != 0, a persistant cache will be
114 stored on local system.
115
116 - cache_directory is the location of the cache
117
118 - flags_directory is the location of the flags
119*/
120
121struct nntp_mailstorage {
122 char * nntp_servername;
123 uint16_t nntp_port;
124 char * nntp_command;
125 int nntp_connection_type;
126
127 int nntp_auth_type;
128 char * nntp_login;
129 char * nntp_password;
130
131 int nntp_cached;
132 char * nntp_cache_directory;
133 char * nntp_flags_directory;
134};
135
136/* this is the type of NNTP authentication */
137
138enum {
139 NNTP_AUTH_TYPE_PLAIN, /* plain text authentication */
140};
141
142#ifdef __cplusplus
143}
144#endif
145
146#endif
diff --git a/kmicromail/libetpan/generic/nntpstorage.c b/kmicromail/libetpan/generic/nntpstorage.c
new file mode 100644
index 0000000..5ba333b
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpstorage.c
@@ -0,0 +1,267 @@
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 "nntpstorage.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41#include "maildriver.h"
42#include "nntpdriver.h"
43#include "nntpdriver_cached.h"
44#include "mailstorage_tools.h"
45#include "mail.h"
46
47/* nntp storage */
48
49#define NNTP_DEFAULT_PORT 119
50#define NNTPS_DEFAULT_PORT 563
51
52static int nntp_mailstorage_connect(struct mailstorage * storage);
53static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
54 char * pathname, mailsession ** result);
55static void nntp_mailstorage_uninitialize(struct mailstorage * storage);
56
57static mailstorage_driver nntp_mailstorage_driver = {
58 .sto_name = "nntp",
59 .sto_connect = nntp_mailstorage_connect,
60 .sto_get_folder_session = nntp_mailstorage_get_folder_session,
61 .sto_uninitialize = nntp_mailstorage_uninitialize,
62};
63
64int nntp_mailstorage_init(struct mailstorage * storage,
65 char * nn_servername, uint16_t nn_port,
66 char * nn_command,
67 int nn_connection_type, int nn_auth_type,
68 char * nn_login, char * nn_password,
69 int nn_cached, char * nn_cache_directory, char * nn_flags_directory)
70{
71 struct nntp_mailstorage * nntp_storage;
72 int res;
73
74 nntp_storage = malloc(sizeof(struct nntp_mailstorage));
75 if (nntp_storage == NULL) {
76 res = MAIL_ERROR_MEMORY;
77 goto err;
78 }
79
80 nntp_storage->nntp_servername = strdup(nn_servername);
81 if (nntp_storage->nntp_servername == NULL) {
82 res = MAIL_ERROR_MEMORY;
83 goto free;
84 }
85
86 nntp_storage->nntp_connection_type = nn_connection_type;
87
88 if (nn_port == 0) {
89 switch (nn_connection_type) {
90 case CONNECTION_TYPE_PLAIN:
91 case CONNECTION_TYPE_COMMAND:
92 nn_port = NNTP_DEFAULT_PORT;
93 break;
94
95 case CONNECTION_TYPE_TLS:
96 case CONNECTION_TYPE_COMMAND_TLS:
97 nn_port = NNTPS_DEFAULT_PORT;
98 break;
99
100 default:
101 res = MAIL_ERROR_INVAL;
102 goto free_servername;
103 }
104 }
105
106 nntp_storage->nntp_port = nn_port;
107
108 if (nn_command != NULL) {
109 nntp_storage->nntp_command = strdup(nn_command);
110 if (nntp_storage->nntp_command == NULL) {
111 res = MAIL_ERROR_MEMORY;
112 goto free_servername;
113 }
114 }
115 else
116 nntp_storage->nntp_command = NULL;
117
118 nntp_storage->nntp_auth_type = nn_auth_type;
119
120 if (nn_login != NULL) {
121 nntp_storage->nntp_login = strdup(nn_login);
122 if (nntp_storage->nntp_login == NULL) {
123 res = MAIL_ERROR_MEMORY;
124 goto free_command;
125 }
126 }
127 else
128 nntp_storage->nntp_login = NULL;
129
130 if (nn_password != NULL) {
131 nntp_storage->nntp_password = strdup(nn_password);
132 if (nntp_storage->nntp_password == NULL) {
133 res = MAIL_ERROR_MEMORY;
134 goto free_login;
135 }
136 }
137 else
138 nntp_storage->nntp_password = NULL;
139
140 nntp_storage->nntp_cached = nn_cached;
141
142 if (nn_cached && (nn_cache_directory != NULL) &&
143 (nn_flags_directory != NULL)) {
144 nntp_storage->nntp_cache_directory = strdup(nn_cache_directory);
145 if (nntp_storage->nntp_cache_directory == NULL) {
146 res = MAIL_ERROR_MEMORY;
147 goto free_password;
148 }
149 nntp_storage->nntp_flags_directory = strdup(nn_flags_directory);
150 if (nntp_storage->nntp_flags_directory == NULL) {
151 res = MAIL_ERROR_MEMORY;
152 goto free_cache_directory;
153 }
154 }
155 else {
156 nntp_storage->nntp_cached = FALSE;
157 nntp_storage->nntp_cache_directory = NULL;
158 nntp_storage->nntp_flags_directory = NULL;
159 }
160
161 storage->sto_data = nntp_storage;
162 storage->sto_driver = &nntp_mailstorage_driver;
163
164 return MAIL_NO_ERROR;
165
166 free_cache_directory:
167 free(nntp_storage->nntp_cache_directory);
168 free_password:
169 free(nntp_storage->nntp_password);
170 free_login:
171 free(nntp_storage->nntp_login);
172 free_command:
173 free(nn_command);
174 free_servername:
175 free(nntp_storage->nntp_servername);
176 free:
177 free(nntp_storage);
178 err:
179 return res;
180}
181
182static void nntp_mailstorage_uninitialize(struct mailstorage * storage)
183{
184 struct nntp_mailstorage * nntp_storage;
185
186 nntp_storage = storage->sto_data;
187
188 if (nntp_storage->nntp_flags_directory != NULL)
189 free(nntp_storage->nntp_flags_directory);
190 if (nntp_storage->nntp_cache_directory != NULL)
191 free(nntp_storage->nntp_cache_directory);
192 if (nntp_storage->nntp_password != NULL)
193 free(nntp_storage->nntp_password);
194 if (nntp_storage->nntp_login != NULL)
195 free(nntp_storage->nntp_login);
196 if (nntp_storage->nntp_command != NULL)
197 free(nntp_storage->nntp_command);
198 free(nntp_storage->nntp_servername);
199 free(nntp_storage);
200
201 storage->sto_data = NULL;
202}
203
204static int nntp_mailstorage_connect(struct mailstorage * storage)
205{
206 struct nntp_mailstorage * nntp_storage;
207 mailsession_driver * driver;
208 int r;
209 int res;
210 mailsession * session;
211
212 nntp_storage = storage->sto_data;
213
214 if (nntp_storage->nntp_cached)
215 driver = nntp_cached_session_driver;
216 else
217 driver = nntp_session_driver;
218
219 r = mailstorage_generic_connect(driver,
220 nntp_storage->nntp_servername,
221 nntp_storage->nntp_port, nntp_storage->nntp_command,
222 nntp_storage->nntp_connection_type,
223 NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY,
224 nntp_storage->nntp_cache_directory,
225 NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY,
226 nntp_storage->nntp_flags_directory,
227 &session);
228 switch (r) {
229 case MAIL_NO_ERROR_NON_AUTHENTICATED:
230 case MAIL_NO_ERROR_AUTHENTICATED:
231 case MAIL_NO_ERROR:
232 break;
233 default:
234 res = r;
235 goto err;
236 }
237
238 r = mailstorage_generic_auth(session, r,
239 nntp_storage->nntp_connection_type,
240 nntp_storage->nntp_login,
241 nntp_storage->nntp_password);
242 if (r != MAIL_NO_ERROR) {
243 res = r;
244 goto free;
245 }
246
247 storage->sto_session = session;
248
249 return MAIL_NO_ERROR;
250
251 free:
252 mailsession_free(session);
253 err:
254 return res;
255}
256
257static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
258 char * pathname, mailsession ** result)
259{
260 int r;
261
262 r = mailsession_select_folder(storage->sto_session, pathname);
263
264 * result = storage->sto_session;
265
266 return MAIL_NO_ERROR;
267}
diff --git a/kmicromail/libetpan/generic/nntpstorage.h b/kmicromail/libetpan/generic/nntpstorage.h
new file mode 100644
index 0000000..794c717
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpstorage.h
@@ -0,0 +1,93 @@
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#ifndef NNTPSTORAGE_H
37
38#define NNTPSTORAGE_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46
47/*
48 nntp_mailstorage_init is the constructor for a NNTP storage
49
50 @param storage this is the storage to initialize.
51
52 @param servername this is the name of the NNTP server
53
54 @param port is the port to connect to, on the server.
55 you give 0 to use the default port.
56
57 @param command the command used to connect to the server instead of
58 allowing normal TCP connections to be used.
59
60 @param connection_type is the type of socket layer to use.
61 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
62 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
63 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
64 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
65
66 @param auth_type is the authenticate mechanism to use.
67 The value can be NNTP_AUTH_TYPE_PLAIN.
68
69 @param login is the login of the POP3 account.
70
71 @param password is the password of the POP3 account.
72
73 @param cached if this value is != 0, a persistant cache will be
74 stored on local system.
75
76 @param cache_directory is the location of the cache
77
78 @param flags_directory is the location of the flags
79*/
80
81int nntp_mailstorage_init(struct mailstorage * storage,
82 char * nntp_servername, uint16_t nntp_port,
83 char * nntp_command,
84 int nntp_connection_type, int nntp_auth_type,
85 char * nntp_login, char * nntp_password,
86 int nntp_cached, char * nntp_cache_directory,
87 char * nntp_flags_directory);
88
89#ifdef __cplusplus
90}
91#endif
92
93#endif
diff --git a/kmicromail/libetpan/generic/pop3driver.c b/kmicromail/libetpan/generic/pop3driver.c
new file mode 100644
index 0000000..20b0fc2
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver.c
@@ -0,0 +1,387 @@
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.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "pop3driver_message.h"
42#include "maildriver_tools.h"
43#include "pop3driver_tools.h"
44#include "mailmessage.h"
45
46static int pop3driver_initialize(mailsession * session);
47
48static void pop3driver_uninitialize(mailsession * session);
49
50static int pop3driver_parameters(mailsession * session,
51 int id, void * value);
52
53static int pop3driver_connect_stream(mailsession * session, mailstream * s);
54
55static int pop3driver_starttls(mailsession * session);
56
57static int pop3driver_login(mailsession * session,
58 char * userid, char * password);
59
60static int pop3driver_logout(mailsession * session);
61
62static int pop3driver_noop(mailsession * session);
63
64static int pop3driver_status_folder(mailsession * session, char * mb,
65 uint32_t * result_messages, uint32_t * result_recent,
66 uint32_t * result_unseen);
67
68static int pop3driver_messages_number(mailsession * session, char * mb,
69 uint32_t * result);
70
71static int pop3driver_remove_message(mailsession * session, uint32_t num);
72
73static int pop3driver_get_messages_list(mailsession * session,
74 struct mailmessage_list ** result);
75
76static int pop3driver_get_message(mailsession * session,
77 uint32_t num, mailmessage ** result);
78
79static mailsession_driver local_pop3_session_driver = {
80 .sess_name = "pop3",
81
82 .sess_initialize = pop3driver_initialize,
83 .sess_uninitialize = pop3driver_uninitialize,
84
85 .sess_parameters = pop3driver_parameters,
86
87 .sess_connect_stream = pop3driver_connect_stream,
88 .sess_connect_path = NULL,
89 .sess_starttls = pop3driver_starttls,
90 .sess_login = pop3driver_login,
91 .sess_logout = pop3driver_logout,
92 .sess_noop = pop3driver_noop,
93
94 .sess_build_folder_name = NULL,
95 .sess_create_folder = NULL,
96 .sess_delete_folder = NULL,
97 .sess_rename_folder = NULL,
98 .sess_check_folder = NULL,
99 .sess_examine_folder = NULL,
100 .sess_select_folder = NULL,
101 .sess_expunge_folder = NULL,
102 .sess_status_folder = pop3driver_status_folder,
103 .sess_messages_number = pop3driver_messages_number,
104 .sess_recent_number = pop3driver_messages_number,
105 .sess_unseen_number = pop3driver_messages_number,
106 .sess_list_folders = NULL,
107 .sess_lsub_folders = NULL,
108 .sess_subscribe_folder = NULL,
109 .sess_unsubscribe_folder = NULL,
110
111 .sess_append_message = NULL,
112 .sess_copy_message = NULL,
113 .sess_move_message = NULL,
114
115 .sess_get_messages_list = pop3driver_get_messages_list,
116 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
117 .sess_remove_message = pop3driver_remove_message,
118#if 0
119 .sess_search_messages = maildriver_generic_search_messages,
120#endif
121
122 .sess_get_message = pop3driver_get_message,
123 .sess_get_message_by_uid = NULL,
124};
125
126mailsession_driver * pop3_session_driver = &local_pop3_session_driver;
127
128static inline struct pop3_session_state_data *
129get_data(mailsession * session)
130{
131 return session->sess_data;
132}
133
134static mailpop3 * get_pop3_session(mailsession * session)
135{
136 return get_data(session)->pop3_session;
137}
138
139static int pop3driver_initialize(mailsession * session)
140{
141 struct pop3_session_state_data * data;
142 mailpop3 * pop3;
143
144 pop3 = mailpop3_new(0, NULL);
145 if (session == NULL)
146 goto err;
147
148 data = malloc(sizeof(* data));
149 if (data == NULL)
150 goto free;
151
152 data->pop3_session = pop3;
153 data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
154
155 session->sess_data = data;
156
157 return MAIL_NO_ERROR;
158
159 free:
160 mailpop3_free(pop3);
161 err:
162 return MAIL_ERROR_MEMORY;
163}
164
165static void pop3driver_uninitialize(mailsession * session)
166{
167 struct pop3_session_state_data * data;
168
169 data = get_data(session);
170
171 mailpop3_free(data->pop3_session);
172 free(data);
173
174 session->sess_data = data;
175}
176
177static int pop3driver_connect_stream(mailsession * session, mailstream * s)
178{
179 int r;
180
181 r = mailpop3_connect(get_pop3_session(session), s);
182
183 switch (r) {
184 case MAILPOP3_NO_ERROR:
185 return MAIL_NO_ERROR_NON_AUTHENTICATED;
186
187 default:
188 return pop3driver_pop3_error_to_mail_error(r);
189 }
190}
191
192static int pop3driver_starttls(mailsession * session)
193{
194 int r;
195 int fd;
196 mailstream_low * low;
197 mailstream_low * new_low;
198 mailpop3 * pop3;
199
200 pop3 = get_pop3_session(session);
201
202 r = mailpop3_stls(pop3);
203
204 switch (r) {
205 case MAILPOP3_NO_ERROR:
206 break;
207 default:
208 return pop3driver_pop3_error_to_mail_error(r);
209 }
210
211 low = mailstream_get_low(pop3->pop3_stream);
212 fd = mailstream_low_get_fd(low);
213 if (fd == -1)
214 return MAIL_ERROR_STREAM;
215
216 new_low = mailstream_low_ssl_open(fd);
217 if (new_low == NULL)
218 return MAIL_ERROR_STREAM;
219 mailstream_low_free(low);
220 mailstream_set_low(pop3->pop3_stream, new_low);
221
222 return MAIL_NO_ERROR;
223}
224
225static int pop3driver_parameters(mailsession * session,
226 int id, void * value)
227{
228 struct pop3_session_state_data * data;
229
230 data = get_data(session);
231
232 switch (id) {
233 case POP3DRIVER_SET_AUTH_TYPE:
234 {
235 int * param;
236
237 param = value;
238
239 data->pop3_auth_type = * param;
240 return MAIL_NO_ERROR;
241 }
242 }
243
244 return MAIL_ERROR_INVAL;
245}
246
247static int pop3driver_login(mailsession * session,
248 char * userid, char * password)
249{
250 int r;
251 carray * msg_tab;
252 struct pop3_session_state_data * data;
253
254 data = get_data(session);
255
256 switch (data->pop3_auth_type) {
257 case POP3DRIVER_AUTH_TYPE_TRY_APOP:
258 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
259 if (r != MAILPOP3_NO_ERROR)
260 r = mailpop3_login(get_pop3_session(session), userid, password);
261 break;
262
263 case POP3DRIVER_AUTH_TYPE_APOP:
264 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
265 break;
266
267 default:
268 case POP3DRIVER_AUTH_TYPE_PLAIN:
269 r = mailpop3_login(get_pop3_session(session), userid, password);
270 break;
271 }
272
273 mailpop3_list(get_pop3_session(session), &msg_tab);
274
275 return pop3driver_pop3_error_to_mail_error(r);
276}
277
278static int pop3driver_logout(mailsession * session)
279{
280 int r;
281
282 r = mailpop3_quit(get_pop3_session(session));
283
284 return pop3driver_pop3_error_to_mail_error(r);
285}
286
287static int pop3driver_noop(mailsession * session)
288{
289 int r;
290
291 r = mailpop3_noop(get_pop3_session(session));
292
293 return pop3driver_pop3_error_to_mail_error(r);
294}
295
296static int pop3driver_status_folder(mailsession * session, char * mb,
297 uint32_t * result_messages,
298 uint32_t * result_recent,
299 uint32_t * result_unseen)
300{
301 uint32_t count;
302 int r;
303
304 r = pop3driver_messages_number(session, mb, &count);
305 if (r != MAIL_NO_ERROR)
306 return r;
307
308 * result_messages = count;
309 * result_recent = count;
310 * result_unseen = count;
311
312 return MAIL_NO_ERROR;
313}
314
315static int pop3driver_messages_number(mailsession * session, char * mb,
316 uint32_t * result)
317{
318 carray * msg_tab;
319
320 mailpop3_list(get_pop3_session(session), &msg_tab);
321
322 * result = carray_count(msg_tab) -
323 get_pop3_session(session)->pop3_deleted_count;
324
325 return MAIL_NO_ERROR;
326}
327
328
329/* messages operations */
330
331static int pop3driver_remove_message(mailsession * session, uint32_t num)
332{
333 mailpop3 * pop3;
334 int r;
335
336 pop3 = get_pop3_session(session);
337
338 r = mailpop3_dele(pop3, num);
339 switch (r) {
340 case MAILPOP3_ERROR_BAD_STATE:
341 return MAIL_ERROR_BAD_STATE;
342
343 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
344 return MAIL_ERROR_MSG_NOT_FOUND;
345
346 case MAILPOP3_ERROR_STREAM:
347 return MAIL_ERROR_STREAM;
348
349 case MAILPOP3_NO_ERROR:
350 return MAIL_NO_ERROR;
351
352 default:
353 return MAIL_ERROR_REMOVE;
354 }
355}
356
357static int pop3driver_get_messages_list(mailsession * session,
358 struct mailmessage_list ** result)
359{
360 mailpop3 * pop3;
361
362 pop3 = get_pop3_session(session);
363
364 return pop3_get_messages_list(pop3, session,
365 pop3_message_driver, result);
366}
367
368static int pop3driver_get_message(mailsession * session,
369 uint32_t num, mailmessage ** result)
370{
371 mailmessage * msg_info;
372 int r;
373
374 msg_info = mailmessage_new();
375 if (msg_info == NULL)
376 return MAIL_ERROR_MEMORY;
377
378 r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0);
379 if (r != MAIL_NO_ERROR) {
380 mailmessage_free(msg_info);
381 return r;
382 }
383
384 * result = msg_info;
385
386 return MAIL_NO_ERROR;
387}
diff --git a/kmicromail/libetpan/generic/pop3driver.h b/kmicromail/libetpan/generic/pop3driver.h
new file mode 100644
index 0000000..2df94db
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver.h
@@ -0,0 +1,52 @@
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#ifndef POP3DRIVER_H
37
38#define POP3DRIVER_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * pop3_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
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}
diff --git a/kmicromail/libetpan/generic/pop3driver_cached.h b/kmicromail/libetpan/generic/pop3driver_cached.h
new file mode 100644
index 0000000..953e699
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached.h
@@ -0,0 +1,52 @@
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#ifndef POP3DRIVER_CACHED_H
37
38#define POP3DRIVER_CACHED_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/pop3driver_types.h>
45
46extern mailsession_driver * pop3_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_cached_message.c b/kmicromail/libetpan/generic/pop3driver_cached_message.c
new file mode 100644
index 0000000..7aeb22c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached_message.c
@@ -0,0 +1,355 @@
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_message.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mail_cache_db.h"
42
43#include "mailmessage.h"
44#include "mailmessage_tools.h"
45#include "pop3driver.h"
46#include "pop3driver_tools.h"
47#include "pop3driver_cached.h"
48#include "pop3driver_message.h"
49#include "generic_cache.h"
50
51static int pop3_prefetch(mailmessage * msg_info);
52
53static void pop3_prefetch_free(struct generic_message_t * msg);
54
55static int pop3_initialize(mailmessage * msg_info);
56
57static void pop3_flush(mailmessage * msg_info);
58
59static void pop3_check(mailmessage * msg_info);
60
61static int pop3_fetch_header(mailmessage * msg_info,
62 char ** result,
63 size_t * result_len);
64
65static int pop3_fetch_size(mailmessage * msg_info,
66 size_t * result);
67
68static int pop3_get_flags(mailmessage * msg_info,
69 struct mail_flags ** result);
70
71static void pop3_uninitialize(mailmessage * msg_info);
72
73static mailmessage_driver local_pop3_cached_message_driver = {
74 .msg_name = "pop3-cached",
75
76 .msg_initialize = pop3_initialize,
77 .msg_uninitialize = pop3_uninitialize,
78
79 .msg_flush = pop3_flush,
80 .msg_check = pop3_check,
81
82 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
83
84 .msg_fetch = mailmessage_generic_fetch,
85 .msg_fetch_header = pop3_fetch_header,
86 .msg_fetch_body = mailmessage_generic_fetch_body,
87 .msg_fetch_size = pop3_fetch_size,
88 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
89 .msg_fetch_section = mailmessage_generic_fetch_section,
90 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
91 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
92 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
93 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
94
95 .msg_get_flags = pop3_get_flags,
96};
97
98mailmessage_driver * pop3_cached_message_driver =
99&local_pop3_cached_message_driver;
100
101
102static inline struct pop3_cached_session_state_data *
103get_cached_session_data(mailmessage * msg)
104{
105 return msg->msg_session->sess_data;
106}
107
108static inline mailsession * get_ancestor_session(mailmessage * msg)
109{
110 return get_cached_session_data(msg)->pop3_ancestor;
111}
112
113static inline struct pop3_session_state_data *
114get_ancestor_session_data(mailmessage * msg)
115{
116 return get_ancestor_session(msg)->sess_data;
117}
118
119static inline mailpop3 * get_pop3_session(mailmessage * msg)
120{
121 return get_ancestor_session_data(msg)->pop3_session;
122}
123
124
125static int pop3_prefetch(mailmessage * msg_info)
126{
127 char * msg_content;
128 size_t msg_length;
129 struct generic_message_t * msg;
130 int r;
131 struct pop3_cached_session_state_data * cached_data;
132 char filename[PATH_MAX];
133
134 /* we try the cached message */
135
136 cached_data = get_cached_session_data(msg_info);
137
138 snprintf(filename, PATH_MAX, "%s/%s",
139 cached_data->pop3_cache_directory, msg_info->msg_uid);
140
141 r = generic_cache_read(filename, &msg_content, &msg_length);
142 if (r == MAIL_NO_ERROR) {
143 msg = msg_info->msg_data;
144
145 msg->msg_message = msg_content;
146 msg->msg_length = msg_length;
147
148 return MAIL_NO_ERROR;
149 }
150
151 /* we get the message through the network */
152
153 r = pop3driver_retr(get_ancestor_session(msg_info), msg_info->msg_index,
154 &msg_content, &msg_length);
155 if (r != MAIL_NO_ERROR)
156 return r;
157
158 /* we write the message cache */
159
160 generic_cache_store(filename, msg_content, msg_length);
161
162 msg = msg_info->msg_data;
163
164 msg->msg_message = msg_content;
165 msg->msg_length = msg_length;
166
167 return MAIL_NO_ERROR;
168}
169
170static void pop3_prefetch_free(struct generic_message_t * msg)
171{
172 if (msg->msg_message != NULL) {
173 mmap_string_unref(msg->msg_message);
174 msg->msg_message = NULL;
175 }
176}
177
178static int pop3_initialize(mailmessage * msg_info)
179{
180 struct generic_message_t * msg;
181 int r;
182 char * uid;
183 struct mailpop3_msg_info * info;
184 mailpop3 * pop3;
185
186 pop3 = get_pop3_session(msg_info);
187
188 r = mailpop3_get_msg_info(pop3, msg_info->msg_index, &info);
189 switch (r) {
190 case MAILPOP3_NO_ERROR:
191 break;
192 default:
193 return pop3driver_pop3_error_to_mail_error(r);
194 }
195
196 uid = strdup(info->msg_uidl);
197 if (uid == NULL)
198 return MAIL_ERROR_MEMORY;
199
200 r = mailmessage_generic_initialize(msg_info);
201 if (r != MAIL_NO_ERROR) {
202 free(uid);
203 return r;
204 }
205
206 msg = msg_info->msg_data;
207 msg->msg_prefetch = pop3_prefetch;
208 msg->msg_prefetch_free = pop3_prefetch_free;
209 msg_info->msg_uid = uid;
210
211 return MAIL_NO_ERROR;
212}
213
214static void pop3_uninitialize(mailmessage * msg_info)
215{
216 mailmessage_generic_uninitialize(msg_info);
217}
218
219#define FLAGS_NAME "flags.db"
220
221static void pop3_flush(mailmessage * msg_info)
222{
223 mailmessage_generic_flush(msg_info);
224}
225
226static void pop3_check(mailmessage * msg_info)
227{
228 int r;
229
230 if (msg_info->msg_flags != NULL) {
231 r = mail_flags_store_set(get_cached_session_data(msg_info)->pop3_flags_store,
232 msg_info);
233 }
234}
235
236
237static int pop3_fetch_header(mailmessage * msg_info,
238 char ** result,
239 size_t * result_len)
240{
241 struct generic_message_t * msg;
242 char * headers;
243 size_t headers_length;
244 int r;
245 struct pop3_cached_session_state_data * cached_data;
246 char filename[PATH_MAX];
247
248 msg = msg_info->msg_data;
249
250 if (msg->msg_message != NULL)
251 return mailmessage_generic_fetch_header(msg_info,
252 result, result_len);
253
254 /* we try the cached message */
255
256 cached_data = get_cached_session_data(msg_info);
257
258 snprintf(filename, PATH_MAX, "%s/%s-header",
259 cached_data->pop3_cache_directory, msg_info->msg_uid);
260
261 r = generic_cache_read(filename, &headers, &headers_length);
262 if (r == MAIL_NO_ERROR) {
263 * result = headers;
264 * result_len = headers_length;
265
266 return MAIL_NO_ERROR;
267 }
268
269 /* we get the message trough the network */
270
271 r = pop3driver_header(get_ancestor_session(msg_info), msg_info->msg_index,
272 &headers, &headers_length);
273 if (r != MAIL_NO_ERROR)
274 return r;
275
276 generic_cache_store(filename, headers, headers_length);
277
278 * result = headers;
279 * result_len = headers_length;
280
281 return MAIL_NO_ERROR;
282}
283
284static int pop3_fetch_size(mailmessage * msg_info,
285 size_t * result)
286{
287 return pop3driver_size(get_ancestor_session(msg_info),
288 msg_info->msg_index, result);
289}
290
291static int pop3_get_flags(mailmessage * msg_info,
292 struct mail_flags ** result)
293{
294 int r;
295 struct mail_flags * flags;
296 struct mail_cache_db * cache_db_flags;
297 char filename_flags[PATH_MAX];
298 int res;
299 struct pop3_cached_session_state_data * cached_data;
300 MMAPString * mmapstr;
301
302 if (msg_info->msg_flags != NULL) {
303 * result = msg_info->msg_flags;
304
305 return MAIL_NO_ERROR;
306 }
307
308 cached_data = get_cached_session_data(msg_info);
309
310 flags = mail_flags_store_get(cached_data->pop3_flags_store,
311 msg_info->msg_index);
312
313 if (flags == NULL) {
314 snprintf(filename_flags, PATH_MAX, "%s/%s",
315 cached_data->pop3_flags_directory, FLAGS_NAME);
316
317 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
318 if (r < 0) {
319 res = MAIL_ERROR_MEMORY;
320 goto err;
321 }
322
323 mmapstr = mmap_string_new("");
324 if (mmapstr == NULL) {
325 res = MAIL_ERROR_MEMORY;
326 goto close_db_flags;
327 }
328
329 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
330 msg_info->msg_session, msg_info->msg_index, &flags);
331 if (r != MAIL_NO_ERROR) {
332 flags = mail_flags_new_empty();
333 if (flags == NULL) {
334 res = MAIL_ERROR_MEMORY;
335 goto free_mmapstr;
336 }
337 }
338
339 mmap_string_free(mmapstr);
340 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
341 }
342
343 msg_info->msg_flags = flags;
344
345 * result = flags;
346
347 return MAIL_NO_ERROR;
348
349 free_mmapstr:
350 mmap_string_free(mmapstr);
351 close_db_flags:
352 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
353 err:
354 return res;
355}
diff --git a/kmicromail/libetpan/generic/pop3driver_cached_message.h b/kmicromail/libetpan/generic/pop3driver_cached_message.h
new file mode 100644
index 0000000..d03f8e5
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached_message.h
@@ -0,0 +1,52 @@
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#ifndef POP3DRIVER_CACHED_MESSAGE_H
37
38#define POP3DRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * pop3_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_message.c b/kmicromail/libetpan/generic/pop3driver_message.c
new file mode 100644
index 0000000..77bd94c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_message.c
@@ -0,0 +1,159 @@
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_message.h"
37
38#include "mailmessage_tools.h"
39#include "pop3driver_tools.h"
40#include "pop3driver.h"
41#include "mailpop3.h"
42
43static int pop3_prefetch(mailmessage * msg_info);
44
45static void pop3_prefetch_free(struct generic_message_t * msg);
46
47static int pop3_initialize(mailmessage * msg_info);
48
49static int pop3_fetch_header(mailmessage * msg_info,
50 char ** result,
51 size_t * result_len);
52
53static int pop3_fetch_size(mailmessage * msg_info,
54 size_t * result);
55
56static mailmessage_driver local_pop3_message_driver = {
57 .msg_name = "pop3",
58
59 .msg_initialize = pop3_initialize,
60 .msg_uninitialize = mailmessage_generic_uninitialize,
61
62 .msg_flush = mailmessage_generic_flush,
63 .msg_check = NULL,
64
65 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
66
67 .msg_fetch = mailmessage_generic_fetch,
68 .msg_fetch_header = pop3_fetch_header,
69 .msg_fetch_body = mailmessage_generic_fetch_body,
70 .msg_fetch_size = pop3_fetch_size,
71 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
72 .msg_fetch_section = mailmessage_generic_fetch_section,
73 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
74 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
75 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
76 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
77
78 .msg_get_flags = NULL,
79};
80
81mailmessage_driver * pop3_message_driver = &local_pop3_message_driver;
82
83
84static int pop3_prefetch(mailmessage * msg_info)
85{
86 char * msg_content;
87 size_t msg_length;
88 struct generic_message_t * msg;
89 int r;
90
91 r = pop3driver_retr(msg_info->msg_session, msg_info->msg_index,
92 &msg_content, &msg_length);
93 if (r != MAIL_NO_ERROR)
94 return r;
95
96 msg = msg_info->msg_data;
97
98 msg->msg_message = msg_content;
99 msg->msg_length = msg_length;
100
101 return MAIL_NO_ERROR;
102}
103
104static void pop3_prefetch_free(struct generic_message_t * msg)
105{
106 if (msg->msg_message != NULL) {
107 mmap_string_unref(msg->msg_message);
108 msg->msg_message = NULL;
109 }
110}
111
112static int pop3_initialize(mailmessage * msg_info)
113{
114 struct generic_message_t * msg;
115 int r;
116
117 r = mailmessage_generic_initialize(msg_info);
118 if (r != MAIL_NO_ERROR)
119 return r;
120
121 msg = msg_info->msg_data;
122 msg->msg_prefetch = pop3_prefetch;
123 msg->msg_prefetch_free = pop3_prefetch_free;
124
125 return MAIL_NO_ERROR;
126}
127
128
129static int pop3_fetch_header(mailmessage * msg_info,
130 char ** result,
131 size_t * result_len)
132{
133 struct generic_message_t * msg;
134 char * headers;
135 size_t headers_length;
136 int r;
137
138 msg = msg_info->msg_data;
139
140 if (msg->msg_message != NULL)
141 return mailmessage_generic_fetch_header(msg_info,
142 result, result_len);
143
144 r = pop3driver_header(msg_info->msg_session, msg_info->msg_index,
145 &headers, &headers_length);
146 if (r != MAIL_NO_ERROR)
147 return r;
148
149 * result = headers;
150 * result_len = headers_length;
151
152 return MAIL_NO_ERROR;
153}
154
155static int pop3_fetch_size(mailmessage * msg_info,
156 size_t * result)
157{
158 return pop3driver_size(msg_info->msg_session, msg_info->msg_index, result);
159}
diff --git a/kmicromail/libetpan/generic/pop3driver_message.h b/kmicromail/libetpan/generic/pop3driver_message.h
new file mode 100644
index 0000000..6281a39
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_message.h
@@ -0,0 +1,52 @@
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#ifndef POP3DRIVER_MESSAGE_H
37
38#define POP3DRIVER_MESSAGE_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * pop3_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_tools.c b/kmicromail/libetpan/generic/pop3driver_tools.c
new file mode 100644
index 0000000..8978b47
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_tools.c
@@ -0,0 +1,344 @@
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_tools.h"
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <unistd.h>
42
43#include "maildriver_types.h"
44#include "mailpop3.h"
45#include "pop3driver.h"
46#include "pop3driver_cached.h"
47#include "generic_cache.h"
48#include "imfcache.h"
49#include "mailmessage.h"
50#include "mail_cache_db.h"
51
52int pop3driver_pop3_error_to_mail_error(int error)
53{
54 switch (error) {
55 case MAILPOP3_NO_ERROR:
56 return MAIL_NO_ERROR;
57
58 case MAILPOP3_ERROR_BAD_STATE:
59 return MAIL_ERROR_BAD_STATE;
60
61 case MAILPOP3_ERROR_UNAUTHORIZED:
62 return MAIL_ERROR_CONNECT;
63
64 case MAILPOP3_ERROR_STREAM:
65 return MAIL_ERROR_STREAM;
66
67 case MAILPOP3_ERROR_DENIED:
68 return MAIL_ERROR_CONNECT;
69
70 case MAILPOP3_ERROR_BAD_USER:
71 case MAILPOP3_ERROR_BAD_PASSWORD:
72 return MAIL_ERROR_LOGIN;
73
74 case MAILPOP3_ERROR_CANT_LIST:
75 return MAIL_ERROR_LIST;
76
77 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
78 return MAIL_ERROR_MSG_NOT_FOUND;
79
80 case MAILPOP3_ERROR_MEMORY:
81 return MAIL_ERROR_MEMORY;
82
83 case MAILPOP3_ERROR_CONNECTION_REFUSED:
84 return MAIL_ERROR_CONNECT;
85
86 case MAILPOP3_ERROR_APOP_NOT_SUPPORTED:
87 return MAIL_ERROR_NO_APOP;
88
89 case MAILPOP3_ERROR_CAPA_NOT_SUPPORTED:
90 return MAIL_ERROR_CAPABILITY;
91
92 case MAILPOP3_ERROR_STLS_NOT_SUPPORTED:
93 return MAIL_ERROR_NO_TLS;
94
95 default:
96 return MAIL_ERROR_INVAL;
97 }
98};
99
100static inline struct pop3_session_state_data *
101session_get_data(mailsession * session)
102{
103 return session->sess_data;
104}
105
106static inline mailpop3 * session_get_pop3_session(mailsession * session)
107{
108 return session_get_data(session)->pop3_session;
109}
110
111static inline struct pop3_cached_session_state_data *
112cached_session_get_data(mailsession * session)
113{
114 return session->sess_data;
115}
116
117static inline mailsession *
118cached_session_get_ancestor(mailsession * session)
119{
120 return cached_session_get_data(session)->pop3_ancestor;
121}
122
123static inline struct pop3_session_state_data *
124cached_session_get_ancestor_data(mailsession * session)
125{
126 return session_get_data(cached_session_get_ancestor(session));
127}
128
129static inline mailpop3 *
130cached_session_get_pop3_session(mailsession * session)
131{
132 return session_get_pop3_session(cached_session_get_ancestor(session));
133}
134
135
136int pop3driver_retr(mailsession * session, uint32_t index,
137 char ** result, size_t * result_len)
138{
139 char * msg_content;
140 size_t msg_length;
141 int r;
142
143 r = mailpop3_retr(session_get_pop3_session(session), index,
144 &msg_content, &msg_length);
145
146 switch (r) {
147 case MAILPOP3_NO_ERROR:
148 break;
149 default:
150 return pop3driver_pop3_error_to_mail_error(r);
151 }
152
153 * result = msg_content;
154 * result_len = msg_length;
155
156 return MAIL_NO_ERROR;
157}
158
159int pop3driver_header(mailsession * session, uint32_t index,
160 char ** result,
161 size_t * result_len)
162{
163 char * headers;
164 size_t headers_length;
165 int r;
166
167 r = mailpop3_header(session_get_pop3_session(session),
168 index, &headers, &headers_length);
169
170 switch (r) {
171 case MAILPOP3_NO_ERROR:
172 break;
173 default:
174 return pop3driver_pop3_error_to_mail_error(r);
175 }
176
177 * result = headers;
178 * result_len = headers_length;
179
180 return MAIL_NO_ERROR;
181}
182
183int pop3driver_size(mailsession * session, uint32_t index,
184 size_t * result)
185{
186 mailpop3 * pop3;
187 carray * msg_tab;
188 struct mailpop3_msg_info * info;
189 int r;
190
191 pop3 = session_get_pop3_session(session);
192
193 mailpop3_list(pop3, &msg_tab);
194
195 r = mailpop3_get_msg_info(pop3, index, &info);
196 switch (r) {
197 case MAILPOP3_NO_ERROR:
198 break;
199 default:
200 return pop3driver_pop3_error_to_mail_error(r);
201 }
202
203 * result = info->msg_size;
204
205 return MAIL_NO_ERROR;
206}
207
208int
209pop3driver_get_cached_flags(struct mail_cache_db * cache_db,
210 MMAPString * mmapstr,
211 mailsession * session,
212 uint32_t num,
213 struct mail_flags ** result)
214{
215 int r;
216 char keyname[PATH_MAX];
217 struct mail_flags * flags;
218 int res;
219 struct mailpop3_msg_info * info;
220
221 r = mailpop3_get_msg_info(cached_session_get_pop3_session(session),
222 num, &info);
223 switch (r) {
224 case MAILPOP3_ERROR_BAD_STATE:
225 return MAIL_ERROR_BAD_STATE;
226 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
227 return MAIL_ERROR_MSG_NOT_FOUND;
228 case MAILPOP3_NO_ERROR:
229 break;
230 default:
231 return MAIL_ERROR_FETCH;
232 }
233
234 snprintf(keyname, PATH_MAX, "%s-flags", info->msg_uidl);
235
236 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
237 if (r != MAIL_NO_ERROR) {
238 res = r;
239 goto err;
240 }
241
242 * result = flags;
243
244 return MAIL_NO_ERROR;
245
246 err:
247 return res;
248}
249
250int
251pop3driver_write_cached_flags(struct mail_cache_db * cache_db,
252 MMAPString * mmapstr,
253 char * uid,
254 struct mail_flags * flags)
255{
256 int r;
257 char keyname[PATH_MAX];
258 int res;
259
260 snprintf(keyname, PATH_MAX, "%s-flags", uid);
261
262 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
263 if (r != MAIL_NO_ERROR) {
264 res = r;
265 goto err;
266 }
267
268 return MAIL_NO_ERROR;
269
270 err:
271 return res;
272}
273
274int pop3_get_messages_list(mailpop3 * pop3,
275 mailsession * session,
276 mailmessage_driver * driver,
277 struct mailmessage_list ** result)
278{
279 carray * msg_tab;
280 carray * tab;
281 struct mailmessage_list * env_list;
282 unsigned int i;
283 int res;
284 int r;
285
286 mailpop3_list(pop3, &msg_tab);
287
288 tab = carray_new(128);
289 if (tab == NULL) {
290 res = MAIL_ERROR_MEMORY;
291 goto err;
292 }
293
294 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
295 struct mailpop3_msg_info * pop3_info;
296 mailmessage * msg;
297
298 pop3_info = carray_get(msg_tab, i);
299
300 if (pop3_info == NULL)
301 continue;
302
303 if (pop3_info->msg_deleted)
304 continue;
305
306 msg = mailmessage_new();
307 if (msg == NULL) {
308 res = MAIL_ERROR_MEMORY;
309 goto free_list;
310 }
311
312 r = mailmessage_init(msg, session, driver,
313 (uint32_t) pop3_info->msg_index, pop3_info->msg_size);
314 if (r != MAIL_NO_ERROR) {
315 mailmessage_free(msg);
316 res = r;
317 goto free_list;
318 }
319
320 r = carray_add(tab, msg, NULL);
321 if (r < 0) {
322 mailmessage_free(msg);
323 res = MAIL_ERROR_MEMORY;
324 goto free_list;
325 }
326 }
327
328 env_list = mailmessage_list_new(/*list*/ tab);
329 if (env_list == NULL) {
330 res = MAIL_ERROR_MEMORY;
331 goto free_list;
332 }
333
334 * result = env_list;
335
336 return MAIL_NO_ERROR;
337
338 free_list:
339 for(i = 0 ; i < carray_count(tab) ; i ++)
340 mailmessage_free(carray_get(tab, i));
341 carray_free(tab);
342 err:
343 return res;
344}
diff --git a/kmicromail/libetpan/generic/pop3driver_tools.h b/kmicromail/libetpan/generic/pop3driver_tools.h
new file mode 100644
index 0000000..ad5f589
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_tools.h
@@ -0,0 +1,82 @@
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#ifndef POP3DRIVER_TOOLS_H
37
38#define POP3DRIVER_TOOLS_H
39
40#include "mail_cache_db_types.h"
41#include "pop3driver_types.h"
42#include "mailpop3.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48int pop3driver_pop3_error_to_mail_error(int error);
49
50int pop3driver_retr(mailsession * session, uint32_t index,
51 char ** result, size_t * result_len);
52
53int pop3driver_header(mailsession * session, uint32_t index,
54 char ** result,
55 size_t * result_len);
56
57int pop3driver_size(mailsession * session, uint32_t index,
58 size_t * result);
59
60int
61pop3driver_get_cached_flags(struct mail_cache_db * cache_db,
62 MMAPString * mmapstr,
63 mailsession * session,
64 uint32_t num,
65 struct mail_flags ** result);
66
67int
68pop3driver_write_cached_flags(struct mail_cache_db * cache_db,
69 MMAPString * mmapstr,
70 char * uid,
71 struct mail_flags * flags);
72
73int pop3_get_messages_list(mailpop3 * pop3,
74 mailsession * session,
75 mailmessage_driver * driver,
76 struct mailmessage_list ** result);
77
78#ifdef __cplusplus
79}
80#endif
81
82#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_types.h b/kmicromail/libetpan/generic/pop3driver_types.h
new file mode 100644
index 0000000..73286d8
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_types.h
@@ -0,0 +1,153 @@
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#ifndef POP3DRIVER_TYPES_H
37
38#define POP3DRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/mailpop3.h>
44#include <libetpan/maildriver_types.h>
45#include <libetpan/chash.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/* POP3 driver for session */
53
54enum {
55 POP3DRIVER_SET_AUTH_TYPE = 1,
56};
57
58enum {
59 POP3DRIVER_AUTH_TYPE_PLAIN = 0,
60 POP3DRIVER_AUTH_TYPE_APOP,
61 POP3DRIVER_AUTH_TYPE_TRY_APOP,
62};
63
64struct pop3_session_state_data {
65 int pop3_auth_type;
66 mailpop3 * pop3_session;
67};
68
69/* cached POP3 driver for session */
70
71enum {
72 /* the mapping of the parameters should be the same as for pop3 */
73 POP3DRIVER_CACHED_SET_AUTH_TYPE = 1,
74 /* cache specific */
75 POP3DRIVER_CACHED_SET_CACHE_DIRECTORY,
76 POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY,
77};
78
79struct pop3_cached_session_state_data {
80 mailsession * pop3_ancestor;
81 char pop3_cache_directory[PATH_MAX];
82 char pop3_flags_directory[PATH_MAX];
83 chash * pop3_flags_hash;
84 carray * pop3_flags_array;
85 struct mail_flags_store * pop3_flags_store;
86};
87
88/* pop3 storage */
89
90/*
91 pop3_mailstorage is the state data specific to the POP3 storage.
92
93 - servername this is the name of the POP3 server
94
95 - port is the port to connect to, on the server.
96 you give 0 to use the default port.
97
98 - connection_type is the type of socket layer to use.
99 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
100 CONNECTION_TYPE_TRY_STARTTLS or CONNECTION_TYPE_TLS.
101
102 - auth_type is the authenticate mechanism to use.
103 The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
104 or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
105
106 - login is the login of the POP3 account.
107
108 - password is the password of the POP3 account.
109
110 - cached if this value is != 0, a persistant cache will be
111 stored on local system.
112
113 - cache_directory is the location of the cache.
114
115 - flags_directory is the location of the flags.
116*/
117
118struct pop3_mailstorage {
119 char * pop3_servername;
120 uint16_t pop3_port;
121 char * pop3_command;
122 int pop3_connection_type;
123
124 int pop3_auth_type;
125 char * pop3_login;
126 char * pop3_password;
127
128 int pop3_cached;
129 char * pop3_cache_directory;
130 char * pop3_flags_directory;
131};
132
133/* this is the type of POP3 authentication */
134
135enum {
136 POP3_AUTH_TYPE_PLAIN, /* plain text authentication */
137 POP3_AUTH_TYPE_APOP, /* APOP authentication */
138 POP3_AUTH_TYPE_TRY_APOP, /* first, try APOP, if it fails,
139 try plain text */
140 POP3_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
141 POP3_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
142 POP3_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
143 POP3_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
144 POP3_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
145 POP3_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
146 POP3_AUTH_TYPE_SASL_DIGEST_MD5, /* SASL digest MD5 */
147};
148
149#ifdef __cplusplus
150}
151#endif
152
153#endif
diff --git a/kmicromail/libetpan/generic/pop3storage.c b/kmicromail/libetpan/generic/pop3storage.c
new file mode 100644
index 0000000..8e7a94e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3storage.c
@@ -0,0 +1,284 @@
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 "pop3storage.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41#include "mail.h"
42#include "mailstorage_tools.h"
43#include "maildriver.h"
44
45/* pop3 storage */
46
47#define POP3_DEFAULT_PORT 110
48#define POP3S_DEFAULT_PORT 995
49
50static int pop3_mailstorage_connect(struct mailstorage * storage);
51static int pop3_mailstorage_get_folder_session(struct mailstorage * storage,
52 char * pathname, mailsession ** result);
53static void pop3_mailstorage_uninitialize(struct mailstorage * storage);
54
55static mailstorage_driver pop3_mailstorage_driver = {
56 .sto_name = "pop3",
57 .sto_connect = pop3_mailstorage_connect,
58 .sto_get_folder_session = pop3_mailstorage_get_folder_session,
59 .sto_uninitialize = pop3_mailstorage_uninitialize,
60};
61
62int pop3_mailstorage_init(struct mailstorage * storage,
63 char * pop3_servername, uint16_t pop3_port,
64 char * pop3_command,
65 int pop3_connection_type, int pop3_auth_type,
66 char * pop3_login, char * pop3_password,
67 int pop3_cached, char * pop3_cache_directory, char * pop3_flags_directory)
68{
69 struct pop3_mailstorage * pop3_storage;
70
71 pop3_storage = malloc(sizeof(struct pop3_mailstorage));
72 if (pop3_storage == NULL)
73 goto err;
74
75 pop3_storage->pop3_servername = strdup(pop3_servername);
76 if (pop3_storage->pop3_servername == NULL)
77 goto free;
78
79 pop3_storage->pop3_connection_type = pop3_connection_type;
80
81 if (pop3_port == 0) {
82 switch (pop3_connection_type) {
83 case CONNECTION_TYPE_PLAIN:
84 case CONNECTION_TYPE_TRY_STARTTLS:
85 case CONNECTION_TYPE_STARTTLS:
86 case CONNECTION_TYPE_COMMAND:
87 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
88 case CONNECTION_TYPE_COMMAND_STARTTLS:
89 pop3_port = POP3_DEFAULT_PORT;
90 break;
91
92 case CONNECTION_TYPE_TLS:
93 case CONNECTION_TYPE_COMMAND_TLS:
94 pop3_port = POP3S_DEFAULT_PORT;
95 break;
96 }
97 }
98
99 pop3_storage->pop3_port = pop3_port;
100
101 if (pop3_command != NULL) {
102 pop3_storage->pop3_command = strdup(pop3_command);
103 if (pop3_storage->pop3_command == NULL)
104 goto free_servername;
105 }
106 else
107 pop3_storage->pop3_command = NULL;
108
109 pop3_storage->pop3_auth_type = pop3_auth_type;
110
111 if (pop3_login != NULL) {
112 pop3_storage->pop3_login = strdup(pop3_login);
113 if (pop3_storage->pop3_login == NULL)
114 goto free_command;
115 }
116 else
117 pop3_storage->pop3_login = NULL;
118
119 if (pop3_password != NULL) {
120 pop3_storage->pop3_password = strdup(pop3_password);
121 if (pop3_storage->pop3_password == NULL)
122 goto free_login;
123 }
124 else
125 pop3_storage->pop3_password = NULL;
126
127 pop3_storage->pop3_cached = pop3_cached;
128
129 if (pop3_cached && (pop3_cache_directory != NULL) &&
130 (pop3_flags_directory != NULL)) {
131 pop3_storage->pop3_cache_directory = strdup(pop3_cache_directory);
132 if (pop3_storage->pop3_cache_directory == NULL)
133 goto free_password;
134 pop3_storage->pop3_flags_directory = strdup(pop3_flags_directory);
135 if (pop3_storage->pop3_flags_directory == NULL)
136 goto free_cache_directory;
137 }
138 else {
139 pop3_storage->pop3_cached = FALSE;
140 pop3_storage->pop3_cache_directory = NULL;
141 pop3_storage->pop3_flags_directory = NULL;
142 }
143
144 storage->sto_data = pop3_storage;
145 storage->sto_driver = &pop3_mailstorage_driver;
146
147 return MAIL_NO_ERROR;
148
149 free_cache_directory:
150 free(pop3_storage->pop3_cache_directory);
151 free_password:
152 if (pop3_storage->pop3_password != NULL)
153 free(pop3_storage->pop3_password);
154 free_login:
155 if (pop3_storage->pop3_login != NULL)
156 free(pop3_storage->pop3_login);
157 free_command:
158 if (pop3_storage->pop3_command != NULL)
159 free(pop3_storage->pop3_command);
160 free_servername:
161 if (pop3_storage->pop3_servername != NULL)
162 free(pop3_storage->pop3_servername);
163 free:
164 free(pop3_storage);
165 err:
166 return MAIL_ERROR_MEMORY;
167}
168
169static void pop3_mailstorage_uninitialize(struct mailstorage * storage)
170{
171 struct pop3_mailstorage * pop3_storage;
172
173 pop3_storage = storage->sto_data;
174
175 if (pop3_storage->pop3_flags_directory != NULL)
176 free(pop3_storage->pop3_flags_directory);
177 if (pop3_storage->pop3_cache_directory != NULL)
178 free(pop3_storage->pop3_cache_directory);
179 if (pop3_storage->pop3_password != NULL)
180 free(pop3_storage->pop3_password);
181 if (pop3_storage->pop3_login != NULL)
182 free(pop3_storage->pop3_login);
183 if (pop3_storage->pop3_command != NULL)
184 free(pop3_storage->pop3_command);
185 free(pop3_storage->pop3_servername);
186 free(pop3_storage);
187
188 storage->sto_data = pop3_storage;
189}
190
191static int pop3_mailstorage_connect(struct mailstorage * storage)
192{
193 struct pop3_mailstorage * pop3_storage;
194 mailsession_driver * driver;
195 int r;
196 int res;
197 mailsession * session;
198 int auth_type;
199
200 pop3_storage = storage->sto_data;
201
202 if (pop3_storage->pop3_cached)
203 driver = pop3_cached_session_driver;
204 else
205 driver = pop3_session_driver;
206
207 r = mailstorage_generic_connect(driver,
208 pop3_storage->pop3_servername,
209 pop3_storage->pop3_port, pop3_storage->pop3_command,
210 pop3_storage->pop3_connection_type,
211 POP3DRIVER_CACHED_SET_CACHE_DIRECTORY,
212 pop3_storage->pop3_cache_directory,
213 POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY,
214 pop3_storage->pop3_flags_directory,
215 &session);
216 switch (r) {
217 case MAIL_NO_ERROR_NON_AUTHENTICATED:
218 case MAIL_NO_ERROR_AUTHENTICATED:
219 case MAIL_NO_ERROR:
220 break;
221 default:
222 res = r;
223 goto err;
224 }
225
226 auth_type = -1;
227 switch (pop3_storage->pop3_auth_type) {
228 case POP3_AUTH_TYPE_PLAIN:
229 auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
230 break;
231 case POP3_AUTH_TYPE_APOP:
232 auth_type = POP3DRIVER_AUTH_TYPE_APOP;
233 break;
234 case POP3_AUTH_TYPE_TRY_APOP:
235 auth_type = POP3DRIVER_AUTH_TYPE_TRY_APOP;
236 break;
237 }
238
239 if (auth_type != -1) {
240 mailsession_parameters(session, POP3DRIVER_SET_AUTH_TYPE, &auth_type);
241 }
242
243 r = mailstorage_generic_auth(session, r,
244 pop3_storage->pop3_auth_type,
245 pop3_storage->pop3_login,
246 pop3_storage->pop3_password);
247 if (r != MAIL_NO_ERROR) {
248 if (pop3_storage->pop3_auth_type == POP3_AUTH_TYPE_TRY_APOP) {
249 /* try in clear authentication */
250 mailsession_free(session);
251
252 pop3_storage->pop3_auth_type = POP3_AUTH_TYPE_PLAIN;
253 r = mailstorage_connect(storage);
254 if (r != MAIL_NO_ERROR) {
255 res = r;
256 return res;
257 }
258 pop3_storage->pop3_auth_type = POP3_AUTH_TYPE_TRY_APOP;
259
260 return MAIL_NO_ERROR;
261 }
262
263 res = r;
264 goto free;
265 }
266
267 storage->sto_session = session;
268
269 return MAIL_NO_ERROR;
270
271 free:
272 mailsession_free(session);
273 err:
274 return res;
275}
276
277static int pop3_mailstorage_get_folder_session(struct mailstorage * storage,
278 char * pathname, mailsession ** result)
279{
280 * result = storage->sto_session;
281
282 return MAIL_NO_ERROR;
283}
284
diff --git a/kmicromail/libetpan/generic/pop3storage.h b/kmicromail/libetpan/generic/pop3storage.h
new file mode 100644
index 0000000..c2118b6
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3storage.h
@@ -0,0 +1,95 @@
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#ifndef POP3STORAGE_H
37
38#define POP3STORAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/pop3driver_types.h>
45#include <libetpan/pop3driver.h>
46#include <libetpan/pop3driver_cached.h>
47
48/*
49 pop3_mailstorage_init is the constructor for a POP3 storage
50
51 @param storage this is the storage to initialize.
52
53 @param servername this is the name of the POP3 server
54
55 @param port is the port to connect to, on the server.
56 you give 0 to use the default port.
57
58 @param command the command used to connect to the server instead of
59 allowing normal TCP connections to be used.
60
61 @param connection_type is the type of socket layer to use.
62 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
63 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
64 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
65 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
66
67 @param auth_type is the authenticate mechanism to use.
68 The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
69 or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
70
71 @param login is the login of the POP3 account.
72
73 @param password is the password of the POP3 account.
74
75 @param cached if this value is != 0, a persistant cache will be
76 stored on local system.
77
78 @param cache_directory is the location of the cache
79
80 @param flags_directory is the location of the flags
81*/
82
83int pop3_mailstorage_init(struct mailstorage * storage,
84 char * pop3_servername, uint16_t pop3_port,
85 char * pop3_command,
86 int pop3_connection_type, int pop3_auth_type,
87 char * pop3_login, char * pop3_password,
88 int pop3_cached, char * pop3_cache_directory,
89 char * pop3_flags_directory);
90
91#ifdef __cplusplus
92}
93#endif
94
95#endif