author | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
commit | 9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf (patch) (unidiff) | |
tree | 2528e6cc740225ca0f47d5ac8ff70f7d3bb10621 /libetpan/src/driver/implementation/mh | |
parent | 9319998f20f03dcc217fbb39656755dc65226276 (diff) | |
download | kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.zip kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.gz kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.bz2 |
Initial revision
Diffstat (limited to 'libetpan/src/driver/implementation/mh') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver.c | 875 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver.h | 52 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_cached.c | 1315 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_cached.h | 52 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_cached_message.c | 338 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_cached_message.h | 52 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_message.c | 213 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_message.h | 52 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_tools.c | 484 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_tools.h | 80 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhdriver_types.h | 100 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhstorage.c | 192 | ||||
-rw-r--r-- | libetpan/src/driver/implementation/mh/mhstorage.h | 67 |
13 files changed, 3872 insertions, 0 deletions
diff --git a/libetpan/src/driver/implementation/mh/mhdriver.c b/libetpan/src/driver/implementation/mh/mhdriver.c new file mode 100644 index 0000000..c44afc9 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver.c | |||
@@ -0,0 +1,875 @@ | |||
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 "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 | |||
55 | static int mhdriver_initialize(mailsession * session); | ||
56 | |||
57 | static void mhdriver_uninitialize(mailsession * session); | ||
58 | |||
59 | static int mhdriver_connect_path(mailsession * session, char * path); | ||
60 | static int mhdriver_logout(mailsession * session); | ||
61 | |||
62 | static int mhdriver_build_folder_name(mailsession * session, char * mb, | ||
63 | char * name, char ** result); | ||
64 | static int mhdriver_create_folder(mailsession * session, char * mb); | ||
65 | |||
66 | static int mhdriver_delete_folder(mailsession * session, char * mb); | ||
67 | |||
68 | static int mhdriver_rename_folder(mailsession * session, char * mb, | ||
69 | char * new_name); | ||
70 | |||
71 | static int mhdriver_select_folder(mailsession * session, char * mb); | ||
72 | |||
73 | static int mhdriver_status_folder(mailsession * session, char * mb, | ||
74 | uint32_t * result_messages, uint32_t * result_recent, | ||
75 | uint32_t * result_unseen); | ||
76 | |||
77 | static int mhdriver_messages_number(mailsession * session, char * mb, | ||
78 | uint32_t * result); | ||
79 | |||
80 | static int mhdriver_list_folders(mailsession * session, char * mb, | ||
81 | struct mail_list ** result); | ||
82 | |||
83 | static int mhdriver_lsub_folders(mailsession * session, char * mb, | ||
84 | struct mail_list ** result); | ||
85 | |||
86 | static int mhdriver_subscribe_folder(mailsession * session, char * mb); | ||
87 | |||
88 | static int mhdriver_unsubscribe_folder(mailsession * session, char * mb); | ||
89 | |||
90 | static int mhdriver_append_message(mailsession * session, | ||
91 | char * message, size_t size); | ||
92 | static int mhdriver_append_message_flags(mailsession * session, | ||
93 | char * message, size_t size, struct mail_flags * flags); | ||
94 | static int mhdriver_copy_message(mailsession * session, | ||
95 | uint32_t num, char * mb); | ||
96 | |||
97 | static int mhdriver_remove_message(mailsession * session, uint32_t num); | ||
98 | |||
99 | static int mhdriver_move_message(mailsession * session, | ||
100 | uint32_t num, char * mb); | ||
101 | |||
102 | static int mhdriver_get_messages_list(mailsession * session, | ||
103 | struct mailmessage_list ** result); | ||
104 | |||
105 | static int mhdriver_get_message(mailsession * session, | ||
106 | uint32_t num, mailmessage ** result); | ||
107 | |||
108 | static int mhdriver_get_message_by_uid(mailsession * session, | ||
109 | const char * uid, | ||
110 | mailmessage ** result); | ||
111 | |||
112 | static mailsession_driver local_mh_session_driver = { | ||
113 | .sess_name = "mh", | ||
114 | |||
115 | .sess_initialize = mhdriver_initialize, | ||
116 | .sess_uninitialize = mhdriver_uninitialize, | ||
117 | |||
118 | .sess_parameters = NULL, | ||
119 | |||
120 | .sess_connect_stream = NULL, | ||
121 | .sess_connect_path = mhdriver_connect_path, | ||
122 | .sess_starttls = NULL, | ||
123 | .sess_login = NULL, | ||
124 | .sess_logout = mhdriver_logout, | ||
125 | .sess_noop = NULL, | ||
126 | |||
127 | .sess_build_folder_name = mhdriver_build_folder_name, | ||
128 | .sess_create_folder = mhdriver_create_folder, | ||
129 | .sess_delete_folder = mhdriver_delete_folder, | ||
130 | .sess_rename_folder = mhdriver_rename_folder, | ||
131 | .sess_check_folder = NULL, | ||
132 | .sess_examine_folder = NULL, | ||
133 | .sess_select_folder = mhdriver_select_folder, | ||
134 | .sess_expunge_folder = NULL, | ||
135 | .sess_status_folder = mhdriver_status_folder, | ||
136 | .sess_messages_number = mhdriver_messages_number, | ||
137 | .sess_recent_number = mhdriver_messages_number, | ||
138 | .sess_unseen_number = mhdriver_messages_number, | ||
139 | .sess_list_folders = mhdriver_list_folders, | ||
140 | .sess_lsub_folders = mhdriver_lsub_folders, | ||
141 | .sess_subscribe_folder = mhdriver_subscribe_folder, | ||
142 | .sess_unsubscribe_folder = mhdriver_unsubscribe_folder, | ||
143 | |||
144 | .sess_append_message = mhdriver_append_message, | ||
145 | .sess_append_message_flags = mhdriver_append_message_flags, | ||
146 | .sess_copy_message = mhdriver_copy_message, | ||
147 | .sess_move_message = mhdriver_move_message, | ||
148 | |||
149 | .sess_get_messages_list = mhdriver_get_messages_list, | ||
150 | .sess_get_envelopes_list = maildriver_generic_get_envelopes_list, | ||
151 | .sess_remove_message = mhdriver_remove_message, | ||
152 | #if 0 | ||
153 | .sess_search_messages = maildriver_generic_search_messages, | ||
154 | #endif | ||
155 | |||
156 | .sess_get_message = mhdriver_get_message, | ||
157 | .sess_get_message_by_uid = mhdriver_get_message_by_uid, | ||
158 | }; | ||
159 | |||
160 | mailsession_driver * mh_session_driver = &local_mh_session_driver; | ||
161 | |||
162 | static inline struct mh_session_state_data * get_data(mailsession * session) | ||
163 | { | ||
164 | return session->sess_data; | ||
165 | } | ||
166 | |||
167 | static inline struct mailmh * get_mh_session(mailsession * session) | ||
168 | { | ||
169 | return get_data(session)->mh_session; | ||
170 | } | ||
171 | |||
172 | static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session) | ||
173 | { | ||
174 | return get_data(session)->mh_cur_folder; | ||
175 | } | ||
176 | |||
177 | static int add_to_list(mailsession * session, char * mb) | ||
178 | { | ||
179 | char * new_mb; | ||
180 | struct mh_session_state_data * data; | ||
181 | int r; | ||
182 | |||
183 | data = get_data(session); | ||
184 | |||
185 | new_mb = strdup(mb); | ||
186 | if (new_mb == NULL) | ||
187 | return -1; | ||
188 | |||
189 | r = clist_append(data->mh_subscribed_list, new_mb); | ||
190 | if (r < 0) { | ||
191 | free(mb); | ||
192 | return -1; | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int remove_from_list(mailsession * session, char * mb) | ||
199 | { | ||
200 | clistiter * cur; | ||
201 | struct mh_session_state_data * data; | ||
202 | |||
203 | data = get_data(session); | ||
204 | |||
205 | for(cur = clist_begin(data->mh_subscribed_list) ; | ||
206 | cur != NULL ; cur = clist_next(cur)) { | ||
207 | char * cur_name; | ||
208 | |||
209 | cur_name = clist_content(cur); | ||
210 | if (strcmp(cur_name, mb) == 0) { | ||
211 | clist_delete(data->mh_subscribed_list, cur); | ||
212 | free(cur_name); | ||
213 | return 0; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | return -1; | ||
218 | } | ||
219 | |||
220 | static int mhdriver_initialize(mailsession * session) | ||
221 | { | ||
222 | struct mh_session_state_data * data; | ||
223 | |||
224 | data = malloc(sizeof(* data)); | ||
225 | if (data == NULL) | ||
226 | goto err; | ||
227 | |||
228 | data->mh_session = NULL; | ||
229 | data->mh_cur_folder = NULL; | ||
230 | |||
231 | data->mh_subscribed_list = clist_new(); | ||
232 | if (data->mh_subscribed_list == NULL) | ||
233 | goto free; | ||
234 | |||
235 | session->sess_data = data; | ||
236 | |||
237 | return MAIL_NO_ERROR; | ||
238 | |||
239 | free: | ||
240 | free(data); | ||
241 | err: | ||
242 | return MAIL_ERROR_MEMORY; | ||
243 | } | ||
244 | |||
245 | static void mhdriver_uninitialize(mailsession * session) | ||
246 | { | ||
247 | struct mh_session_state_data * data; | ||
248 | |||
249 | data = get_data(session); | ||
250 | |||
251 | if (data->mh_session != NULL) | ||
252 | mailmh_free(data->mh_session); | ||
253 | |||
254 | clist_foreach(data->mh_subscribed_list, (clist_func) free, NULL); | ||
255 | clist_free(data->mh_subscribed_list); | ||
256 | |||
257 | free(data); | ||
258 | |||
259 | session->sess_data = NULL; | ||
260 | } | ||
261 | |||
262 | |||
263 | static int mhdriver_connect_path(mailsession * session, char * path) | ||
264 | { | ||
265 | struct mailmh * mh; | ||
266 | |||
267 | if (get_mh_session(session) != NULL) | ||
268 | return MAIL_ERROR_BAD_STATE; | ||
269 | |||
270 | mh = mailmh_new(path); | ||
271 | if (mh == NULL) | ||
272 | return MAIL_ERROR_MEMORY; | ||
273 | |||
274 | get_data(session)->mh_session = mh; | ||
275 | |||
276 | return MAIL_NO_ERROR; | ||
277 | } | ||
278 | |||
279 | static int mhdriver_logout(mailsession * session) | ||
280 | { | ||
281 | struct mailmh * mh; | ||
282 | |||
283 | mh = get_mh_session(session); | ||
284 | |||
285 | if (mh == NULL) | ||
286 | return MAIL_ERROR_BAD_STATE; | ||
287 | |||
288 | mailmh_free(mh); | ||
289 | get_data(session)->mh_session = NULL; | ||
290 | |||
291 | return MAIL_NO_ERROR; | ||
292 | } | ||
293 | |||
294 | /* folders operations */ | ||
295 | |||
296 | static int mhdriver_build_folder_name(mailsession * session, char * mb, | ||
297 | char * name, char ** result) | ||
298 | { | ||
299 | char * folder_name; | ||
300 | |||
301 | folder_name = malloc(strlen(mb) + 2 + strlen(name)); | ||
302 | if (folder_name == NULL) | ||
303 | return MAIL_ERROR_MEMORY; | ||
304 | |||
305 | strcpy(folder_name, mb); | ||
306 | strcat(folder_name, "/"); | ||
307 | strcat(folder_name, name); | ||
308 | |||
309 | * result = folder_name; | ||
310 | |||
311 | return MAIL_NO_ERROR; | ||
312 | } | ||
313 | |||
314 | static int get_parent(mailsession * session, char * mb, | ||
315 | struct mailmh_folder ** result_folder, | ||
316 | char ** result_name) | ||
317 | { | ||
318 | char * name; | ||
319 | size_t length; | ||
320 | int i; | ||
321 | char * parent_name; | ||
322 | struct mailmh_folder * parent; | ||
323 | struct mailmh * mh; | ||
324 | |||
325 | mh = get_mh_session(session); | ||
326 | if (mh == NULL) | ||
327 | return MAIL_ERROR_BAD_STATE; | ||
328 | |||
329 | length = strlen(mb); | ||
330 | for(i = length - 1 ; i >= 0 ; i--) | ||
331 | if (mb[i] == '/') | ||
332 | break; | ||
333 | name = mb + i + 1; | ||
334 | |||
335 | parent_name = malloc(i + 1); | ||
336 | /* strndup(mb, i) */ | ||
337 | if (parent_name == NULL) | ||
338 | return MAIL_ERROR_MEMORY; | ||
339 | |||
340 | strncpy(parent_name, mb, i); | ||
341 | parent_name[i] = '\0'; | ||
342 | |||
343 | parent = mailmh_folder_find(mh->mh_main, parent_name); | ||
344 | free(parent_name); | ||
345 | if (parent == NULL) | ||
346 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
347 | |||
348 | * result_folder = parent; | ||
349 | * result_name = name; | ||
350 | |||
351 | return MAIL_NO_ERROR; | ||
352 | } | ||
353 | |||
354 | static int mhdriver_create_folder(mailsession * session, char * mb) | ||
355 | { | ||
356 | int r; | ||
357 | struct mailmh_folder * parent; | ||
358 | char * name; | ||
359 | |||
360 | r = get_parent(session, mb, &parent, &name); | ||
361 | if (r != MAIL_NO_ERROR) | ||
362 | return r; | ||
363 | |||
364 | r = mailmh_folder_add_subfolder(parent, name); | ||
365 | |||
366 | return mhdriver_mh_error_to_mail_error(r); | ||
367 | } | ||
368 | |||
369 | static int mhdriver_delete_folder(mailsession * session, char * mb) | ||
370 | { | ||
371 | int r; | ||
372 | struct mailmh_folder * folder; | ||
373 | struct mailmh * mh; | ||
374 | |||
375 | mh = get_mh_session(session); | ||
376 | if (mh == NULL) | ||
377 | return MAIL_ERROR_BAD_STATE; | ||
378 | |||
379 | folder = mailmh_folder_find(mh->mh_main, mb); | ||
380 | if (folder == NULL) | ||
381 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
382 | |||
383 | if (get_mh_cur_folder(session) == folder) | ||
384 | get_data(session)->mh_cur_folder = NULL; | ||
385 | |||
386 | r = mailmh_folder_remove_subfolder(folder); | ||
387 | |||
388 | return mhdriver_mh_error_to_mail_error(r); | ||
389 | } | ||
390 | |||
391 | static int mhdriver_rename_folder(mailsession * session, char * mb, | ||
392 | char * new_name) | ||
393 | { | ||
394 | struct mailmh_folder * src_folder; | ||
395 | struct mailmh_folder * dst_folder; | ||
396 | char * name; | ||
397 | struct mailmh * mh; | ||
398 | int r; | ||
399 | |||
400 | r = get_parent(session, new_name, &dst_folder, &name); | ||
401 | if (r != MAIL_NO_ERROR) | ||
402 | return r; | ||
403 | |||
404 | mh = get_mh_session(session); | ||
405 | if (mh == NULL) | ||
406 | return MAIL_ERROR_BAD_STATE; | ||
407 | |||
408 | src_folder = mailmh_folder_find(mh->mh_main, mb); | ||
409 | if (src_folder == NULL) | ||
410 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
411 | |||
412 | if (get_mh_cur_folder(session) == src_folder) | ||
413 | get_data(session)->mh_cur_folder = NULL; | ||
414 | |||
415 | r = mailmh_folder_rename_subfolder(src_folder, dst_folder, name); | ||
416 | |||
417 | return mhdriver_mh_error_to_mail_error(r); | ||
418 | } | ||
419 | |||
420 | static int mhdriver_select_folder(mailsession * session, char * mb) | ||
421 | { | ||
422 | struct mailmh_folder * folder; | ||
423 | struct mailmh * mh; | ||
424 | int r; | ||
425 | |||
426 | mh = get_mh_session(session); | ||
427 | if (mh == NULL) | ||
428 | return MAIL_ERROR_BAD_STATE; | ||
429 | |||
430 | r = mailmh_folder_update(mh->mh_main); | ||
431 | |||
432 | folder = mailmh_folder_find(mh->mh_main, mb); | ||
433 | if (folder == NULL) | ||
434 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
435 | |||
436 | get_data(session)->mh_cur_folder = folder; | ||
437 | r = mailmh_folder_update(folder); | ||
438 | |||
439 | return mhdriver_mh_error_to_mail_error(r); | ||
440 | } | ||
441 | |||
442 | static int mhdriver_status_folder(mailsession * session, char * mb, | ||
443 | uint32_t * result_messages, uint32_t * result_recent, | ||
444 | uint32_t * result_unseen) | ||
445 | { | ||
446 | uint32_t count; | ||
447 | int r; | ||
448 | |||
449 | r = mhdriver_messages_number(session, mb, &count); | ||
450 | if (r != MAIL_NO_ERROR) | ||
451 | return r; | ||
452 | |||
453 | * result_messages = count; | ||
454 | * result_recent = count; | ||
455 | * result_unseen = count; | ||
456 | |||
457 | return MAIL_NO_ERROR; | ||
458 | } | ||
459 | |||
460 | static int mhdriver_messages_number(mailsession * session, char * mb, | ||
461 | uint32_t * result) | ||
462 | { | ||
463 | struct mailmh_folder * folder; | ||
464 | uint32_t count; | ||
465 | struct mailmh * mh; | ||
466 | unsigned int i; | ||
467 | |||
468 | mh = get_mh_session(session); | ||
469 | if (mh == NULL) | ||
470 | return MAIL_ERROR_BAD_STATE; | ||
471 | |||
472 | if (mb != NULL) { | ||
473 | folder = mailmh_folder_find(mh->mh_main, mb); | ||
474 | if (folder == NULL) | ||
475 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
476 | } | ||
477 | else { | ||
478 | folder = get_mh_cur_folder(session); | ||
479 | if (folder == NULL) | ||
480 | return MAIL_ERROR_BAD_STATE; | ||
481 | } | ||
482 | |||
483 | mailmh_folder_update(folder); | ||
484 | count = 0; | ||
485 | for (i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { | ||
486 | struct mailmh_msg_info * msg_info; | ||
487 | |||
488 | msg_info = carray_get(folder->fl_msgs_tab, i); | ||
489 | if (msg_info != NULL) | ||
490 | count ++; | ||
491 | } | ||
492 | |||
493 | * result = count; | ||
494 | |||
495 | return MAIL_NO_ERROR; | ||
496 | } | ||
497 | |||
498 | |||
499 | static int get_list_folders(struct mailmh_folder * folder, clist ** result) | ||
500 | { | ||
501 | unsigned int i; | ||
502 | clist * list; | ||
503 | char * new_filename; | ||
504 | int res; | ||
505 | int r; | ||
506 | |||
507 | list = * result; | ||
508 | |||
509 | new_filename = strdup(folder->fl_filename); | ||
510 | if (new_filename == NULL) { | ||
511 | res = MAIL_ERROR_MEMORY; | ||
512 | goto free; | ||
513 | } | ||
514 | |||
515 | r = mailmh_folder_update(folder); | ||
516 | |||
517 | switch (r) { | ||
518 | case MAILMH_NO_ERROR: | ||
519 | break; | ||
520 | |||
521 | default: | ||
522 | res = mhdriver_mh_error_to_mail_error(r); | ||
523 | goto free; | ||
524 | } | ||
525 | |||
526 | r = clist_append(list, new_filename); | ||
527 | if (r < 0) { | ||
528 | free(new_filename); | ||
529 | res = MAIL_ERROR_MEMORY; | ||
530 | goto free; | ||
531 | } | ||
532 | |||
533 | if (folder->fl_subfolders_tab != NULL) { | ||
534 | for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) { | ||
535 | struct mailmh_folder * subfolder; | ||
536 | |||
537 | subfolder = carray_get(folder->fl_subfolders_tab, i); | ||
538 | |||
539 | r = get_list_folders(subfolder, &list); | ||
540 | if (r != MAIL_NO_ERROR) { | ||
541 | res = MAIL_ERROR_MEMORY; | ||
542 | goto free; | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | |||
547 | * result = list; | ||
548 | |||
549 | return MAIL_NO_ERROR; | ||
550 | |||
551 | free: | ||
552 | clist_foreach(list, (clist_func) free, NULL); | ||
553 | clist_free(list); | ||
554 | return res; | ||
555 | } | ||
556 | |||
557 | |||
558 | static int mhdriver_list_folders(mailsession * session, char * mb, | ||
559 | struct mail_list ** result) | ||
560 | { | ||
561 | clist * list; | ||
562 | int r; | ||
563 | struct mailmh * mh; | ||
564 | struct mail_list * ml; | ||
565 | |||
566 | mh = get_mh_session(session); | ||
567 | |||
568 | if (mh == NULL) | ||
569 | return MAIL_ERROR_BAD_STATE; | ||
570 | |||
571 | list = clist_new(); | ||
572 | if (list == NULL) | ||
573 | return MAIL_ERROR_MEMORY; | ||
574 | |||
575 | r = get_list_folders(mh->mh_main, &list); | ||
576 | if (r != MAIL_NO_ERROR) | ||
577 | return r; | ||
578 | |||
579 | ml = mail_list_new(list); | ||
580 | if (ml == NULL) | ||
581 | goto free; | ||
582 | |||
583 | * result = ml; | ||
584 | |||
585 | return MAIL_NO_ERROR; | ||
586 | |||
587 | free: | ||
588 | clist_foreach(list, (clist_func) free, NULL); | ||
589 | clist_free(list); | ||
590 | return MAIL_ERROR_MEMORY; | ||
591 | } | ||
592 | |||
593 | static int mhdriver_lsub_folders(mailsession * session, char * mb, | ||
594 | struct mail_list ** result) | ||
595 | { | ||
596 | clist * subscribed; | ||
597 | clist * lsub_result; | ||
598 | clistiter * cur; | ||
599 | struct mail_list * lsub; | ||
600 | size_t length; | ||
601 | int r; | ||
602 | |||
603 | length = strlen(mb); | ||
604 | |||
605 | subscribed = get_data(session)->mh_subscribed_list; | ||
606 | |||
607 | lsub_result = clist_new(); | ||
608 | if (lsub_result == NULL) | ||
609 | return MAIL_ERROR_MEMORY; | ||
610 | |||
611 | for(cur = clist_begin(subscribed) ; cur != NULL ; | ||
612 | cur = clist_next(cur)) { | ||
613 | char * cur_mb; | ||
614 | char * new_mb; | ||
615 | |||
616 | cur_mb = clist_content(cur); | ||
617 | |||
618 | if (strncmp(mb, cur_mb, length) == 0) { | ||
619 | new_mb = strdup(cur_mb); | ||
620 | if (new_mb == NULL) | ||
621 | goto free_list; | ||
622 | |||
623 | r = clist_append(lsub_result, new_mb); | ||
624 | if (r < 0) { | ||
625 | free(new_mb); | ||
626 | goto free_list; | ||
627 | } | ||
628 | } | ||
629 | } | ||
630 | |||
631 | lsub = mail_list_new(lsub_result); | ||
632 | if (lsub == NULL) | ||
633 | goto free_list; | ||
634 | |||
635 | * result = lsub; | ||
636 | |||
637 | return MAIL_NO_ERROR; | ||
638 | |||
639 | free_list: | ||
640 | clist_foreach(lsub_result, (clist_func) free, NULL); | ||
641 | clist_free(lsub_result); | ||
642 | return MAIL_ERROR_MEMORY; | ||
643 | } | ||
644 | |||
645 | static int mhdriver_subscribe_folder(mailsession * session, char * mb) | ||
646 | { | ||
647 | int r; | ||
648 | |||
649 | r = add_to_list(session, mb); | ||
650 | if (r < 0) | ||
651 | return MAIL_ERROR_SUBSCRIBE; | ||
652 | |||
653 | return MAIL_NO_ERROR; | ||
654 | } | ||
655 | |||
656 | static int mhdriver_unsubscribe_folder(mailsession * session, char * mb) | ||
657 | { | ||
658 | int r; | ||
659 | |||
660 | r = remove_from_list(session, mb); | ||
661 | if (r < 0) | ||
662 | return MAIL_ERROR_UNSUBSCRIBE; | ||
663 | |||
664 | return MAIL_NO_ERROR; | ||
665 | } | ||
666 | |||
667 | /* messages operations */ | ||
668 | |||
669 | static int mhdriver_append_message(mailsession * session, | ||
670 | char * message, size_t size) | ||
671 | { | ||
672 | int r; | ||
673 | struct mailmh_folder * folder; | ||
674 | |||
675 | folder = get_mh_cur_folder(session); | ||
676 | if (folder == NULL) | ||
677 | return MAIL_ERROR_BAD_STATE; | ||
678 | |||
679 | r = mailmh_folder_add_message(folder, message, size); | ||
680 | |||
681 | switch (r) { | ||
682 | case MAILMH_ERROR_FILE: | ||
683 | return MAIL_ERROR_DISKSPACE; | ||
684 | |||
685 | default: | ||
686 | return mhdriver_mh_error_to_mail_error(r); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | static int mhdriver_append_message_flags(mailsession * session, | ||
691 | char * message, size_t size, struct mail_flags * flags) | ||
692 | { | ||
693 | return mhdriver_append_message(session, message, size); | ||
694 | } | ||
695 | |||
696 | static int mhdriver_copy_message(mailsession * session, | ||
697 | uint32_t num, char * mb) | ||
698 | { | ||
699 | int fd; | ||
700 | int r; | ||
701 | struct mailmh_folder * folder; | ||
702 | struct mailmh * mh; | ||
703 | int res; | ||
704 | |||
705 | mh = get_mh_session(session); | ||
706 | if (mh == NULL) { | ||
707 | res = MAIL_ERROR_BAD_STATE; | ||
708 | goto err; | ||
709 | } | ||
710 | |||
711 | folder = get_mh_cur_folder(session); | ||
712 | if (folder == NULL) { | ||
713 | res = MAIL_ERROR_BAD_STATE; | ||
714 | goto err; | ||
715 | } | ||
716 | |||
717 | r = mailmh_folder_get_message_fd(folder, num, O_RDONLY, &fd); | ||
718 | if (r != MAIL_NO_ERROR) { | ||
719 | res = r; | ||
720 | goto err; | ||
721 | } | ||
722 | |||
723 | folder = mailmh_folder_find(mh->mh_main, mb); | ||
724 | if (folder == NULL) { | ||
725 | res = MAIL_ERROR_FOLDER_NOT_FOUND; | ||
726 | goto close; | ||
727 | } | ||
728 | |||
729 | r = mailmh_folder_add_message_file(folder, fd); | ||
730 | if (r != MAIL_NO_ERROR) { | ||
731 | res = MAIL_ERROR_COPY; | ||
732 | goto close; | ||
733 | } | ||
734 | |||
735 | close(fd); | ||
736 | |||
737 | return MAIL_NO_ERROR; | ||
738 | |||
739 | close: | ||
740 | close(fd); | ||
741 | err: | ||
742 | return res; | ||
743 | } | ||
744 | |||
745 | static int mhdriver_remove_message(mailsession * session, uint32_t num) | ||
746 | { | ||
747 | int r; | ||
748 | struct mailmh_folder * folder; | ||
749 | |||
750 | folder = get_mh_cur_folder(session); | ||
751 | if (folder == NULL) | ||
752 | return MAIL_ERROR_DELETE; | ||
753 | |||
754 | r = mailmh_folder_remove_message(folder, num); | ||
755 | |||
756 | return mhdriver_mh_error_to_mail_error(r); | ||
757 | } | ||
758 | |||
759 | static int mhdriver_move_message(mailsession * session, | ||
760 | uint32_t num, char * mb) | ||
761 | { | ||
762 | int r; | ||
763 | struct mailmh_folder * src_folder; | ||
764 | struct mailmh_folder * dest_folder; | ||
765 | struct mailmh * mh; | ||
766 | |||
767 | mh = get_mh_session(session); | ||
768 | if (mh == NULL) | ||
769 | return MAIL_ERROR_BAD_STATE; | ||
770 | |||
771 | src_folder = get_mh_cur_folder(session); | ||
772 | if (src_folder == NULL) | ||
773 | return MAIL_ERROR_BAD_STATE; | ||
774 | |||
775 | dest_folder = mailmh_folder_find(mh->mh_main, mb); | ||
776 | if (dest_folder == NULL) | ||
777 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
778 | |||
779 | r = mailmh_folder_move_message(dest_folder, src_folder, num); | ||
780 | |||
781 | return mhdriver_mh_error_to_mail_error(r); | ||
782 | } | ||
783 | |||
784 | |||
785 | static int mhdriver_get_messages_list(mailsession * session, | ||
786 | struct mailmessage_list ** result) | ||
787 | { | ||
788 | struct mailmh_folder * folder; | ||
789 | int res; | ||
790 | |||
791 | folder = get_mh_cur_folder(session); | ||
792 | if (folder == NULL) { | ||
793 | res = MAIL_ERROR_BAD_STATE; | ||
794 | goto err; | ||
795 | } | ||
796 | |||
797 | mailmh_folder_update(folder); | ||
798 | return mh_get_messages_list(folder, session, mh_message_driver, result); | ||
799 | |||
800 | err: | ||
801 | return res; | ||
802 | } | ||
803 | |||
804 | static int mhdriver_get_message(mailsession * session, | ||
805 | uint32_t num, mailmessage ** result) | ||
806 | { | ||
807 | mailmessage * msg_info; | ||
808 | int r; | ||
809 | |||
810 | msg_info = mailmessage_new(); | ||
811 | if (msg_info == NULL) | ||
812 | return MAIL_ERROR_MEMORY; | ||
813 | |||
814 | r = mailmessage_init(msg_info, session, mh_message_driver, num, 0); | ||
815 | if (r != MAIL_NO_ERROR) { | ||
816 | mailmessage_free(msg_info); | ||
817 | return r; | ||
818 | } | ||
819 | |||
820 | * result = msg_info; | ||
821 | |||
822 | return MAIL_NO_ERROR; | ||
823 | } | ||
824 | |||
825 | static int mhdriver_get_message_by_uid(mailsession * session, | ||
826 | const char * uid, | ||
827 | mailmessage ** result) | ||
828 | { | ||
829 | uint32_t index; | ||
830 | char *p; | ||
831 | struct mailmh_msg_info * mh_msg_info; | ||
832 | struct mh_session_state_data * mh_data; | ||
833 | chashdatum key; | ||
834 | chashdatum data; | ||
835 | int r; | ||
836 | time_t mtime; | ||
837 | char * mtime_p; | ||
838 | |||
839 | if (uid == NULL) | ||
840 | return MAIL_ERROR_INVAL; | ||
841 | |||
842 | index = strtoul(uid, &p, 10); | ||
843 | if (p == uid || * p != '-') | ||
844 | return MAIL_ERROR_INVAL; | ||
845 | |||
846 | mh_data = session->sess_data; | ||
847 | #if 0 | ||
848 | mh_msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, index); | ||
849 | #endif | ||
850 | key.data = &index; | ||
851 | key.len = sizeof(index); | ||
852 | r = chash_get(mh_data->mh_cur_folder->fl_msgs_hash, &key, &data); | ||
853 | if (r < 0) | ||
854 | return MAIL_ERROR_MSG_NOT_FOUND; | ||
855 | |||
856 | mh_msg_info = data.data; | ||
857 | |||
858 | mtime_p = p + 1; | ||
859 | |||
860 | mtime = strtoul(mtime_p, &p, 10); | ||
861 | if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) { | ||
862 | size_t size; | ||
863 | char *size_p; | ||
864 | |||
865 | size_p = p + 1; | ||
866 | size = strtoul(size_p, &p, 10); | ||
867 | if ((* p == '\0') && (size == mh_msg_info->msg_size)) | ||
868 | return mhdriver_get_message(session, index, result); | ||
869 | } | ||
870 | else if (* p != '-') { | ||
871 | return MAIL_ERROR_INVAL; | ||
872 | } | ||
873 | |||
874 | return MAIL_ERROR_MSG_NOT_FOUND; | ||
875 | } | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver.h b/libetpan/src/driver/implementation/mh/mhdriver.h new file mode 100644 index 0000000..a3f45f5 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver.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 MHDRIVER_H | ||
37 | |||
38 | #define MHDRIVER_H | ||
39 | |||
40 | #include <libetpan/maildriver.h> | ||
41 | |||
42 | #ifdef __cplusplus | ||
43 | extern "C" { | ||
44 | #endif | ||
45 | |||
46 | extern mailsession_driver * mh_session_driver; | ||
47 | |||
48 | #ifdef __cplusplus | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | #endif | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver_cached.c b/libetpan/src/driver/implementation/mh/mhdriver_cached.c new file mode 100644 index 0000000..1e5c28b --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_cached.c | |||
@@ -0,0 +1,1315 @@ | |||
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 "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 | |||
62 | static int mhdriver_cached_initialize(mailsession * session); | ||
63 | |||
64 | static void mhdriver_cached_uninitialize(mailsession * session); | ||
65 | |||
66 | static int mhdriver_cached_parameters(mailsession * session, | ||
67 | int id, void * value); | ||
68 | |||
69 | static int mhdriver_cached_connect_path(mailsession * session, char * path); | ||
70 | static int mhdriver_cached_logout(mailsession * session); | ||
71 | |||
72 | static int mhdriver_cached_build_folder_name(mailsession * session, char * mb, | ||
73 | char * name, char ** result); | ||
74 | static int mhdriver_cached_create_folder(mailsession * session, char * mb); | ||
75 | |||
76 | static int mhdriver_cached_delete_folder(mailsession * session, char * mb); | ||
77 | |||
78 | static int mhdriver_cached_rename_folder(mailsession * session, char * mb, | ||
79 | char * new_name); | ||
80 | |||
81 | static int mhdriver_cached_check_folder(mailsession * session); | ||
82 | |||
83 | static int mhdriver_cached_select_folder(mailsession * session, char * mb); | ||
84 | |||
85 | static int mhdriver_cached_expunge_folder(mailsession * session); | ||
86 | |||
87 | static int mhdriver_cached_status_folder(mailsession * session, char * mb, | ||
88 | uint32_t * result_messages, uint32_t * result_recent, | ||
89 | uint32_t * result_unseen); | ||
90 | |||
91 | static int mhdriver_cached_messages_number(mailsession * session, char * mb, | ||
92 | uint32_t * result); | ||
93 | static int mhdriver_cached_recent_number(mailsession * session, char * mb, | ||
94 | uint32_t * result); | ||
95 | static int mhdriver_cached_unseen_number(mailsession * session, char * mb, | ||
96 | uint32_t * result); | ||
97 | |||
98 | static int mhdriver_cached_list_folders(mailsession * session, char * mb, | ||
99 | struct mail_list ** result); | ||
100 | |||
101 | static int mhdriver_cached_lsub_folders(mailsession * session, char * mb, | ||
102 | struct mail_list ** result); | ||
103 | |||
104 | static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb); | ||
105 | |||
106 | static int mhdriver_cached_unsubscribe_folder(mailsession * session, | ||
107 | char * mb); | ||
108 | |||
109 | static int mhdriver_cached_append_message(mailsession * session, | ||
110 | char * message, size_t size); | ||
111 | static int mhdriver_cached_append_message_flags(mailsession * session, | ||
112 | char * message, size_t size, struct mail_flags * flags); | ||
113 | static int mhdriver_cached_copy_message(mailsession * session, | ||
114 | uint32_t num, char * mb); | ||
115 | |||
116 | static int mhdriver_cached_remove_message(mailsession * session, | ||
117 | uint32_t num); | ||
118 | |||
119 | static int mhdriver_cached_move_message(mailsession * session, | ||
120 | uint32_t num, char * mb); | ||
121 | |||
122 | static int | ||
123 | mhdriver_cached_get_messages_list(mailsession * session, | ||
124 | struct mailmessage_list ** result); | ||
125 | |||
126 | static int | ||
127 | mhdriver_cached_get_envelopes_list(mailsession * session, | ||
128 | struct mailmessage_list * env_list); | ||
129 | |||
130 | static int mhdriver_cached_get_message(mailsession * session, | ||
131 | uint32_t num, mailmessage ** result); | ||
132 | |||
133 | static int mhdriver_cached_get_message_by_uid(mailsession * session, | ||
134 | const char * uid, | ||
135 | mailmessage ** result); | ||
136 | |||
137 | static mailsession_driver local_mh_cached_session_driver = { | ||
138 | .sess_name = "mh-cached", | ||
139 | |||
140 | .sess_initialize = mhdriver_cached_initialize, | ||
141 | .sess_uninitialize = mhdriver_cached_uninitialize, | ||
142 | |||
143 | .sess_parameters = mhdriver_cached_parameters, | ||
144 | |||
145 | .sess_connect_stream = NULL, | ||
146 | .sess_connect_path = mhdriver_cached_connect_path, | ||
147 | .sess_starttls = NULL, | ||
148 | .sess_login = NULL, | ||
149 | .sess_logout = mhdriver_cached_logout, | ||
150 | .sess_noop = NULL, | ||
151 | |||
152 | .sess_build_folder_name = mhdriver_cached_build_folder_name, | ||
153 | .sess_create_folder = mhdriver_cached_create_folder, | ||
154 | .sess_delete_folder = mhdriver_cached_delete_folder, | ||
155 | .sess_rename_folder = mhdriver_cached_rename_folder, | ||
156 | .sess_check_folder = mhdriver_cached_check_folder, | ||
157 | .sess_examine_folder = NULL, | ||
158 | .sess_select_folder = mhdriver_cached_select_folder, | ||
159 | .sess_expunge_folder = mhdriver_cached_expunge_folder, | ||
160 | .sess_status_folder = mhdriver_cached_status_folder, | ||
161 | .sess_messages_number = mhdriver_cached_messages_number, | ||
162 | .sess_recent_number = mhdriver_cached_recent_number, | ||
163 | .sess_unseen_number = mhdriver_cached_unseen_number, | ||
164 | .sess_list_folders = mhdriver_cached_list_folders, | ||
165 | .sess_lsub_folders = mhdriver_cached_lsub_folders, | ||
166 | .sess_subscribe_folder = mhdriver_cached_subscribe_folder, | ||
167 | .sess_unsubscribe_folder = mhdriver_cached_unsubscribe_folder, | ||
168 | |||
169 | .sess_append_message = mhdriver_cached_append_message, | ||
170 | .sess_append_message_flags = mhdriver_cached_append_message_flags, | ||
171 | .sess_copy_message = mhdriver_cached_copy_message, | ||
172 | .sess_move_message = mhdriver_cached_move_message, | ||
173 | |||
174 | .sess_get_messages_list = mhdriver_cached_get_messages_list, | ||
175 | .sess_get_envelopes_list = mhdriver_cached_get_envelopes_list, | ||
176 | .sess_remove_message = mhdriver_cached_remove_message, | ||
177 | #if 0 | ||
178 | .sess_search_messages = maildriver_generic_search_messages, | ||
179 | #endif | ||
180 | |||
181 | .sess_get_message = mhdriver_cached_get_message, | ||
182 | .sess_get_message_by_uid = mhdriver_cached_get_message_by_uid, | ||
183 | }; | ||
184 | |||
185 | mailsession_driver * mh_cached_session_driver = | ||
186 | &local_mh_cached_session_driver; | ||
187 | |||
188 | #define ENV_NAME "env.db" | ||
189 | #define FLAGS_NAME "flags.db" | ||
190 | |||
191 | |||
192 | static inline struct mh_cached_session_state_data * | ||
193 | get_cached_data(mailsession * session) | ||
194 | { | ||
195 | return session->sess_data; | ||
196 | } | ||
197 | |||
198 | static inline mailsession * get_ancestor(mailsession * session) | ||
199 | { | ||
200 | return get_cached_data(session)->mh_ancestor; | ||
201 | } | ||
202 | |||
203 | static inline struct mh_session_state_data * | ||
204 | get_ancestor_data(mailsession * session) | ||
205 | { | ||
206 | return get_ancestor(session)->sess_data; | ||
207 | } | ||
208 | |||
209 | static inline struct mailmh * | ||
210 | get_mh_session(mailsession * session) | ||
211 | { | ||
212 | return get_ancestor_data(session)->mh_session; | ||
213 | } | ||
214 | |||
215 | static inline struct mailmh_folder * | ||
216 | get_mh_cur_folder(mailsession * session) | ||
217 | { | ||
218 | return get_ancestor_data(session)->mh_cur_folder; | ||
219 | } | ||
220 | |||
221 | |||
222 | #define FILENAME_MAX_UID "max-uid" | ||
223 | |||
224 | /* write max uid current value */ | ||
225 | |||
226 | static int write_max_uid_value(mailsession * session) | ||
227 | { | ||
228 | int r; | ||
229 | char filename[PATH_MAX]; | ||
230 | FILE * f; | ||
231 | int res; | ||
232 | struct mh_cached_session_state_data * cached_data; | ||
233 | struct mh_session_state_data * ancestor_data; | ||
234 | int fd; | ||
235 | |||
236 | MMAPString * mmapstr; | ||
237 | size_t cur_token; | ||
238 | |||
239 | cached_data = get_cached_data(session); | ||
240 | ancestor_data = get_ancestor_data(session); | ||
241 | |||
242 | if (cached_data->mh_quoted_mb == NULL) | ||
243 | return MAIL_ERROR_BAD_STATE; | ||
244 | |||
245 | snprintf(filename, PATH_MAX, "%s/%s/%s", | ||
246 | cached_data->mh_cache_directory, | ||
247 | cached_data->mh_quoted_mb, FILENAME_MAX_UID); | ||
248 | |||
249 | fd = creat(filename, S_IRUSR | S_IWUSR); | ||
250 | if (fd < 0) { | ||
251 | res = MAIL_ERROR_FILE; | ||
252 | goto err; | ||
253 | } | ||
254 | |||
255 | f = fdopen(fd, "w"); | ||
256 | if (f == NULL) { | ||
257 | close(fd); | ||
258 | res = MAIL_ERROR_FILE; | ||
259 | goto err; | ||
260 | } | ||
261 | |||
262 | mmapstr = mmap_string_new(""); | ||
263 | if (mmapstr == NULL) { | ||
264 | res = MAIL_ERROR_MEMORY; | ||
265 | goto close; | ||
266 | } | ||
267 | |||
268 | r = mail_serialize_clear(mmapstr, &cur_token); | ||
269 | if (r != MAIL_NO_ERROR) { | ||
270 | res = r; | ||
271 | goto free_mmapstr; | ||
272 | } | ||
273 | |||
274 | r = mailimf_cache_int_write(mmapstr, &cur_token, | ||
275 | ancestor_data->mh_cur_folder->fl_max_index); | ||
276 | if (r != MAIL_NO_ERROR) { | ||
277 | res = r; | ||
278 | goto free_mmapstr; | ||
279 | } | ||
280 | |||
281 | fwrite(mmapstr->str, 1, mmapstr->len, f); | ||
282 | |||
283 | mmap_string_free(mmapstr); | ||
284 | fclose(f); | ||
285 | |||
286 | return MAIL_NO_ERROR; | ||
287 | |||
288 | free_mmapstr: | ||
289 | mmap_string_free(mmapstr); | ||
290 | close: | ||
291 | fclose(f); | ||
292 | err: | ||
293 | return res; | ||
294 | } | ||
295 | |||
296 | static int read_max_uid_value(mailsession * session) | ||
297 | { | ||
298 | int r; | ||
299 | char filename[PATH_MAX]; | ||
300 | FILE * f; | ||
301 | uint32_t written_uid; | ||
302 | int res; | ||
303 | struct mh_cached_session_state_data * cached_data; | ||
304 | struct mh_session_state_data * ancestor_data; | ||
305 | |||
306 | MMAPString * mmapstr; | ||
307 | size_t cur_token; | ||
308 | char buf[sizeof(uint32_t)]; | ||
309 | size_t read_size; | ||
310 | |||
311 | cached_data = get_cached_data(session); | ||
312 | ancestor_data = get_ancestor_data(session); | ||
313 | |||
314 | snprintf(filename, PATH_MAX, "%s/%s/%s", | ||
315 | cached_data->mh_cache_directory, | ||
316 | cached_data->mh_quoted_mb, FILENAME_MAX_UID); | ||
317 | |||
318 | f = fopen(filename, "r"); | ||
319 | if (f == NULL) { | ||
320 | res = MAIL_ERROR_FILE; | ||
321 | goto err; | ||
322 | } | ||
323 | |||
324 | read_size = fread(buf, 1, sizeof(uint32_t), f); | ||
325 | |||
326 | mmapstr = mmap_string_new_len(buf, read_size); | ||
327 | if (mmapstr == NULL) { | ||
328 | res = MAIL_ERROR_MEMORY; | ||
329 | goto close; | ||
330 | } | ||
331 | |||
332 | cur_token = 0; | ||
333 | |||
334 | r = mailimf_cache_int_read(mmapstr, &cur_token, &written_uid); | ||
335 | if (r != MAIL_NO_ERROR) { | ||
336 | fclose(f); | ||
337 | res = r; | ||
338 | goto free_mmapstr; | ||
339 | } | ||
340 | |||
341 | mmap_string_free(mmapstr); | ||
342 | fclose(f); | ||
343 | |||
344 | if (written_uid > ancestor_data->mh_cur_folder->fl_max_index) | ||
345 | ancestor_data->mh_cur_folder->fl_max_index = written_uid; | ||
346 | |||
347 | return MAIL_NO_ERROR; | ||
348 | |||
349 | free_mmapstr: | ||
350 | mmap_string_free(mmapstr); | ||
351 | close: | ||
352 | fclose(f); | ||
353 | err: | ||
354 | return res; | ||
355 | } | ||
356 | |||
357 | |||
358 | static int mhdriver_cached_initialize(mailsession * session) | ||
359 | { | ||
360 | struct mh_cached_session_state_data * data; | ||
361 | |||
362 | data = malloc(sizeof(* data)); | ||
363 | if (data == NULL) | ||
364 | goto err; | ||
365 | |||
366 | data->mh_flags_store = mail_flags_store_new(); | ||
367 | if (data->mh_flags_store == NULL) | ||
368 | goto free; | ||
369 | |||
370 | data->mh_ancestor = mailsession_new(mh_session_driver); | ||
371 | if (data->mh_ancestor == NULL) | ||
372 | goto free_store; | ||
373 | |||
374 | data->mh_quoted_mb = NULL; | ||
375 | |||
376 | session->sess_data = data; | ||
377 | |||
378 | return MAIL_NO_ERROR; | ||
379 | |||
380 | free_store: | ||
381 | mail_flags_store_free(data->mh_flags_store); | ||
382 | free: | ||
383 | free(data); | ||
384 | err: | ||
385 | return MAIL_ERROR_MEMORY; | ||
386 | } | ||
387 | |||
388 | static void free_state(struct mh_cached_session_state_data * mh_data) | ||
389 | { | ||
390 | if (mh_data->mh_quoted_mb) { | ||
391 | free(mh_data->mh_quoted_mb); | ||
392 | mh_data->mh_quoted_mb = NULL; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static int mh_flags_store_process(char * flags_directory, char * quoted_mb, | ||
397 | struct mail_flags_store * flags_store) | ||
398 | { | ||
399 | char filename_flags[PATH_MAX]; | ||
400 | struct mail_cache_db * cache_db_flags; | ||
401 | MMAPString * mmapstr; | ||
402 | unsigned int i; | ||
403 | int r; | ||
404 | int res; | ||
405 | |||
406 | if (carray_count(flags_store->fls_tab) == 0) | ||
407 | return MAIL_NO_ERROR; | ||
408 | |||
409 | if (quoted_mb == NULL) | ||
410 | return MAIL_NO_ERROR; | ||
411 | |||
412 | snprintf(filename_flags, PATH_MAX, "%s/%s/%s", | ||
413 | flags_directory, quoted_mb, FLAGS_NAME); | ||
414 | |||
415 | r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); | ||
416 | if (r < 0) { | ||
417 | res = MAIL_ERROR_FILE; | ||
418 | goto err; | ||
419 | } | ||
420 | |||
421 | mmapstr = mmap_string_new(""); | ||
422 | if (mmapstr == NULL) { | ||
423 | res = MAIL_ERROR_MEMORY; | ||
424 | goto close_db_flags; | ||
425 | } | ||
426 | |||
427 | for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) { | ||
428 | mailmessage * msg; | ||
429 | |||
430 | msg = carray_get(flags_store->fls_tab, i); | ||
431 | |||
432 | r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, | ||
433 | msg->msg_uid, msg->msg_flags); | ||
434 | } | ||
435 | |||
436 | mmap_string_free(mmapstr); | ||
437 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
438 | |||
439 | mail_flags_store_clear(flags_store); | ||
440 | |||
441 | return MAIL_NO_ERROR; | ||
442 | |||
443 | close_db_flags: | ||
444 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
445 | err: | ||
446 | return res; | ||
447 | } | ||
448 | |||
449 | static void mhdriver_cached_uninitialize(mailsession * session) | ||
450 | { | ||
451 | struct mh_cached_session_state_data * data; | ||
452 | |||
453 | data = get_cached_data(session); | ||
454 | |||
455 | mh_flags_store_process(data->mh_flags_directory, data->mh_quoted_mb, | ||
456 | data->mh_flags_store); | ||
457 | |||
458 | mail_flags_store_free(data->mh_flags_store); | ||
459 | |||
460 | free_state(data); | ||
461 | mailsession_free(data->mh_ancestor); | ||
462 | free(data); | ||
463 | |||
464 | session->sess_data = NULL; | ||
465 | } | ||
466 | |||
467 | static int mhdriver_cached_parameters(mailsession * session, | ||
468 | int id, void * value) | ||
469 | { | ||
470 | struct mh_cached_session_state_data * cached_data; | ||
471 | int r; | ||
472 | |||
473 | cached_data = get_cached_data(session); | ||
474 | |||
475 | switch (id) { | ||
476 | case MHDRIVER_CACHED_SET_CACHE_DIRECTORY: | ||
477 | strncpy(cached_data->mh_cache_directory, value, PATH_MAX); | ||
478 | cached_data->mh_cache_directory[PATH_MAX - 1] = '\0'; | ||
479 | |||
480 | r = generic_cache_create_dir(cached_data->mh_cache_directory); | ||
481 | if (r != MAIL_NO_ERROR) | ||
482 | return r; | ||
483 | |||
484 | return MAIL_NO_ERROR; | ||
485 | |||
486 | case MHDRIVER_CACHED_SET_FLAGS_DIRECTORY: | ||
487 | strncpy(cached_data->mh_flags_directory, value, PATH_MAX); | ||
488 | cached_data->mh_flags_directory[PATH_MAX - 1] = '\0'; | ||
489 | |||
490 | r = generic_cache_create_dir(cached_data->mh_flags_directory); | ||
491 | if (r != MAIL_NO_ERROR) | ||
492 | return r; | ||
493 | |||
494 | return MAIL_NO_ERROR; | ||
495 | } | ||
496 | |||
497 | return MAIL_ERROR_INVAL; | ||
498 | } | ||
499 | |||
500 | static int mhdriver_cached_connect_path(mailsession * session, char * path) | ||
501 | { | ||
502 | return mailsession_connect_path(get_ancestor(session), path); | ||
503 | } | ||
504 | |||
505 | static int mhdriver_cached_logout(mailsession * session) | ||
506 | { | ||
507 | int r; | ||
508 | struct mh_cached_session_state_data * cached_data; | ||
509 | |||
510 | r = write_max_uid_value(session); | ||
511 | |||
512 | cached_data = get_cached_data(session); | ||
513 | |||
514 | mh_flags_store_process(cached_data->mh_flags_directory, | ||
515 | cached_data->mh_quoted_mb, | ||
516 | cached_data->mh_flags_store); | ||
517 | |||
518 | return mailsession_logout(get_ancestor(session)); | ||
519 | } | ||
520 | |||
521 | static int mhdriver_cached_check_folder(mailsession * session) | ||
522 | { | ||
523 | struct mh_cached_session_state_data * cached_data; | ||
524 | |||
525 | cached_data = get_cached_data(session); | ||
526 | |||
527 | mh_flags_store_process(cached_data->mh_flags_directory, | ||
528 | cached_data->mh_quoted_mb, | ||
529 | cached_data->mh_flags_store); | ||
530 | |||
531 | return MAIL_NO_ERROR; | ||
532 | } | ||
533 | |||
534 | /* folders operations */ | ||
535 | |||
536 | static int mhdriver_cached_build_folder_name(mailsession * session, char * mb, | ||
537 | char * name, char ** result) | ||
538 | { | ||
539 | return mailsession_build_folder_name(get_ancestor(session), | ||
540 | mb, name, result); | ||
541 | } | ||
542 | |||
543 | static int mhdriver_cached_create_folder(mailsession * session, char * mb) | ||
544 | { | ||
545 | return mailsession_create_folder(get_ancestor(session), mb); | ||
546 | } | ||
547 | |||
548 | static int mhdriver_cached_delete_folder(mailsession * session, char * mb) | ||
549 | { | ||
550 | return mailsession_delete_folder(get_ancestor(session), mb); | ||
551 | } | ||
552 | |||
553 | static int mhdriver_cached_rename_folder(mailsession * session, char * mb, | ||
554 | char * new_name) | ||
555 | { | ||
556 | return mailsession_rename_folder(get_ancestor(session), mb, new_name); | ||
557 | } | ||
558 | |||
559 | static int get_cache_directory(mailsession * session, | ||
560 | char * path, char ** result) | ||
561 | { | ||
562 | char * quoted_mb; | ||
563 | char dirname[PATH_MAX]; | ||
564 | int res; | ||
565 | int r; | ||
566 | struct mh_cached_session_state_data * cached_data; | ||
567 | |||
568 | cached_data = get_cached_data(session); | ||
569 | |||
570 | quoted_mb = maildriver_quote_mailbox(path); | ||
571 | if (quoted_mb == NULL) { | ||
572 | res = MAIL_ERROR_MEMORY; | ||
573 | goto err; | ||
574 | } | ||
575 | |||
576 | snprintf(dirname, PATH_MAX, "%s/%s", | ||
577 | cached_data->mh_cache_directory, quoted_mb); | ||
578 | |||
579 | r = generic_cache_create_dir(dirname); | ||
580 | if (r != MAIL_NO_ERROR) { | ||
581 | res = r; | ||
582 | goto free; | ||
583 | } | ||
584 | |||
585 | snprintf(dirname, PATH_MAX, "%s/%s", | ||
586 | cached_data->mh_flags_directory, quoted_mb); | ||
587 | |||
588 | r = generic_cache_create_dir(dirname); | ||
589 | if (r != MAIL_NO_ERROR) { | ||
590 | res = r; | ||
591 | goto free; | ||
592 | } | ||
593 | |||
594 | * result = quoted_mb; | ||
595 | |||
596 | return MAIL_NO_ERROR; | ||
597 | |||
598 | free: | ||
599 | free(quoted_mb); | ||
600 | err: | ||
601 | return res; | ||
602 | } | ||
603 | |||
604 | static int mhdriver_cached_select_folder(mailsession * session, char * mb) | ||
605 | { | ||
606 | int r; | ||
607 | int res; | ||
608 | char * quoted_mb; | ||
609 | struct mh_cached_session_state_data * cached_data; | ||
610 | |||
611 | cached_data = get_cached_data(session); | ||
612 | |||
613 | mh_flags_store_process(cached_data->mh_flags_directory, | ||
614 | cached_data->mh_quoted_mb, | ||
615 | cached_data->mh_flags_store); | ||
616 | |||
617 | r = get_cache_directory(session, mb, "ed_mb); | ||
618 | if (r != MAIL_NO_ERROR) { | ||
619 | res = r; | ||
620 | goto err; | ||
621 | } | ||
622 | |||
623 | r = mailsession_select_folder(get_ancestor(session), mb); | ||
624 | if (r != MAIL_NO_ERROR) { | ||
625 | res = r; | ||
626 | goto free; | ||
627 | } | ||
628 | |||
629 | r = write_max_uid_value(session); | ||
630 | |||
631 | free_state(cached_data); | ||
632 | cached_data->mh_quoted_mb = quoted_mb; | ||
633 | |||
634 | r = read_max_uid_value(session); | ||
635 | |||
636 | return MAIL_NO_ERROR; | ||
637 | |||
638 | free: | ||
639 | free(quoted_mb); | ||
640 | err: | ||
641 | return res; | ||
642 | } | ||
643 | |||
644 | static int mhdriver_cached_expunge_folder(mailsession * session) | ||
645 | { | ||
646 | struct mailmh_folder * folder; | ||
647 | int res; | ||
648 | char filename_flags[PATH_MAX]; | ||
649 | struct mail_cache_db * cache_db_flags; | ||
650 | MMAPString * mmapstr; | ||
651 | struct mh_cached_session_state_data * cached_data; | ||
652 | unsigned int i; | ||
653 | int r; | ||
654 | |||
655 | cached_data = get_cached_data(session); | ||
656 | if (cached_data->mh_quoted_mb == NULL) { | ||
657 | res = MAIL_ERROR_BAD_STATE; | ||
658 | goto err; | ||
659 | } | ||
660 | |||
661 | mh_flags_store_process(cached_data->mh_flags_directory, | ||
662 | cached_data->mh_quoted_mb, | ||
663 | cached_data->mh_flags_store); | ||
664 | |||
665 | folder = get_mh_cur_folder(session); | ||
666 | if (folder == NULL) { | ||
667 | res = MAIL_ERROR_BAD_STATE; | ||
668 | goto err; | ||
669 | } | ||
670 | |||
671 | snprintf(filename_flags, PATH_MAX, "%s/%s/%s", | ||
672 | cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME); | ||
673 | |||
674 | r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); | ||
675 | if (r < 0) { | ||
676 | res = MAIL_ERROR_FILE; | ||
677 | goto err; | ||
678 | } | ||
679 | |||
680 | mmapstr = mmap_string_new(""); | ||
681 | if (mmapstr == NULL) { | ||
682 | res = MAIL_ERROR_MEMORY; | ||
683 | goto close_db_flags; | ||
684 | } | ||
685 | |||
686 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { | ||
687 | struct mailmh_msg_info * mh_info; | ||
688 | struct mail_flags * flags; | ||
689 | |||
690 | mh_info = carray_get(folder->fl_msgs_tab, i); | ||
691 | if (mh_info == NULL) | ||
692 | continue; | ||
693 | |||
694 | r = mhdriver_get_cached_flags(cache_db_flags, mmapstr, | ||
695 | session, mh_info->msg_index, &flags); | ||
696 | if (r != MAIL_NO_ERROR) | ||
697 | continue; | ||
698 | |||
699 | if (flags->fl_flags & MAIL_FLAG_DELETED) { | ||
700 | r = mailmh_folder_remove_message(folder, mh_info->msg_index); | ||
701 | } | ||
702 | |||
703 | mail_flags_free(flags); | ||
704 | } | ||
705 | |||
706 | mmap_string_free(mmapstr); | ||
707 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
708 | |||
709 | mailmh_folder_update(folder); | ||
710 | |||
711 | return MAIL_NO_ERROR; | ||
712 | |||
713 | close_db_flags: | ||
714 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
715 | err: | ||
716 | return res; | ||
717 | } | ||
718 | |||
719 | |||
720 | static int mhdriver_cached_status_folder(mailsession * session, char * mb, | ||
721 | uint32_t * result_messages, | ||
722 | uint32_t * result_recent, | ||
723 | uint32_t * result_unseen) | ||
724 | { | ||
725 | struct mailmh_folder * folder; | ||
726 | int res; | ||
727 | char filename_flags[PATH_MAX]; | ||
728 | struct mail_cache_db * cache_db_flags; | ||
729 | MMAPString * mmapstr; | ||
730 | struct mh_cached_session_state_data * cached_data; | ||
731 | unsigned int i; | ||
732 | int r; | ||
733 | uint32_t count; | ||
734 | uint32_t recent; | ||
735 | uint32_t unseen; | ||
736 | |||
737 | r = mhdriver_cached_select_folder(session, mb); | ||
738 | if (r != MAIL_NO_ERROR) { | ||
739 | res = r; | ||
740 | goto err; | ||
741 | } | ||
742 | |||
743 | count = 0; | ||
744 | recent = 0; | ||
745 | unseen = 0; | ||
746 | |||
747 | folder = get_mh_cur_folder(session); | ||
748 | if (folder == NULL) { | ||
749 | res = MAIL_ERROR_BAD_STATE; | ||
750 | goto err; | ||
751 | } | ||
752 | |||
753 | cached_data = get_cached_data(session); | ||
754 | if (cached_data->mh_quoted_mb == NULL) { | ||
755 | res = MAIL_ERROR_BAD_STATE; | ||
756 | goto err; | ||
757 | } | ||
758 | |||
759 | snprintf(filename_flags, PATH_MAX, "%s/%s/%s", | ||
760 | cached_data->mh_flags_directory, | ||
761 | cached_data->mh_quoted_mb, FLAGS_NAME); | ||
762 | |||
763 | r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); | ||
764 | if (r < 0) { | ||
765 | res = MAIL_ERROR_FILE; | ||
766 | goto err; | ||
767 | } | ||
768 | |||
769 | mmapstr = mmap_string_new(""); | ||
770 | if (mmapstr == NULL) { | ||
771 | res = MAIL_ERROR_MEMORY; | ||
772 | goto close_db_flags; | ||
773 | } | ||
774 | |||
775 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { | ||
776 | struct mailmh_msg_info * mh_info; | ||
777 | struct mail_flags * flags; | ||
778 | |||
779 | mh_info = carray_get(folder->fl_msgs_tab, i); | ||
780 | if (mh_info == NULL) | ||
781 | continue; | ||
782 | |||
783 | count ++; | ||
784 | |||
785 | r = mhdriver_get_cached_flags(cache_db_flags, mmapstr, | ||
786 | session, mh_info->msg_index, | ||
787 | &flags); | ||
788 | |||
789 | if (r != MAIL_NO_ERROR) { | ||
790 | recent ++; | ||
791 | unseen ++; | ||
792 | continue; | ||
793 | } | ||
794 | |||
795 | if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) { | ||
796 | recent ++; | ||
797 | } | ||
798 | if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { | ||
799 | unseen ++; | ||
800 | } | ||
801 | mail_flags_free(flags); | ||
802 | } | ||
803 | |||
804 | mmap_string_free(mmapstr); | ||
805 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
806 | |||
807 | * result_messages = count; | ||
808 | * result_recent = recent; | ||
809 | * result_unseen = unseen; | ||
810 | |||
811 | return MAIL_NO_ERROR; | ||
812 | |||
813 | close_db_flags: | ||
814 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
815 | err: | ||
816 | return res; | ||
817 | } | ||
818 | |||
819 | static int mhdriver_cached_messages_number(mailsession * session, char * mb, | ||
820 | uint32_t * result) | ||
821 | { | ||
822 | return mailsession_messages_number(get_ancestor(session), mb, result); | ||
823 | } | ||
824 | |||
825 | static int mhdriver_cached_recent_number(mailsession * session, char * mb, | ||
826 | uint32_t * result) | ||
827 | { | ||
828 | uint32_t messages; | ||
829 | uint32_t recent; | ||
830 | uint32_t unseen; | ||
831 | int r; | ||
832 | |||
833 | r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); | ||
834 | if (r != MAIL_NO_ERROR) | ||
835 | return r; | ||
836 | |||
837 | * result = recent; | ||
838 | |||
839 | return MAIL_NO_ERROR; | ||
840 | } | ||
841 | |||
842 | |||
843 | static int mhdriver_cached_unseen_number(mailsession * session, char * mb, | ||
844 | uint32_t * result) | ||
845 | { | ||
846 | uint32_t messages; | ||
847 | uint32_t recent; | ||
848 | uint32_t unseen; | ||
849 | int r; | ||
850 | |||
851 | r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen); | ||
852 | if (r != MAIL_NO_ERROR) | ||
853 | return r; | ||
854 | |||
855 | * result = recent; | ||
856 | |||
857 | return MAIL_NO_ERROR; | ||
858 | } | ||
859 | |||
860 | |||
861 | static int mhdriver_cached_list_folders(mailsession * session, char * mb, | ||
862 | struct mail_list ** result) | ||
863 | { | ||
864 | return mailsession_list_folders(get_ancestor(session), mb, result); | ||
865 | } | ||
866 | |||
867 | static int mhdriver_cached_lsub_folders(mailsession * session, char * mb, | ||
868 | struct mail_list ** result) | ||
869 | { | ||
870 | return mailsession_lsub_folders(get_ancestor(session), mb, result); | ||
871 | } | ||
872 | |||
873 | static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb) | ||
874 | { | ||
875 | return mailsession_subscribe_folder(get_ancestor(session), mb); | ||
876 | } | ||
877 | |||
878 | static int mhdriver_cached_unsubscribe_folder(mailsession * session, | ||
879 | char * mb) | ||
880 | { | ||
881 | return mailsession_unsubscribe_folder(get_ancestor(session), mb); | ||
882 | } | ||
883 | |||
884 | /* messages operations */ | ||
885 | |||
886 | static int mhdriver_cached_append_message(mailsession * session, | ||
887 | char * message, size_t size) | ||
888 | { | ||
889 | return mhdriver_cached_append_message_flags(session, | ||
890 | message, size, NULL); | ||
891 | } | ||
892 | |||
893 | static int mhdriver_cached_append_message_flags(mailsession * session, | ||
894 | char * message, size_t size, struct mail_flags * flags) | ||
895 | { | ||
896 | int r; | ||
897 | struct mailmh_folder * folder; | ||
898 | struct mailmh_msg_info * msg_info; | ||
899 | chashdatum key; | ||
900 | chashdatum value; | ||
901 | uint32_t uid; | ||
902 | struct mh_cached_session_state_data * data; | ||
903 | char filename_flags[PATH_MAX]; | ||
904 | struct mail_cache_db * cache_db_flags; | ||
905 | MMAPString * mmapstr; | ||
906 | char keyname[PATH_MAX]; | ||
907 | |||
908 | folder = get_mh_cur_folder(session); | ||
909 | if (folder == NULL) | ||
910 | return MAIL_ERROR_BAD_STATE; | ||
911 | |||
912 | r = mailmh_folder_add_message_uid(folder, | ||
913 | message, size, &uid); | ||
914 | |||
915 | switch (r) { | ||
916 | case MAILMH_ERROR_FILE: | ||
917 | return MAIL_ERROR_DISKSPACE; | ||
918 | |||
919 | case MAILMH_NO_ERROR: | ||
920 | break; | ||
921 | |||
922 | default: | ||
923 | return mhdriver_mh_error_to_mail_error(r); | ||
924 | } | ||
925 | |||
926 | if (flags == NULL) | ||
927 | goto exit; | ||
928 | |||
929 | key.data = &uid; | ||
930 | key.len = sizeof(uid); | ||
931 | r = chash_get(folder->fl_msgs_hash, &key, &value); | ||
932 | if (r < 0) | ||
933 | return MAIL_ERROR_CACHE_MISS; | ||
934 | |||
935 | msg_info = value.data; | ||
936 | |||
937 | data = get_cached_data(session); | ||
938 | |||
939 | snprintf(filename_flags, PATH_MAX, "%s/%s/%s", | ||
940 | data->mh_flags_directory, data->mh_quoted_mb, FLAGS_NAME); | ||
941 | |||
942 | r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); | ||
943 | if (r < 0) | ||
944 | goto exit; | ||
945 | |||
946 | mmapstr = mmap_string_new(""); | ||
947 | if (mmapstr == NULL) | ||
948 | goto close_db_flags; | ||
949 | |||
950 | snprintf(keyname, PATH_MAX, "%u-%lu-%lu-flags", | ||
951 | uid, (unsigned long) msg_info->msg_mtime, | ||
952 | (unsigned long) msg_info->msg_size); | ||
953 | |||
954 | r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, keyname, flags); | ||
955 | |||
956 | mmap_string_free(mmapstr); | ||
957 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
958 | |||
959 | if (r != MAIL_NO_ERROR) | ||
960 | goto exit; | ||
961 | |||
962 | return MAIL_NO_ERROR; | ||
963 | |||
964 | close_db_flags: | ||
965 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
966 | exit: | ||
967 | return MAIL_NO_ERROR; | ||
968 | } | ||
969 | |||
970 | static int mhdriver_cached_copy_message(mailsession * session, | ||
971 | uint32_t num, char * mb) | ||
972 | { | ||
973 | return mailsession_copy_message(get_ancestor(session), num, mb); | ||
974 | } | ||
975 | |||
976 | static int mhdriver_cached_remove_message(mailsession * session, uint32_t num) | ||
977 | { | ||
978 | return mailsession_remove_message(get_ancestor(session), num); | ||
979 | } | ||
980 | |||
981 | static int mhdriver_cached_move_message(mailsession * session, | ||
982 | uint32_t num, char * mb) | ||
983 | { | ||
984 | return mailsession_move_message(get_ancestor(session), num, mb); | ||
985 | } | ||
986 | |||
987 | static int | ||
988 | mhdriver_cached_get_messages_list(mailsession * session, | ||
989 | struct mailmessage_list ** result) | ||
990 | { | ||
991 | struct mailmh_folder * folder; | ||
992 | int res; | ||
993 | |||
994 | folder = get_mh_cur_folder(session); | ||
995 | if (folder == NULL) { | ||
996 | res = MAIL_ERROR_BAD_STATE; | ||
997 | goto err; | ||
998 | } | ||
999 | |||
1000 | return mh_get_messages_list(folder, session, | ||
1001 | mh_cached_message_driver, result); | ||
1002 | |||
1003 | err: | ||
1004 | return res; | ||
1005 | } | ||
1006 | |||
1007 | |||
1008 | |||
1009 | static int | ||
1010 | get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, | ||
1011 | mailsession * session, uint32_t num, | ||
1012 | struct mailimf_fields ** result) | ||
1013 | { | ||
1014 | int r; | ||
1015 | char keyname[PATH_MAX]; | ||
1016 | struct mailimf_fields * fields; | ||
1017 | int res; | ||
1018 | struct mailmh_folder * folder; | ||
1019 | struct mailmh_msg_info * msg_info; | ||
1020 | chashdatum key; | ||
1021 | chashdatum data; | ||
1022 | |||
1023 | folder = get_mh_cur_folder(session); | ||
1024 | |||
1025 | #if 0 | ||
1026 | msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num); | ||
1027 | if (msg_info == NULL) | ||
1028 | return MAIL_ERROR_CACHE_MISS; | ||
1029 | #endif | ||
1030 | key.data = # | ||
1031 | key.len = sizeof(num); | ||
1032 | r = chash_get(folder->fl_msgs_hash, &key, &data); | ||
1033 | if (r < 0) | ||
1034 | return MAIL_ERROR_CACHE_MISS; | ||
1035 | msg_info = data.data; | ||
1036 | |||
1037 | snprintf(keyname, PATH_MAX, "%u-%lu-%lu-envelope", | ||
1038 | num, (unsigned long) msg_info->msg_mtime, | ||
1039 | (unsigned long) msg_info->msg_size); | ||
1040 | |||
1041 | r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields); | ||
1042 | if (r != MAIL_NO_ERROR) { | ||
1043 | res = r; | ||
1044 | goto err; | ||
1045 | } | ||
1046 | |||
1047 | * result = fields; | ||
1048 | |||
1049 | return MAIL_NO_ERROR; | ||
1050 | |||
1051 | err: | ||
1052 | return res; | ||
1053 | } | ||
1054 | |||
1055 | static int | ||
1056 | write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, | ||
1057 | mailsession * session, uint32_t num, | ||
1058 | struct mailimf_fields * fields) | ||
1059 | { | ||
1060 | int r; | ||
1061 | char keyname[PATH_MAX]; | ||
1062 | int res; | ||
1063 | struct mailmh_folder * folder; | ||
1064 | chashdatum key; | ||
1065 | chashdatum data; | ||
1066 | struct mailmh_msg_info * msg_info; | ||
1067 | |||
1068 | folder = get_mh_cur_folder(session); | ||
1069 | #if 0 | ||
1070 | msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num); | ||
1071 | if (msg_info == NULL) { | ||
1072 | res = MAIL_ERROR_CACHE_MISS; | ||
1073 | goto err; | ||
1074 | } | ||
1075 | #endif | ||
1076 | key.data = # | ||
1077 | key.len = sizeof(num); | ||
1078 | r = chash_get(folder->fl_msgs_hash, &key, &data); | ||
1079 | if (r < 0) | ||
1080 | return MAIL_ERROR_CACHE_MISS; | ||
1081 | msg_info = data.data; | ||
1082 | |||
1083 | snprintf(keyname, PATH_MAX, "%u-%lu-%lu-envelope", | ||
1084 | num, (unsigned long) msg_info->msg_mtime, | ||
1085 | (unsigned long) msg_info->msg_size); | ||
1086 | |||
1087 | r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields); | ||
1088 | if (r != MAIL_NO_ERROR) { | ||
1089 | res = r; | ||
1090 | goto err; | ||
1091 | } | ||
1092 | |||
1093 | return MAIL_NO_ERROR; | ||
1094 | |||
1095 | err: | ||
1096 | return res; | ||
1097 | } | ||
1098 | |||
1099 | static int | ||
1100 | mhdriver_cached_get_envelopes_list(mailsession * session, | ||
1101 | struct mailmessage_list * env_list) | ||
1102 | { | ||
1103 | int r; | ||
1104 | unsigned int i; | ||
1105 | char filename_env[PATH_MAX]; | ||
1106 | char filename_flags[PATH_MAX]; | ||
1107 | struct mail_cache_db * cache_db_env; | ||
1108 | struct mail_cache_db * cache_db_flags; | ||
1109 | MMAPString * mmapstr; | ||
1110 | int res; | ||
1111 | struct mh_cached_session_state_data * cached_data; | ||
1112 | |||
1113 | cached_data = get_cached_data(session); | ||
1114 | if (cached_data->mh_quoted_mb == NULL) { | ||
1115 | res = MAIL_ERROR_BAD_STATE; | ||
1116 | goto err; | ||
1117 | } | ||
1118 | |||
1119 | mh_flags_store_process(cached_data->mh_flags_directory, | ||
1120 | cached_data->mh_quoted_mb, | ||
1121 | cached_data->mh_flags_store); | ||
1122 | |||
1123 | mmapstr = mmap_string_new(""); | ||
1124 | if (mmapstr == NULL) { | ||
1125 | res = MAIL_ERROR_MEMORY; | ||
1126 | goto err; | ||
1127 | } | ||
1128 | |||
1129 | snprintf(filename_env, PATH_MAX, "%s/%s/%s", | ||
1130 | cached_data->mh_cache_directory, | ||
1131 | cached_data->mh_quoted_mb, ENV_NAME); | ||
1132 | |||
1133 | r = mail_cache_db_open_lock(filename_env, &cache_db_env); | ||
1134 | if (r < 0) { | ||
1135 | res = MAIL_ERROR_MEMORY; | ||
1136 | goto free_mmapstr; | ||
1137 | } | ||
1138 | |||
1139 | snprintf(filename_flags, PATH_MAX, "%s/%s/%s", | ||
1140 | cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME); | ||
1141 | |||
1142 | r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); | ||
1143 | if (r < 0) { | ||
1144 | res = MAIL_ERROR_MEMORY; | ||
1145 | goto close_db_env; | ||
1146 | } | ||
1147 | |||
1148 | /* fill with cached */ | ||
1149 | |||
1150 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
1151 | mailmessage * msg; | ||
1152 | struct mailimf_fields * fields; | ||
1153 | struct mail_flags * flags; | ||
1154 | |||
1155 | msg = carray_get(env_list->msg_tab, i); | ||
1156 | |||
1157 | if (msg->msg_fields == NULL) { | ||
1158 | r = get_cached_envelope(cache_db_env, mmapstr, | ||
1159 | msg->msg_session, msg->msg_index, &fields); | ||
1160 | if (r == MAIL_NO_ERROR) { | ||
1161 | msg->msg_cached = TRUE; | ||
1162 | msg->msg_fields = fields; | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | if (msg->msg_flags == NULL) { | ||
1167 | r = mhdriver_get_cached_flags(cache_db_flags, mmapstr, | ||
1168 | session, msg->msg_index, &flags); | ||
1169 | if (r == MAIL_NO_ERROR) { | ||
1170 | msg->msg_flags = flags; | ||
1171 | } | ||
1172 | } | ||
1173 | } | ||
1174 | |||
1175 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
1176 | mail_cache_db_close_unlock(filename_env, cache_db_env); | ||
1177 | |||
1178 | r = mailsession_get_envelopes_list(get_ancestor(session), env_list); | ||
1179 | |||
1180 | if (r != MAIL_NO_ERROR) { | ||
1181 | res = r; | ||
1182 | goto free_mmapstr; | ||
1183 | } | ||
1184 | |||
1185 | r = mail_cache_db_open_lock(filename_env, &cache_db_env); | ||
1186 | if (r < 0) { | ||
1187 | res = MAIL_ERROR_MEMORY; | ||
1188 | goto free_mmapstr; | ||
1189 | } | ||
1190 | |||
1191 | r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); | ||
1192 | if (r < 0) { | ||
1193 | res = MAIL_ERROR_MEMORY; | ||
1194 | goto close_db_env; | ||
1195 | } | ||
1196 | |||
1197 | /* add flags */ | ||
1198 | |||
1199 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
1200 | mailmessage * msg; | ||
1201 | |||
1202 | msg = carray_get(env_list->msg_tab, i); | ||
1203 | |||
1204 | if (msg->msg_flags == NULL) | ||
1205 | msg->msg_flags = mail_flags_new_empty(); | ||
1206 | } | ||
1207 | |||
1208 | /* must write cache */ | ||
1209 | |||
1210 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
1211 | mailmessage * msg; | ||
1212 | |||
1213 | msg = carray_get(env_list->msg_tab, i); | ||
1214 | |||
1215 | if (msg->msg_fields != NULL) { | ||
1216 | if (!msg->msg_cached) { | ||
1217 | r = write_cached_envelope(cache_db_env, mmapstr, | ||
1218 | session, msg->msg_index, msg->msg_fields); | ||
1219 | } | ||
1220 | } | ||
1221 | |||
1222 | if (msg->msg_flags != NULL) { | ||
1223 | r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, | ||
1224 | msg->msg_uid, msg->msg_flags); | ||
1225 | } | ||
1226 | } | ||
1227 | |||
1228 | /* flush cache */ | ||
1229 | |||
1230 | maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list); | ||
1231 | |||
1232 | mail_cache_db_close_unlock(filename_flags, cache_db_flags); | ||
1233 | mail_cache_db_close_unlock(filename_env, cache_db_env); | ||
1234 | |||
1235 | mmap_string_free(mmapstr); | ||
1236 | |||
1237 | return MAIL_NO_ERROR; | ||
1238 | |||
1239 | close_db_env: | ||
1240 | mail_cache_db_close_unlock(filename_env, cache_db_env); | ||
1241 | free_mmapstr: | ||
1242 | mmap_string_free(mmapstr); | ||
1243 | err: | ||
1244 | return res; | ||
1245 | } | ||
1246 | |||
1247 | static int mhdriver_cached_get_message(mailsession * session, | ||
1248 | uint32_t num, mailmessage ** result) | ||
1249 | { | ||
1250 | mailmessage * msg_info; | ||
1251 | int r; | ||
1252 | |||
1253 | msg_info = mailmessage_new(); | ||
1254 | if (msg_info == NULL) | ||
1255 | return MAIL_ERROR_MEMORY; | ||
1256 | |||
1257 | r = mailmessage_init(msg_info, session, mh_cached_message_driver, num, 0); | ||
1258 | if (r != MAIL_NO_ERROR) | ||
1259 | return r; | ||
1260 | |||
1261 | * result = msg_info; | ||
1262 | |||
1263 | return MAIL_NO_ERROR; | ||
1264 | } | ||
1265 | |||
1266 | static int mhdriver_cached_get_message_by_uid(mailsession * session, | ||
1267 | const char * uid, | ||
1268 | mailmessage ** result) | ||
1269 | { | ||
1270 | uint32_t index; | ||
1271 | char *p; | ||
1272 | struct mailmh_msg_info * mh_msg_info; | ||
1273 | struct mailmh_folder * folder; | ||
1274 | time_t mtime; | ||
1275 | char * mtime_p; | ||
1276 | chashdatum key; | ||
1277 | chashdatum data; | ||
1278 | int r; | ||
1279 | |||
1280 | if (uid == NULL) | ||
1281 | return MAIL_ERROR_INVAL; | ||
1282 | |||
1283 | index = strtoul(uid, &p, 10); | ||
1284 | if (p == uid || * p != '-') | ||
1285 | return MAIL_ERROR_INVAL; | ||
1286 | |||
1287 | folder = get_mh_cur_folder(session); | ||
1288 | |||
1289 | mh_msg_info = NULL; | ||
1290 | key.data = &index; | ||
1291 | key.len = sizeof(index); | ||
1292 | r = chash_get(folder->fl_msgs_hash, &key, &data); | ||
1293 | if (r < 0) | ||
1294 | return MAIL_ERROR_MSG_NOT_FOUND; | ||
1295 | |||
1296 | mh_msg_info = data.data; | ||
1297 | |||
1298 | mtime_p = p + 1; | ||
1299 | |||
1300 | mtime = strtoul(mtime_p, &p, 10); | ||
1301 | if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) { | ||
1302 | size_t size; | ||
1303 | char *size_p; | ||
1304 | |||
1305 | size_p = p + 1; | ||
1306 | size = strtoul(size_p, &p, 10); | ||
1307 | if ((* p == '\0') && (size == mh_msg_info->msg_size)) | ||
1308 | return mhdriver_cached_get_message(session, index, result); | ||
1309 | } | ||
1310 | else if (*p != '-') { | ||
1311 | return MAIL_ERROR_INVAL; | ||
1312 | } | ||
1313 | |||
1314 | return MAIL_ERROR_MSG_NOT_FOUND; | ||
1315 | } | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver_cached.h b/libetpan/src/driver/implementation/mh/mhdriver_cached.h new file mode 100644 index 0000000..d2e5803 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_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 MHDRIVER_CACHED_H | ||
37 | |||
38 | #define MHDRIVER_CACHED_H | ||
39 | |||
40 | #include <libetpan/mhdriver_types.h> | ||
41 | |||
42 | #ifdef __cplusplus | ||
43 | extern "C" { | ||
44 | #endif | ||
45 | |||
46 | extern mailsession_driver * mh_cached_session_driver; | ||
47 | |||
48 | #ifdef __cplusplus | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | #endif | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver_cached_message.c b/libetpan/src/driver/implementation/mh/mhdriver_cached_message.c new file mode 100644 index 0000000..a59beea --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_cached_message.c | |||
@@ -0,0 +1,338 @@ | |||
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 "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 | |||
54 | static int mh_prefetch(mailmessage * msg_info); | ||
55 | |||
56 | static void mh_prefetch_free(struct generic_message_t * msg); | ||
57 | |||
58 | static int mh_initialize(mailmessage * msg_info); | ||
59 | |||
60 | static int mh_fetch_size(mailmessage * msg_info, | ||
61 | size_t * result); | ||
62 | |||
63 | static int mh_get_flags(mailmessage * msg_info, | ||
64 | struct mail_flags ** result); | ||
65 | |||
66 | static void mh_uninitialize(mailmessage * msg_info); | ||
67 | |||
68 | static void mh_flush(mailmessage * msg_info); | ||
69 | |||
70 | static void mh_check(mailmessage * msg_info); | ||
71 | |||
72 | static int mh_fetch_header(mailmessage * msg_info, | ||
73 | char ** result, | ||
74 | size_t * result_len); | ||
75 | |||
76 | static 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 | |||
101 | mailmessage_driver * mh_cached_message_driver = | ||
102 | &local_mh_cached_message_driver; | ||
103 | |||
104 | static inline struct mh_cached_session_state_data * | ||
105 | get_cached_session_data(mailmessage * msg) | ||
106 | { | ||
107 | return msg->msg_session->sess_data; | ||
108 | } | ||
109 | |||
110 | static inline mailsession * get_ancestor_session(mailmessage * msg) | ||
111 | { | ||
112 | return get_cached_session_data(msg)->mh_ancestor; | ||
113 | } | ||
114 | |||
115 | static inline struct mh_session_state_data * | ||
116 | get_ancestor_session_data(mailmessage * msg) | ||
117 | { | ||
118 | return get_ancestor_session(msg)->sess_data; | ||
119 | } | ||
120 | |||
121 | static inline struct mailmh * | ||
122 | get_mh_session(mailmessage * msg) | ||
123 | { | ||
124 | return get_ancestor_session_data(msg)->mh_session; | ||
125 | } | ||
126 | |||
127 | static inline struct mailmh_folder * | ||
128 | get_mh_cur_folder(mailmessage * msg) | ||
129 | { | ||
130 | return get_ancestor_session_data(msg)->mh_cur_folder; | ||
131 | } | ||
132 | |||
133 | static 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 | |||
153 | static 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 | |||
161 | static 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-%lu", msg_info->msg_index, | ||
183 | mh_msg_info->msg_mtime, (unsigned long) 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 | |||
202 | static void mh_uninitialize(mailmessage * msg_info) | ||
203 | { | ||
204 | mailmessage_generic_uninitialize(msg_info); | ||
205 | } | ||
206 | |||
207 | |||
208 | #define FLAGS_NAME "flags.db" | ||
209 | |||
210 | static void mh_flush(mailmessage * msg_info) | ||
211 | { | ||
212 | mailmessage_generic_flush(msg_info); | ||
213 | } | ||
214 | |||
215 | static 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 | |||
226 | static 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 | |||
242 | static 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 | |||
314 | static 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/libetpan/src/driver/implementation/mh/mhdriver_cached_message.h b/libetpan/src/driver/implementation/mh/mhdriver_cached_message.h new file mode 100644 index 0000000..f585708 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_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 MHDRIVER_CACHED_MESSAGE_H | ||
37 | |||
38 | #define MHDRIVER_CACHED_MESSAGE_H | ||
39 | |||
40 | #include <libetpan/mhdriver_types.h> | ||
41 | |||
42 | #ifdef __cplusplus | ||
43 | extern "C" { | ||
44 | #endif | ||
45 | |||
46 | extern mailmessage_driver * mh_cached_message_driver; | ||
47 | |||
48 | #ifdef __cplusplus | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | #endif | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver_message.c b/libetpan/src/driver/implementation/mh/mhdriver_message.c new file mode 100644 index 0000000..0e486b4 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_message.c | |||
@@ -0,0 +1,213 @@ | |||
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 "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 | |||
51 | static int mh_prefetch(mailmessage * msg_info); | ||
52 | |||
53 | static void mh_prefetch_free(struct generic_message_t * msg); | ||
54 | |||
55 | static int mh_initialize(mailmessage * msg_info); | ||
56 | |||
57 | static int mh_fetch_size(mailmessage * msg_info, | ||
58 | size_t * result); | ||
59 | |||
60 | static int mh_fetch_header(mailmessage * msg_info, | ||
61 | char ** result, | ||
62 | size_t * result_len); | ||
63 | |||
64 | static 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 | |||
89 | mailmessage_driver * mh_message_driver = &local_mh_message_driver; | ||
90 | |||
91 | static 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 | |||
111 | static 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 | |||
119 | static inline struct mh_session_state_data * get_data(mailmessage * msg) | ||
120 | { | ||
121 | return msg->msg_session->sess_data; | ||
122 | } | ||
123 | |||
124 | static inline struct mailmh_folder * get_mh_cur_folder(mailmessage * msg) | ||
125 | { | ||
126 | return get_data(msg)->mh_cur_folder; | ||
127 | } | ||
128 | |||
129 | static 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-%lu", msg_info->msg_index, | ||
148 | (unsigned long) mh_msg_info->msg_mtime, | ||
149 | (unsigned long) mh_msg_info->msg_size); | ||
150 | uid = strdup(static_uid); | ||
151 | if (uid == NULL) | ||
152 | return MAIL_ERROR_MEMORY; | ||
153 | |||
154 | r = mailmessage_generic_initialize(msg_info); | ||
155 | if (r != MAIL_NO_ERROR) { | ||
156 | free(uid); | ||
157 | return r; | ||
158 | } | ||
159 | |||
160 | msg = msg_info->msg_data; | ||
161 | msg->msg_prefetch = mh_prefetch; | ||
162 | msg->msg_prefetch_free = mh_prefetch_free; | ||
163 | msg_info->msg_uid = uid; | ||
164 | |||
165 | return MAIL_NO_ERROR; | ||
166 | } | ||
167 | |||
168 | |||
169 | static int mh_fetch_size(mailmessage * msg_info, | ||
170 | size_t * result) | ||
171 | { | ||
172 | int r; | ||
173 | size_t size; | ||
174 | |||
175 | r = mhdriver_fetch_size(msg_info->msg_session, msg_info->msg_index, &size); | ||
176 | if (r != MAIL_NO_ERROR) | ||
177 | return r; | ||
178 | |||
179 | * result = size; | ||
180 | |||
181 | return MAIL_NO_ERROR; | ||
182 | } | ||
183 | |||
184 | |||
185 | |||
186 | |||
187 | static int mh_fetch_header(mailmessage * msg_info, | ||
188 | char ** result, | ||
189 | size_t * result_len) | ||
190 | { | ||
191 | struct generic_message_t * msg; | ||
192 | int r; | ||
193 | char * msg_content; | ||
194 | size_t msg_length; | ||
195 | |||
196 | msg = msg_info->msg_data; | ||
197 | if (msg->msg_message != NULL) { | ||
198 | |||
199 | r = mailmessage_generic_fetch_header(msg_info, result, result_len); | ||
200 | return r; | ||
201 | } | ||
202 | else { | ||
203 | r = mhdriver_fetch_header(msg_info->msg_session, msg_info->msg_index, | ||
204 | &msg_content, &msg_length); | ||
205 | if (r != MAIL_NO_ERROR) | ||
206 | return r; | ||
207 | |||
208 | * result = msg_content; | ||
209 | * result_len = msg_length; | ||
210 | |||
211 | return MAIL_NO_ERROR; | ||
212 | } | ||
213 | } | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver_message.h b/libetpan/src/driver/implementation/mh/mhdriver_message.h new file mode 100644 index 0000000..2b11f3e --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_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 MHDRIVER_MESSAGE_H | ||
37 | |||
38 | #define MHDRIVER_MESSAGE_H | ||
39 | |||
40 | #include <libetpan/mhdriver_types.h> | ||
41 | |||
42 | #ifdef __cplusplus | ||
43 | extern "C" { | ||
44 | #endif | ||
45 | |||
46 | extern mailmessage_driver * mh_message_driver; | ||
47 | |||
48 | #ifdef __cplusplus | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | #endif | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver_tools.c b/libetpan/src/driver/implementation/mh/mhdriver_tools.c new file mode 100644 index 0000000..b8bcf03 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_tools.c | |||
@@ -0,0 +1,484 @@ | |||
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 "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 | |||
55 | int 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_ERROR_FOLDER; | ||
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 | |||
85 | static inline struct mh_session_state_data * get_data(mailsession * session) | ||
86 | { | ||
87 | return session->sess_data; | ||
88 | } | ||
89 | |||
90 | static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session) | ||
91 | { | ||
92 | return get_data(session)->mh_cur_folder; | ||
93 | } | ||
94 | |||
95 | static inline struct mh_cached_session_state_data * | ||
96 | cached_get_data(mailsession * session) | ||
97 | { | ||
98 | return session->sess_data; | ||
99 | } | ||
100 | |||
101 | |||
102 | static inline mailsession * cached_get_ancestor(mailsession * session) | ||
103 | { | ||
104 | return cached_get_data(session)->mh_ancestor; | ||
105 | } | ||
106 | |||
107 | static inline struct mh_session_state_data * | ||
108 | cached_get_ancestor_data(mailsession * session) | ||
109 | { | ||
110 | return get_data(cached_get_ancestor(session)); | ||
111 | } | ||
112 | |||
113 | static inline struct mailmh_folder * | ||
114 | cached_get_mh_cur_folder(mailsession * session) | ||
115 | { | ||
116 | return get_mh_cur_folder(cached_get_ancestor(session)); | ||
117 | } | ||
118 | |||
119 | int 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, 5) == 0) { | ||
169 | cur_token += 5; | ||
170 | |||
171 | while (1) { | ||
172 | if (str[cur_token] == '\n') { | ||
173 | cur_token ++; | ||
174 | break; | ||
175 | } | ||
176 | if (cur_token >= size) | ||
177 | break; | ||
178 | cur_token ++; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | mmapstr = mmap_string_new_len(str + cur_token, size - cur_token); | ||
183 | if (mmapstr == NULL) { | ||
184 | res = MAIL_ERROR_MEMORY; | ||
185 | goto unmap; | ||
186 | } | ||
187 | |||
188 | if (mmap_string_ref(mmapstr) != 0) { | ||
189 | res = MAIL_ERROR_MEMORY; | ||
190 | goto free_str; | ||
191 | } | ||
192 | |||
193 | munmap(str, size); | ||
194 | close(fd); | ||
195 | |||
196 | * result = mmapstr->str; | ||
197 | * result_len = mmapstr->len; | ||
198 | |||
199 | return MAIL_NO_ERROR; | ||
200 | |||
201 | free_str: | ||
202 | mmap_string_free(mmapstr); | ||
203 | unmap: | ||
204 | munmap(str, size); | ||
205 | close: | ||
206 | close(fd); | ||
207 | err: | ||
208 | return res; | ||
209 | } | ||
210 | |||
211 | |||
212 | int mhdriver_fetch_header(mailsession * session, uint32_t index, | ||
213 | char ** result, size_t * result_len) | ||
214 | { | ||
215 | size_t size; | ||
216 | size_t cur_token; | ||
217 | size_t begin; | ||
218 | struct mailmh_folder * folder; | ||
219 | int fd; | ||
220 | MMAPString * mmapstr; | ||
221 | char * str; | ||
222 | int res; | ||
223 | int r; | ||
224 | |||
225 | folder = get_mh_cur_folder(session); | ||
226 | if (folder == NULL) { | ||
227 | res = MAIL_ERROR_BAD_STATE; | ||
228 | goto err; | ||
229 | } | ||
230 | |||
231 | r = mailmh_folder_get_message_fd(folder, index, O_RDONLY, &fd); | ||
232 | |||
233 | switch (r) { | ||
234 | case MAILMH_NO_ERROR: | ||
235 | break; | ||
236 | |||
237 | default: | ||
238 | res = mhdriver_mh_error_to_mail_error(r); | ||
239 | goto close; | ||
240 | } | ||
241 | |||
242 | r = mhdriver_fetch_size(session, index, &size); | ||
243 | |||
244 | switch (r) { | ||
245 | case MAILMH_NO_ERROR: | ||
246 | break; | ||
247 | |||
248 | default: | ||
249 | res = mhdriver_mh_error_to_mail_error(r); | ||
250 | goto close; | ||
251 | } | ||
252 | |||
253 | str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); | ||
254 | if (str == MAP_FAILED) { | ||
255 | res = MAIL_ERROR_FETCH; | ||
256 | goto close; | ||
257 | } | ||
258 | |||
259 | /* strip "From " header for broken implementations */ | ||
260 | cur_token = 0; | ||
261 | if (size > 5) { | ||
262 | if (strncmp("From ", str, 5) == 0) { | ||
263 | cur_token += 5; | ||
264 | |||
265 | while (1) { | ||
266 | if (str[cur_token] == '\n') { | ||
267 | cur_token ++; | ||
268 | break; | ||
269 | } | ||
270 | if (cur_token >= size) | ||
271 | break; | ||
272 | cur_token ++; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | |||
277 | begin = cur_token; | ||
278 | |||
279 | while (1) { | ||
280 | r = mailimf_ignore_field_parse(str, size, &cur_token); | ||
281 | if (r == MAILIMF_NO_ERROR) { | ||
282 | /* do nothing */ | ||
283 | } | ||
284 | else | ||
285 | break; | ||
286 | } | ||
287 | mailimf_crlf_parse(str, size, &cur_token); | ||
288 | |||
289 | mmapstr = mmap_string_new_len(str + begin, cur_token - begin); | ||
290 | if (mmapstr == NULL) { | ||
291 | res = MAIL_ERROR_MEMORY; | ||
292 | goto unmap; | ||
293 | } | ||
294 | |||
295 | if (mmap_string_ref(mmapstr) != 0) { | ||
296 | res = MAIL_ERROR_MEMORY; | ||
297 | goto free_str; | ||
298 | } | ||
299 | |||
300 | munmap(str, size); | ||
301 | close(fd); | ||
302 | |||
303 | * result = mmapstr->str; | ||
304 | * result_len = mmapstr->len; | ||
305 | |||
306 | return MAIL_NO_ERROR; | ||
307 | |||
308 | free_str: | ||
309 | mmap_string_free(mmapstr); | ||
310 | unmap: | ||
311 | munmap(str, size); | ||
312 | close: | ||
313 | close(fd); | ||
314 | err: | ||
315 | return res; | ||
316 | } | ||
317 | |||
318 | |||
319 | int mhdriver_fetch_size(mailsession * session, uint32_t index, | ||
320 | size_t * result) | ||
321 | { | ||
322 | struct mailmh_folder * folder; | ||
323 | int r; | ||
324 | struct stat buf; | ||
325 | char * name; | ||
326 | |||
327 | folder = get_mh_cur_folder(session); | ||
328 | if (folder == NULL) | ||
329 | return MAIL_ERROR_FETCH; | ||
330 | |||
331 | r = mailmh_folder_get_message_filename(folder, index, &name); | ||
332 | |||
333 | switch (r) { | ||
334 | case MAILMH_NO_ERROR: | ||
335 | break; | ||
336 | |||
337 | default: | ||
338 | return mhdriver_mh_error_to_mail_error(r); | ||
339 | } | ||
340 | |||
341 | r = stat(name, &buf); | ||
342 | free(name); | ||
343 | if (r == -1) | ||
344 | return MAIL_ERROR_FETCH; | ||
345 | |||
346 | * result = buf.st_size; | ||
347 | |||
348 | return MAIL_NO_ERROR; | ||
349 | } | ||
350 | |||
351 | int | ||
352 | mhdriver_get_cached_flags(struct mail_cache_db * cache_db, | ||
353 | MMAPString * mmapstr, | ||
354 | mailsession * session, | ||
355 | uint32_t num, | ||
356 | struct mail_flags ** result) | ||
357 | { | ||
358 | int r; | ||
359 | char keyname[PATH_MAX]; | ||
360 | struct mail_flags * flags; | ||
361 | int res; | ||
362 | struct mailmh_msg_info * msg_info; | ||
363 | chashdatum key; | ||
364 | chashdatum data; | ||
365 | struct mailmh_folder * folder; | ||
366 | |||
367 | folder = cached_get_mh_cur_folder(session); | ||
368 | #if 0 | ||
369 | msg_info = cinthash_find(mh_data->cur_folder->fl_msgs_hash, num); | ||
370 | if (msg_info == NULL) | ||
371 | return MAIL_ERROR_CACHE_MISS; | ||
372 | #endif | ||
373 | key.data = # | ||
374 | key.len = sizeof(num); | ||
375 | r = chash_get(folder->fl_msgs_hash, &key, &data); | ||
376 | if (r < 0) | ||
377 | return MAIL_ERROR_CACHE_MISS; | ||
378 | msg_info = data.data; | ||
379 | |||
380 | snprintf(keyname, PATH_MAX, "%u-%lu-%lu-flags", | ||
381 | num, (unsigned long) msg_info->msg_mtime, | ||
382 | (unsigned long) msg_info->msg_size); | ||
383 | |||
384 | r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags); | ||
385 | if (r != MAIL_NO_ERROR) { | ||
386 | res = r; | ||
387 | goto err; | ||
388 | } | ||
389 | |||
390 | * result = flags; | ||
391 | |||
392 | return MAIL_NO_ERROR; | ||
393 | |||
394 | err: | ||
395 | return res; | ||
396 | } | ||
397 | |||
398 | int | ||
399 | mhdriver_write_cached_flags(struct mail_cache_db * cache_db, | ||
400 | MMAPString * mmapstr, | ||
401 | char * uid, | ||
402 | struct mail_flags * flags) | ||
403 | { | ||
404 | int r; | ||
405 | char keyname[PATH_MAX]; | ||
406 | int res; | ||
407 | |||
408 | snprintf(keyname, PATH_MAX, "%s-flags", uid); | ||
409 | |||
410 | r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags); | ||
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 | |||
422 | |||
423 | int mh_get_messages_list(struct mailmh_folder * folder, | ||
424 | mailsession * session, mailmessage_driver * driver, | ||
425 | struct mailmessage_list ** result) | ||
426 | { | ||
427 | unsigned int i; | ||
428 | struct mailmessage_list * env_list; | ||
429 | int r; | ||
430 | carray * tab; | ||
431 | int res; | ||
432 | |||
433 | tab = carray_new(128); | ||
434 | if (tab == NULL) { | ||
435 | res = MAIL_ERROR_MEMORY; | ||
436 | goto err; | ||
437 | } | ||
438 | |||
439 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { | ||
440 | struct mailmh_msg_info * mh_info; | ||
441 | mailmessage * msg; | ||
442 | |||
443 | mh_info = carray_get(folder->fl_msgs_tab, i); | ||
444 | if (mh_info == NULL) | ||
445 | continue; | ||
446 | |||
447 | msg = mailmessage_new(); | ||
448 | if (msg == NULL) { | ||
449 | res = MAIL_ERROR_MEMORY; | ||
450 | goto free_list; | ||
451 | } | ||
452 | |||
453 | r = mailmessage_init(msg, session, driver, | ||
454 | mh_info->msg_index, mh_info->msg_size); | ||
455 | if (r != MAIL_NO_ERROR) { | ||
456 | res = r; | ||
457 | goto free_list; | ||
458 | } | ||
459 | |||
460 | r = carray_add(tab, msg, NULL); | ||
461 | if (r < 0) { | ||
462 | mailmessage_free(msg); | ||
463 | res = MAIL_ERROR_MEMORY; | ||
464 | goto free_list; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | env_list = mailmessage_list_new(tab); | ||
469 | if (env_list == NULL) { | ||
470 | res = MAIL_ERROR_MEMORY; | ||
471 | goto free_list; | ||
472 | } | ||
473 | |||
474 | * result = env_list; | ||
475 | |||
476 | return MAIL_NO_ERROR; | ||
477 | |||
478 | free_list: | ||
479 | for(i = 0 ; i < carray_count(tab) ; i ++) | ||
480 | mailmessage_free(carray_get(tab, i)); | ||
481 | carray_free(tab); | ||
482 | err: | ||
483 | return res; | ||
484 | } | ||
diff --git a/libetpan/src/driver/implementation/mh/mhdriver_tools.h b/libetpan/src/driver/implementation/mh/mhdriver_tools.h new file mode 100644 index 0000000..7b8928e --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_tools.h | |||
@@ -0,0 +1,80 @@ | |||
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 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 | ||
45 | extern "C" { | ||
46 | #endif | ||
47 | |||
48 | int mhdriver_mh_error_to_mail_error(int error); | ||
49 | |||
50 | int mhdriver_fetch_message(mailsession * session, uint32_t index, | ||
51 | char ** result, size_t * result_len); | ||
52 | |||
53 | int mhdriver_fetch_header(mailsession * session, uint32_t index, | ||
54 | char ** result, size_t * result_len); | ||
55 | |||
56 | int mhdriver_fetch_size(mailsession * session, uint32_t index, | ||
57 | size_t * result); | ||
58 | |||
59 | int | ||
60 | mhdriver_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 | |||
66 | int | ||
67 | mhdriver_write_cached_flags(struct mail_cache_db * cache_db, | ||
68 | MMAPString * mmapstr, | ||
69 | char * uid, | ||
70 | struct mail_flags * flags); | ||
71 | |||
72 | int 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/libetpan/src/driver/implementation/mh/mhdriver_types.h b/libetpan/src/driver/implementation/mh/mhdriver_types.h new file mode 100644 index 0000000..45afb64 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhdriver_types.h | |||
@@ -0,0 +1,100 @@ | |||
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 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 | ||
49 | extern "C" { | ||
50 | #endif | ||
51 | |||
52 | struct 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 | |||
60 | enum { | ||
61 | MHDRIVER_CACHED_SET_CACHE_DIRECTORY = 1, | ||
62 | MHDRIVER_CACHED_SET_FLAGS_DIRECTORY, | ||
63 | }; | ||
64 | |||
65 | struct 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 | |||
88 | struct 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/libetpan/src/driver/implementation/mh/mhstorage.c b/libetpan/src/driver/implementation/mh/mhstorage.c new file mode 100644 index 0000000..e7fc2f0 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhstorage.c | |||
@@ -0,0 +1,192 @@ | |||
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 "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 | |||
47 | static int mh_mailstorage_connect(struct mailstorage * storage); | ||
48 | static int mh_mailstorage_get_folder_session(struct mailstorage * storage, | ||
49 | char * pathname, mailsession ** result); | ||
50 | static void mh_mailstorage_uninitialize(struct mailstorage * storage); | ||
51 | |||
52 | static 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 | |||
59 | int 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(* mh_storage)); | ||
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 | |||
105 | static 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 | |||
120 | static 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 | |||
180 | static 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/libetpan/src/driver/implementation/mh/mhstorage.h b/libetpan/src/driver/implementation/mh/mhstorage.h new file mode 100644 index 0000000..be86007 --- a/dev/null +++ b/libetpan/src/driver/implementation/mh/mhstorage.h | |||
@@ -0,0 +1,67 @@ | |||
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 MHSTORAGE_H | ||
37 | |||
38 | #define MHSTORAGE_H | ||
39 | |||
40 | #include <libetpan/mhdriver_types.h> | ||
41 | |||
42 | #ifdef __cplusplus | ||
43 | extern "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 | |||
59 | int 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 | ||