summaryrefslogtreecommitdiffabout
path: root/libetpan/src/driver/implementation/pop3
Unidiff
Diffstat (limited to 'libetpan/src/driver/implementation/pop3') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver.c388
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached.c899
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c355
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_message.c193
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_message.h52
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_tools.c344
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_tools.h82
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver_types.h153
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3storage.c284
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3storage.h95
13 files changed, 3001 insertions, 0 deletions
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver.c b/libetpan/src/driver/implementation/pop3/pop3driver.c
new file mode 100644
index 0000000..ea69923
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver.c
@@ -0,0 +1,388 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "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_append_message_flags = NULL,
113 .sess_copy_message = NULL,
114 .sess_move_message = NULL,
115
116 .sess_get_messages_list = pop3driver_get_messages_list,
117 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
118 .sess_remove_message = pop3driver_remove_message,
119#if 0
120 .sess_search_messages = maildriver_generic_search_messages,
121#endif
122
123 .sess_get_message = pop3driver_get_message,
124 .sess_get_message_by_uid = NULL,
125};
126
127mailsession_driver * pop3_session_driver = &local_pop3_session_driver;
128
129static inline struct pop3_session_state_data *
130get_data(mailsession * session)
131{
132 return session->sess_data;
133}
134
135static mailpop3 * get_pop3_session(mailsession * session)
136{
137 return get_data(session)->pop3_session;
138}
139
140static int pop3driver_initialize(mailsession * session)
141{
142 struct pop3_session_state_data * data;
143 mailpop3 * pop3;
144
145 pop3 = mailpop3_new(0, NULL);
146 if (session == NULL)
147 goto err;
148
149 data = malloc(sizeof(* data));
150 if (data == NULL)
151 goto free;
152
153 data->pop3_session = pop3;
154 data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
155
156 session->sess_data = data;
157
158 return MAIL_NO_ERROR;
159
160 free:
161 mailpop3_free(pop3);
162 err:
163 return MAIL_ERROR_MEMORY;
164}
165
166static void pop3driver_uninitialize(mailsession * session)
167{
168 struct pop3_session_state_data * data;
169
170 data = get_data(session);
171
172 mailpop3_free(data->pop3_session);
173 free(data);
174
175 session->sess_data = data;
176}
177
178static int pop3driver_connect_stream(mailsession * session, mailstream * s)
179{
180 int r;
181
182 r = mailpop3_connect(get_pop3_session(session), s);
183
184 switch (r) {
185 case MAILPOP3_NO_ERROR:
186 return MAIL_NO_ERROR_NON_AUTHENTICATED;
187
188 default:
189 return pop3driver_pop3_error_to_mail_error(r);
190 }
191}
192
193static int pop3driver_starttls(mailsession * session)
194{
195 int r;
196 int fd;
197 mailstream_low * low;
198 mailstream_low * new_low;
199 mailpop3 * pop3;
200
201 pop3 = get_pop3_session(session);
202
203 r = mailpop3_stls(pop3);
204
205 switch (r) {
206 case MAILPOP3_NO_ERROR:
207 break;
208 default:
209 return pop3driver_pop3_error_to_mail_error(r);
210 }
211
212 low = mailstream_get_low(pop3->pop3_stream);
213 fd = mailstream_low_get_fd(low);
214 if (fd == -1)
215 return MAIL_ERROR_STREAM;
216
217 new_low = mailstream_low_ssl_open(fd);
218 if (new_low == NULL)
219 return MAIL_ERROR_STREAM;
220 mailstream_low_free(low);
221 mailstream_set_low(pop3->pop3_stream, new_low);
222
223 return MAIL_NO_ERROR;
224}
225
226static int pop3driver_parameters(mailsession * session,
227 int id, void * value)
228{
229 struct pop3_session_state_data * data;
230
231 data = get_data(session);
232
233 switch (id) {
234 case POP3DRIVER_SET_AUTH_TYPE:
235 {
236 int * param;
237
238 param = value;
239
240 data->pop3_auth_type = * param;
241 return MAIL_NO_ERROR;
242 }
243 }
244
245 return MAIL_ERROR_INVAL;
246}
247
248static int pop3driver_login(mailsession * session,
249 char * userid, char * password)
250{
251 int r;
252 carray * msg_tab;
253 struct pop3_session_state_data * data;
254
255 data = get_data(session);
256
257 switch (data->pop3_auth_type) {
258 case POP3DRIVER_AUTH_TYPE_TRY_APOP:
259 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
260 if (r != MAILPOP3_NO_ERROR)
261 r = mailpop3_login(get_pop3_session(session), userid, password);
262 break;
263
264 case POP3DRIVER_AUTH_TYPE_APOP:
265 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
266 break;
267
268 default:
269 case POP3DRIVER_AUTH_TYPE_PLAIN:
270 r = mailpop3_login(get_pop3_session(session), userid, password);
271 break;
272 }
273
274 mailpop3_list(get_pop3_session(session), &msg_tab);
275
276 return pop3driver_pop3_error_to_mail_error(r);
277}
278
279static int pop3driver_logout(mailsession * session)
280{
281 int r;
282
283 r = mailpop3_quit(get_pop3_session(session));
284
285 return pop3driver_pop3_error_to_mail_error(r);
286}
287
288static int pop3driver_noop(mailsession * session)
289{
290 int r;
291
292 r = mailpop3_noop(get_pop3_session(session));
293
294 return pop3driver_pop3_error_to_mail_error(r);
295}
296
297static int pop3driver_status_folder(mailsession * session, char * mb,
298 uint32_t * result_messages,
299 uint32_t * result_recent,
300 uint32_t * result_unseen)
301{
302 uint32_t count;
303 int r;
304
305 r = pop3driver_messages_number(session, mb, &count);
306 if (r != MAIL_NO_ERROR)
307 return r;
308
309 * result_messages = count;
310 * result_recent = count;
311 * result_unseen = count;
312
313 return MAIL_NO_ERROR;
314}
315
316static int pop3driver_messages_number(mailsession * session, char * mb,
317 uint32_t * result)
318{
319 carray * msg_tab;
320
321 mailpop3_list(get_pop3_session(session), &msg_tab);
322
323 * result = carray_count(msg_tab) -
324 get_pop3_session(session)->pop3_deleted_count;
325
326 return MAIL_NO_ERROR;
327}
328
329
330/* messages operations */
331
332static int pop3driver_remove_message(mailsession * session, uint32_t num)
333{
334 mailpop3 * pop3;
335 int r;
336
337 pop3 = get_pop3_session(session);
338
339 r = mailpop3_dele(pop3, num);
340 switch (r) {
341 case MAILPOP3_ERROR_BAD_STATE:
342 return MAIL_ERROR_BAD_STATE;
343
344 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
345 return MAIL_ERROR_MSG_NOT_FOUND;
346
347 case MAILPOP3_ERROR_STREAM:
348 return MAIL_ERROR_STREAM;
349
350 case MAILPOP3_NO_ERROR:
351 return MAIL_NO_ERROR;
352
353 default:
354 return MAIL_ERROR_REMOVE;
355 }
356}
357
358static int pop3driver_get_messages_list(mailsession * session,
359 struct mailmessage_list ** result)
360{
361 mailpop3 * pop3;
362
363 pop3 = get_pop3_session(session);
364
365 return pop3_get_messages_list(pop3, session,
366 pop3_message_driver, result);
367}
368
369static int pop3driver_get_message(mailsession * session,
370 uint32_t num, mailmessage ** result)
371{
372 mailmessage * msg_info;
373 int r;
374
375 msg_info = mailmessage_new();
376 if (msg_info == NULL)
377 return MAIL_ERROR_MEMORY;
378
379 r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0);
380 if (r != MAIL_NO_ERROR) {
381 mailmessage_free(msg_info);
382 return r;
383 }
384
385 * result = msg_info;
386
387 return MAIL_NO_ERROR;
388}
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver.h b/libetpan/src/driver/implementation/pop3/pop3driver.h
new file mode 100644
index 0000000..b70f69e
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef 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/libetpan/src/driver/implementation/pop3/pop3driver_cached.c b/libetpan/src/driver/implementation/pop3/pop3driver_cached.c
new file mode 100644
index 0000000..d3cc98e
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached.c
@@ -0,0 +1,899 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "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 int pop3driver_cached_get_message_by_uid(mailsession * session,
114 const char * uid, mailmessage ** result);
115
116static mailsession_driver local_pop3_cached_session_driver = {
117 .sess_name = "pop3-cached",
118
119 .sess_initialize = pop3driver_cached_initialize,
120 .sess_uninitialize = pop3driver_cached_uninitialize,
121
122 .sess_parameters = pop3driver_cached_parameters,
123
124 .sess_connect_stream = pop3driver_cached_connect_stream,
125 .sess_connect_path = NULL,
126 .sess_starttls = pop3driver_cached_starttls,
127 .sess_login = pop3driver_cached_login,
128 .sess_logout = pop3driver_cached_logout,
129 .sess_noop = pop3driver_cached_noop,
130
131 .sess_build_folder_name = NULL,
132 .sess_create_folder = NULL,
133 .sess_delete_folder = NULL,
134 .sess_rename_folder = NULL,
135 .sess_check_folder = pop3driver_cached_check_folder,
136 .sess_examine_folder = NULL,
137 .sess_select_folder = NULL,
138 .sess_expunge_folder = pop3driver_cached_expunge_folder,
139 .sess_status_folder = pop3driver_cached_status_folder,
140 .sess_messages_number = pop3driver_cached_messages_number,
141 .sess_recent_number = pop3driver_cached_recent_number,
142 .sess_unseen_number = pop3driver_cached_unseen_number,
143 .sess_list_folders = NULL,
144 .sess_lsub_folders = NULL,
145 .sess_subscribe_folder = NULL,
146 .sess_unsubscribe_folder = NULL,
147
148 .sess_append_message = NULL,
149 .sess_append_message_flags = NULL,
150 .sess_copy_message = NULL,
151 .sess_move_message = NULL,
152
153 .sess_get_messages_list = pop3driver_cached_get_messages_list,
154 .sess_get_envelopes_list = pop3driver_cached_get_envelopes_list,
155 .sess_remove_message = pop3driver_cached_remove_message,
156#if 0
157 .sess_search_messages = maildriver_generic_search_messages,
158#endif
159
160 .sess_get_message = pop3driver_cached_get_message,
161 .sess_get_message_by_uid = pop3driver_cached_get_message_by_uid,
162};
163
164mailsession_driver * pop3_cached_session_driver =
165&local_pop3_cached_session_driver;
166
167#define ENV_NAME "env.db"
168#define FLAGS_NAME "flags.db"
169
170
171static inline struct pop3_cached_session_state_data *
172get_cached_data(mailsession * session)
173{
174 return session->sess_data;
175}
176
177static inline mailsession * get_ancestor(mailsession * session)
178{
179 return get_cached_data(session)->pop3_ancestor;
180}
181
182static inline struct pop3_session_state_data *
183get_ancestor_data(mailsession * session)
184{
185 return get_ancestor(session)->sess_data;
186}
187
188static inline mailpop3 * get_pop3_session(mailsession * session)
189{
190 return get_ancestor_data(session)->pop3_session;
191}
192
193static int pop3driver_cached_initialize(mailsession * session)
194{
195 struct pop3_cached_session_state_data * data;
196
197 data = malloc(sizeof(* data));
198 if (data == NULL)
199 goto err;
200
201 data->pop3_flags_store = mail_flags_store_new();
202 if (data->pop3_flags_store == NULL)
203 goto free_data;
204
205 data->pop3_ancestor = mailsession_new(pop3_session_driver);
206 if (data->pop3_ancestor == NULL)
207 goto free_store;
208
209 data->pop3_flags_hash = chash_new(128, CHASH_COPYNONE);
210 if (data->pop3_flags_hash == NULL)
211 goto free_session;
212
213 session->sess_data = data;
214
215 return MAIL_NO_ERROR;
216
217 free_session:
218 mailsession_free(data->pop3_ancestor);
219 free_store:
220 mail_flags_store_free(data->pop3_flags_store);
221 free_data:
222 free(data);
223 err:
224 return MAIL_ERROR_MEMORY;
225}
226
227static int pop3_flags_store_process(char * flags_directory,
228 struct mail_flags_store * flags_store)
229{
230 char filename_flags[PATH_MAX];
231 struct mail_cache_db * cache_db_flags;
232 MMAPString * mmapstr;
233 unsigned int i;
234 int r;
235 int res;
236
237 if (carray_count(flags_store->fls_tab) == 0)
238 return MAIL_NO_ERROR;
239
240 snprintf(filename_flags, PATH_MAX, "%s/%s",
241 flags_directory, FLAGS_NAME);
242
243 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
244 if (r < 0) {
245 res = MAIL_ERROR_FILE;
246 goto err;
247 }
248
249 mmapstr = mmap_string_new("");
250 if (mmapstr == NULL) {
251 res = MAIL_ERROR_MEMORY;
252 goto close_db_flags;
253 }
254
255 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
256 mailmessage * msg;
257
258 msg = carray_get(flags_store->fls_tab, i);
259
260 r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
261 msg->msg_uid, msg->msg_flags);
262 }
263
264 mmap_string_free(mmapstr);
265 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
266
267 mail_flags_store_clear(flags_store);
268
269 return MAIL_NO_ERROR;
270
271 close_db_flags:
272 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
273 err:
274 return res;
275}
276
277static void pop3driver_cached_uninitialize(mailsession * session)
278{
279 struct pop3_cached_session_state_data * data;
280
281 data = get_cached_data(session);
282
283 pop3_flags_store_process(data->pop3_flags_directory,
284 data->pop3_flags_store);
285
286 mail_flags_store_free(data->pop3_flags_store);
287
288 chash_free(data->pop3_flags_hash);
289 mailsession_free(data->pop3_ancestor);
290 free(data);
291
292 session->sess_data = data;
293}
294
295static int pop3driver_cached_check_folder(mailsession * session)
296{
297 struct pop3_cached_session_state_data * pop3_data;
298
299 pop3_data = get_cached_data(session);
300
301 pop3_flags_store_process(pop3_data->pop3_flags_directory,
302 pop3_data->pop3_flags_store);
303
304 return MAIL_NO_ERROR;
305}
306
307static int pop3driver_cached_parameters(mailsession * session,
308 int id, void * value)
309{
310 struct pop3_cached_session_state_data * data;
311 int r;
312
313 data = get_cached_data(session);
314
315 switch (id) {
316 case POP3DRIVER_CACHED_SET_CACHE_DIRECTORY:
317 strncpy(data->pop3_cache_directory, value, PATH_MAX);
318 data->pop3_cache_directory[PATH_MAX - 1] = '\0';
319
320 r = generic_cache_create_dir(data->pop3_cache_directory);
321 if (r != MAIL_NO_ERROR)
322 return r;
323
324 return MAIL_NO_ERROR;
325
326 case POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY:
327 strncpy(data->pop3_flags_directory, value, PATH_MAX);
328 data->pop3_flags_directory[PATH_MAX - 1] = '\0';
329
330 r = generic_cache_create_dir(data->pop3_flags_directory);
331 if (r != MAIL_NO_ERROR)
332 return r;
333
334 return MAIL_NO_ERROR;
335
336 default:
337 return mailsession_parameters(data->pop3_ancestor, id, value);
338 }
339}
340
341static int pop3driver_cached_connect_stream(mailsession * session,
342 mailstream * s)
343{
344 int r;
345
346 r = mailsession_connect_stream(get_ancestor(session), s);
347 if (r != MAIL_NO_ERROR)
348 return r;
349
350 return MAIL_NO_ERROR;
351}
352
353static int pop3driver_cached_starttls(mailsession * session)
354{
355 return mailsession_starttls(get_ancestor(session));
356}
357
358
359static int pop3driver_cached_login(mailsession * session,
360 char * userid, char * password)
361{
362 return mailsession_login(get_ancestor(session), userid, password);
363}
364
365static int pop3driver_cached_logout(mailsession * session)
366{
367 struct pop3_cached_session_state_data * cached_data;
368
369 cached_data = get_cached_data(session);
370
371 pop3_flags_store_process(cached_data->pop3_flags_directory,
372 cached_data->pop3_flags_store);
373
374 return mailsession_logout(get_ancestor(session));
375}
376
377static int pop3driver_cached_noop(mailsession * session)
378{
379 return mailsession_noop(get_ancestor(session));
380}
381
382static int pop3driver_cached_expunge_folder(mailsession * session)
383{
384 int res;
385 struct pop3_cached_session_state_data * cached_data;
386 char filename_flags[PATH_MAX];
387 struct mail_cache_db * cache_db_flags;
388 MMAPString * mmapstr;
389 unsigned int i;
390 int r;
391 carray * msg_tab;
392 mailpop3 * pop3;
393
394 pop3 = get_pop3_session(session);
395
396 cached_data = get_cached_data(session);
397
398 pop3_flags_store_process(cached_data->pop3_flags_directory,
399 cached_data->pop3_flags_store);
400
401 snprintf(filename_flags, PATH_MAX, "%s/%s",
402 cached_data->pop3_flags_directory, FLAGS_NAME);
403
404 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
405 if (r < 0) {
406 res = MAIL_ERROR_MEMORY;
407 goto err;
408 }
409
410 mmapstr = mmap_string_new("");
411 if (mmapstr == NULL) {
412 res = MAIL_ERROR_MEMORY;
413 goto close_db_flags;
414 }
415
416 mailpop3_list(pop3, &msg_tab);
417
418 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
419 struct mailpop3_msg_info * pop3_info;
420 struct mail_flags * flags;
421
422 pop3_info = carray_get(msg_tab, i);
423 if (pop3_info == NULL)
424 continue;
425
426 if (pop3_info->msg_deleted)
427 continue;
428
429 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
430 session, pop3_info->msg_index, &flags);
431 if (r != MAIL_NO_ERROR)
432 continue;
433
434 if (flags->fl_flags & MAIL_FLAG_DELETED) {
435 r = mailpop3_dele(pop3, pop3_info->msg_index);
436 }
437
438 mail_flags_free(flags);
439 }
440
441 mmap_string_free(mmapstr);
442 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
443
444 return MAIL_NO_ERROR;
445
446 close_db_flags:
447 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
448 err:
449 return res;
450}
451
452static int pop3driver_cached_status_folder(mailsession * session,
453 char * mb, uint32_t * result_messages, uint32_t * result_recent,
454 uint32_t * result_unseen)
455{
456 int res;
457 struct pop3_cached_session_state_data * cached_data;
458 char filename_flags[PATH_MAX];
459 struct mail_cache_db * cache_db_flags;
460 MMAPString * mmapstr;
461 unsigned int i;
462 int r;
463 carray * msg_tab;
464 mailpop3 * pop3;
465 uint32_t recent;
466 uint32_t unseen;
467
468 recent = 0;
469 unseen = 0;
470
471 pop3 = get_pop3_session(session);
472
473 cached_data = get_cached_data(session);
474
475 pop3_flags_store_process(cached_data->pop3_flags_directory,
476 cached_data->pop3_flags_store);
477
478 snprintf(filename_flags, PATH_MAX, "%s/%s",
479 cached_data->pop3_flags_directory, FLAGS_NAME);
480
481 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
482 if (r < 0) {
483 res = MAIL_ERROR_MEMORY;
484 goto err;
485 }
486
487 mmapstr = mmap_string_new("");
488 if (mmapstr == NULL) {
489 res = MAIL_ERROR_MEMORY;
490 goto close_db_flags;
491 }
492
493 mailpop3_list(pop3, &msg_tab);
494
495 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
496 struct mailpop3_msg_info * pop3_info;
497 struct mail_flags * flags;
498
499 pop3_info = carray_get(msg_tab, i);
500 if (pop3_info == NULL)
501 continue;
502
503 if (pop3_info->msg_deleted)
504 continue;
505
506 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
507 session, pop3_info->msg_index, &flags);
508 if (r != MAIL_NO_ERROR) {
509 recent ++;
510 unseen ++;
511 continue;
512 }
513
514 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
515 recent ++;
516 }
517 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
518 unseen ++;
519 }
520 mail_flags_free(flags);
521
522 }
523
524 mmap_string_free(mmapstr);
525 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
526
527 * result_messages = carray_count(msg_tab) - pop3->pop3_deleted_count;
528 * result_recent = recent;
529 * result_unseen = unseen;
530
531 return MAIL_NO_ERROR;
532
533 close_db_flags:
534 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
535 err:
536 return res;
537}
538
539static int pop3driver_cached_messages_number(mailsession * session,
540 char * mb,
541 uint32_t * result)
542{
543 return mailsession_messages_number(get_ancestor(session), mb, result);
544}
545
546static int pop3driver_cached_recent_number(mailsession * session,
547 char * mb,
548 uint32_t * result)
549{
550 uint32_t messages;
551 uint32_t recent;
552 uint32_t unseen;
553 int r;
554
555 r = pop3driver_cached_status_folder(session, mb,
556 &messages, &recent, &unseen);
557 if (r != MAIL_NO_ERROR)
558 return r;
559
560 * result = recent;
561
562 return MAIL_NO_ERROR;
563}
564
565static int pop3driver_cached_unseen_number(mailsession * session,
566 char * mb,
567 uint32_t * result)
568{
569 uint32_t messages;
570 uint32_t recent;
571 uint32_t unseen;
572 int r;
573
574 r = pop3driver_cached_status_folder(session, mb,
575 &messages, &recent, &unseen);
576 if (r != MAIL_NO_ERROR)
577 return r;
578
579 * result = unseen;
580
581 return MAIL_NO_ERROR;
582}
583
584/* messages operations */
585
586static int pop3driver_cached_remove_message(mailsession * session,
587 uint32_t num)
588{
589 return mailsession_remove_message(get_ancestor(session), num);
590}
591
592static int
593pop3driver_cached_get_messages_list(mailsession * session,
594 struct mailmessage_list ** result)
595{
596 mailpop3 * pop3;
597
598 pop3 = get_pop3_session(session);
599
600 return pop3_get_messages_list(pop3, session,
601 pop3_cached_message_driver, result);
602}
603
604
605static int
606get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
607 mailsession * session, uint32_t num,
608 struct mailimf_fields ** result)
609{
610 int r;
611 char keyname[PATH_MAX];
612 struct mailpop3_msg_info * info;
613 struct mailimf_fields * fields;
614 int res;
615 mailpop3 * pop3;
616
617 pop3 = get_pop3_session(session);
618
619 r = mailpop3_get_msg_info(pop3, num, &info);
620 switch (r) {
621 case MAILPOP3_ERROR_BAD_STATE:
622 return MAIL_ERROR_BAD_STATE;
623 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
624 return MAIL_ERROR_MSG_NOT_FOUND;
625 case MAILPOP3_NO_ERROR:
626 break;
627 default:
628 return MAIL_ERROR_FETCH;
629 }
630
631 snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
632
633 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
634 if (r != MAIL_NO_ERROR) {
635 res = r;
636 goto err;
637 }
638
639 * result = fields;
640
641 return MAIL_NO_ERROR;
642
643 err:
644 return res;
645}
646
647static int
648write_cached_envelope(struct mail_cache_db * cache_db,
649 MMAPString * mmapstr,
650 mailsession * session, uint32_t num,
651 struct mailimf_fields * fields)
652{
653 int r;
654 char keyname[PATH_MAX];
655 int res;
656 struct mailpop3_msg_info * info;
657 mailpop3 * pop3;
658
659 pop3 = get_pop3_session(session);
660
661 r = mailpop3_get_msg_info(pop3, num, &info);
662 switch (r) {
663 case MAILPOP3_ERROR_BAD_STATE:
664 return MAIL_ERROR_BAD_STATE;
665 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
666 return MAIL_ERROR_MSG_NOT_FOUND;
667 case MAILPOP3_NO_ERROR:
668 break;
669 default:
670 return MAIL_ERROR_FETCH;
671 }
672
673 snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
674
675 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
676 if (r != MAIL_NO_ERROR) {
677 res = r;
678 goto err;
679 }
680
681 return MAIL_NO_ERROR;
682
683 err:
684 return res;
685}
686
687static void get_uid_from_filename(char * filename)
688{
689 char * p;
690
691 p = strstr(filename, "-header");
692 if (p != NULL)
693 * p = 0;
694}
695
696static int
697pop3driver_cached_get_envelopes_list(mailsession * session,
698 struct mailmessage_list * env_list)
699{
700 int r;
701 unsigned int i;
702 struct pop3_cached_session_state_data * cached_data;
703 char filename_env[PATH_MAX];
704 char filename_flags[PATH_MAX];
705 struct mail_cache_db * cache_db_env;
706 struct mail_cache_db * cache_db_flags;
707 MMAPString * mmapstr;
708 int res;
709
710 cached_data = get_cached_data(session);
711
712 pop3_flags_store_process(cached_data->pop3_flags_directory,
713 cached_data->pop3_flags_store);
714
715 snprintf(filename_env, PATH_MAX, "%s/%s",
716 cached_data->pop3_cache_directory, ENV_NAME);
717
718 mmapstr = mmap_string_new("");
719 if (mmapstr == NULL) {
720 res = MAIL_ERROR_MEMORY;
721 goto err;
722 }
723
724 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
725 if (r < 0) {
726 res = MAIL_ERROR_MEMORY;
727 goto free_mmapstr;
728 }
729
730 snprintf(filename_flags, PATH_MAX, "%s/%s",
731 cached_data->pop3_flags_directory, FLAGS_NAME);
732
733 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
734 if (r < 0) {
735 res = MAIL_ERROR_MEMORY;
736 goto close_db_env;
737 }
738
739 /* fill with cached */
740
741 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
742 mailmessage * msg;
743 struct mailimf_fields * fields;
744 struct mail_flags * flags;
745
746 msg = carray_get(env_list->msg_tab, i);
747
748 if (msg->msg_fields == NULL) {
749 r = get_cached_envelope(cache_db_env, mmapstr,
750 session, msg->msg_index, &fields);
751 if (r == MAIL_NO_ERROR) {
752 msg->msg_cached = TRUE;
753 msg->msg_fields = fields;
754 }
755 }
756
757 if (msg->msg_flags == NULL) {
758 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
759 session, msg->msg_index, &flags);
760 if (r == MAIL_NO_ERROR) {
761 msg->msg_flags = flags;
762 }
763 }
764 }
765
766 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
767 mail_cache_db_close_unlock(filename_env, cache_db_env);
768
769 r = maildriver_generic_get_envelopes_list(session, env_list);
770
771 if (r != MAIL_NO_ERROR) {
772 res = r;
773 goto free_mmapstr;
774 }
775
776 /* add flags */
777
778 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
779 mailmessage * msg;
780
781 msg = carray_get(env_list->msg_tab, i);
782
783 if (msg->msg_flags == NULL)
784 msg->msg_flags = mail_flags_new_empty();
785 }
786
787 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
788 if (r < 0) {
789 res = MAIL_ERROR_MEMORY;
790 goto free_mmapstr;
791 }
792
793 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
794 if (r < 0) {
795 res = MAIL_ERROR_MEMORY;
796 goto close_db_env;
797 }
798
799 /* must write cache */
800
801 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
802 mailmessage * msg;
803
804 msg = carray_get(env_list->msg_tab, i);
805
806 if (msg->msg_fields != NULL) {
807 if (!msg->msg_cached) {
808 r = write_cached_envelope(cache_db_env, mmapstr,
809 session, msg->msg_index, msg->msg_fields);
810 }
811 }
812
813 if (msg->msg_flags != NULL) {
814 r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
815 msg->msg_uid, msg->msg_flags);
816 }
817 }
818
819 /* flush cache */
820
821 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
822
823 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
824 mail_cache_db_close_unlock(filename_env, cache_db_env);
825 mmap_string_free(mmapstr);
826
827 /* remove cache files */
828
829 maildriver_message_cache_clean_up(cached_data->pop3_cache_directory,
830 env_list, get_uid_from_filename);
831
832 return MAIL_NO_ERROR;
833
834 close_db_env:
835 mail_cache_db_close_unlock(filename_env, cache_db_env);
836 free_mmapstr:
837 mmap_string_free(mmapstr);
838 err:
839 return res;
840}
841
842static int pop3driver_cached_get_message(mailsession * session,
843 uint32_t num, mailmessage ** result)
844{
845 mailmessage * msg_info;
846 int r;
847
848 msg_info = mailmessage_new();
849 if (msg_info == NULL)
850 return MAIL_ERROR_MEMORY;
851
852 r = mailmessage_init(msg_info, session, pop3_cached_message_driver, num, 0);
853 if (r != MAIL_NO_ERROR) {
854 mailmessage_free(msg_info);
855 return r;
856 }
857
858 * result = msg_info;
859
860 return MAIL_NO_ERROR;
861}
862
863static int pop3driver_cached_get_message_by_uid(mailsession * session,
864 const char * uid, mailmessage ** result)
865{
866 mailpop3 * pop3;
867 struct mailpop3_msg_info * msg_info;
868 int found;
869 unsigned int i;
870
871 if (uid == NULL)
872 return MAIL_ERROR_INVAL;
873
874 pop3 = get_pop3_session(session);
875
876 found = 0;
877
878 /* iterate all messages and look for uid */
879 for(i = 0 ; i < carray_count(pop3->pop3_msg_tab) ; i++) {
880 msg_info = carray_get(pop3->pop3_msg_tab, i);
881
882 if (msg_info == NULL)
883 continue;
884
885 if (msg_info->msg_deleted)
886 continue;
887
888 /* uid found, stop looking */
889 if (strcmp(msg_info->msg_uidl, uid) == 0) {
890 found = 1;
891 break;
892 }
893 }
894
895 if (!found)
896 return MAIL_ERROR_MSG_NOT_FOUND;
897
898 return pop3driver_cached_get_message(session, msg_info->msg_index, result);
899}
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_cached.h b/libetpan/src/driver/implementation/pop3/pop3driver_cached.h
new file mode 100644
index 0000000..4f4b6c9
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef 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/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c
new file mode 100644
index 0000000..4eed0db
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.c
@@ -0,0 +1,355 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "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/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h
new file mode 100644
index 0000000..f13cec7
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef 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/libetpan/src/driver/implementation/pop3/pop3driver_message.c b/libetpan/src/driver/implementation/pop3/pop3driver_message.c
new file mode 100644
index 0000000..6ea8979
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_message.c
@@ -0,0 +1,193 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "pop3driver_message.h"
37
38#include "mailmessage_tools.h"
39#include "pop3driver_tools.h"
40#include "pop3driver.h"
41#include "mailpop3.h"
42#include <stdlib.h>
43#include <string.h>
44
45static int pop3_prefetch(mailmessage * msg_info);
46
47static void pop3_prefetch_free(struct generic_message_t * msg);
48
49static int pop3_initialize(mailmessage * msg_info);
50
51static int pop3_fetch_header(mailmessage * msg_info,
52 char ** result,
53 size_t * result_len);
54
55static int pop3_fetch_size(mailmessage * msg_info,
56 size_t * result);
57
58static mailmessage_driver local_pop3_message_driver = {
59 .msg_name = "pop3",
60
61 .msg_initialize = pop3_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 = pop3_fetch_header,
71 .msg_fetch_body = mailmessage_generic_fetch_body,
72 .msg_fetch_size = pop3_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 * pop3_message_driver = &local_pop3_message_driver;
84
85static inline struct pop3_session_state_data *
86get_data(mailsession * session)
87{
88 return session->sess_data;
89}
90
91
92static mailpop3 * get_pop3_session(mailsession * session)
93{
94 return get_data(session)->pop3_session;
95}
96
97
98static int pop3_prefetch(mailmessage * msg_info)
99{
100 char * msg_content;
101 size_t msg_length;
102 struct generic_message_t * msg;
103 int r;
104
105 r = pop3driver_retr(msg_info->msg_session, msg_info->msg_index,
106 &msg_content, &msg_length);
107 if (r != MAIL_NO_ERROR)
108 return r;
109
110 msg = msg_info->msg_data;
111
112 msg->msg_message = msg_content;
113 msg->msg_length = msg_length;
114
115 return MAIL_NO_ERROR;
116}
117
118static void pop3_prefetch_free(struct generic_message_t * msg)
119{
120 if (msg->msg_message != NULL) {
121 mmap_string_unref(msg->msg_message);
122 msg->msg_message = NULL;
123 }
124}
125
126static int pop3_initialize(mailmessage * msg_info)
127{
128 struct generic_message_t * msg;
129 int r;
130 char * uid;
131 struct mailpop3_msg_info * info;
132 mailpop3 * pop3;
133
134 pop3 = get_pop3_session(msg_info->msg_session);
135
136 r = mailpop3_get_msg_info(pop3, msg_info->msg_index, &info);
137 switch (r) {
138 case MAILPOP3_NO_ERROR:
139 break;
140 default:
141 return pop3driver_pop3_error_to_mail_error(r);
142 }
143
144 uid = strdup(info->msg_uidl);
145 if (uid == NULL)
146 return MAIL_ERROR_MEMORY;
147
148 r = mailmessage_generic_initialize(msg_info);
149 if (r != MAIL_NO_ERROR) {
150 free(uid);
151 return r;
152 }
153
154 msg = msg_info->msg_data;
155 msg->msg_prefetch = pop3_prefetch;
156 msg->msg_prefetch_free = pop3_prefetch_free;
157 msg_info->msg_uid = uid;
158
159 return MAIL_NO_ERROR;
160}
161
162
163static int pop3_fetch_header(mailmessage * msg_info,
164 char ** result,
165 size_t * result_len)
166{
167 struct generic_message_t * msg;
168 char * headers;
169 size_t headers_length;
170 int r;
171
172 msg = msg_info->msg_data;
173
174 if (msg->msg_message != NULL)
175 return mailmessage_generic_fetch_header(msg_info,
176 result, result_len);
177
178 r = pop3driver_header(msg_info->msg_session, msg_info->msg_index,
179 &headers, &headers_length);
180 if (r != MAIL_NO_ERROR)
181 return r;
182
183 * result = headers;
184 * result_len = headers_length;
185
186 return MAIL_NO_ERROR;
187}
188
189static int pop3_fetch_size(mailmessage * msg_info,
190 size_t * result)
191{
192 return pop3driver_size(msg_info->msg_session, msg_info->msg_index, result);
193}
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver_message.h b/libetpan/src/driver/implementation/pop3/pop3driver_message.h
new file mode 100644
index 0000000..ad0a01b
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef 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/libetpan/src/driver/implementation/pop3/pop3driver_tools.c b/libetpan/src/driver/implementation/pop3/pop3driver_tools.c
new file mode 100644
index 0000000..73dd22a
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_tools.c
@@ -0,0 +1,344 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "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/libetpan/src/driver/implementation/pop3/pop3driver_tools.h b/libetpan/src/driver/implementation/pop3/pop3driver_tools.h
new file mode 100644
index 0000000..e6413aa
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_tools.h
@@ -0,0 +1,82 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef 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/libetpan/src/driver/implementation/pop3/pop3driver_types.h b/libetpan/src/driver/implementation/pop3/pop3driver_types.h
new file mode 100644
index 0000000..4bb872c
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3driver_types.h
@@ -0,0 +1,153 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef 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/libetpan/src/driver/implementation/pop3/pop3storage.c b/libetpan/src/driver/implementation/pop3/pop3storage.c
new file mode 100644
index 0000000..1cff650
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3storage.c
@@ -0,0 +1,284 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "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(* pop3_storage));
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/libetpan/src/driver/implementation/pop3/pop3storage.h b/libetpan/src/driver/implementation/pop3/pop3storage.h
new file mode 100644
index 0000000..e8cd513
--- a/dev/null
+++ b/libetpan/src/driver/implementation/pop3/pop3storage.h
@@ -0,0 +1,95 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef 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