author | zautrix <zautrix> | 2004-07-03 16:33:12 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-07-03 16:33:12 (UTC) |
commit | e3b89230f065c48c84b48c88edb6eb088374c487 (patch) (unidiff) | |
tree | 162ea2ef909a6f82ccfcedf45d80d6c821174912 /kmicromail/libetpan/generic/maildriver_tools.c | |
parent | 2dd6ac0b2d24c91d35ce674a6c26351352df2b15 (diff) | |
download | kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.zip kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.gz kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.bz2 |
Initial revision
Diffstat (limited to 'kmicromail/libetpan/generic/maildriver_tools.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | kmicromail/libetpan/generic/maildriver_tools.c | 841 |
1 files changed, 841 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/maildriver_tools.c b/kmicromail/libetpan/generic/maildriver_tools.c new file mode 100644 index 0000000..105fd9f --- a/dev/null +++ b/kmicromail/libetpan/generic/maildriver_tools.c | |||
@@ -0,0 +1,841 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2002 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #include "maildriver_tools.h" | ||
37 | |||
38 | #include "libetpan-config.h" | ||
39 | |||
40 | #include <stdlib.h> | ||
41 | #include <ctype.h> | ||
42 | #include <string.h> | ||
43 | #include <dirent.h> | ||
44 | #include <unistd.h> | ||
45 | |||
46 | #include "maildriver.h" | ||
47 | #include "mailmessage.h" | ||
48 | #include "mailstream.h" | ||
49 | #include "mailmime.h" | ||
50 | #include "mail_cache_db.h" | ||
51 | |||
52 | /* ********************************************************************* */ | ||
53 | /* tools */ | ||
54 | |||
55 | |||
56 | int | ||
57 | maildriver_generic_get_envelopes_list(mailsession * session, | ||
58 | struct mailmessage_list * env_list) | ||
59 | { | ||
60 | int r; | ||
61 | unsigned i; | ||
62 | #if 0 | ||
63 | uint32_t j; | ||
64 | uint32_t last_msg; | ||
65 | |||
66 | last_msg = 0; | ||
67 | #endif | ||
68 | |||
69 | #if 0 | ||
70 | j = 0; | ||
71 | i = 0; | ||
72 | while (i < env_list->tab->len) { | ||
73 | mailmessage * msg; | ||
74 | uint32_t index; | ||
75 | |||
76 | msg = carray_get(env_list->tab, i); | ||
77 | |||
78 | index = msg->index; | ||
79 | |||
80 | if (msg->fields == NULL) { | ||
81 | struct mailimf_fields * fields; | ||
82 | |||
83 | r = mailmessage_fetch_envelope(msg, &fields); | ||
84 | if (r != MAIL_NO_ERROR) { | ||
85 | /* do nothing */ | ||
86 | } | ||
87 | else { | ||
88 | msg->fields = fields; | ||
89 | |||
90 | carray_set(env_list->tab, j, msg); | ||
91 | |||
92 | j ++; | ||
93 | last_msg = i + 1; | ||
94 | } | ||
95 | mailmessage_flush(msg); | ||
96 | } | ||
97 | else { | ||
98 | j ++; | ||
99 | last_msg = i + 1; | ||
100 | } | ||
101 | |||
102 | i ++; | ||
103 | } | ||
104 | |||
105 | for(i = last_msg ; i < env_list->tab->len ; i ++) { | ||
106 | mailmessage_free(carray_get(env_list->tab, i)); | ||
107 | carray_set(env_list->tab, i, NULL); | ||
108 | } | ||
109 | |||
110 | r = carray_set_size(env_list->tab, j); | ||
111 | if (r < 0) | ||
112 | return MAIL_ERROR_MEMORY; | ||
113 | #endif | ||
114 | |||
115 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
116 | mailmessage * msg; | ||
117 | |||
118 | msg = carray_get(env_list->msg_tab, i); | ||
119 | |||
120 | if (msg->msg_fields == NULL) { | ||
121 | struct mailimf_fields * fields; | ||
122 | |||
123 | r = mailmessage_fetch_envelope(msg, &fields); | ||
124 | if (r != MAIL_NO_ERROR) { | ||
125 | /* do nothing */ | ||
126 | } | ||
127 | else { | ||
128 | msg->msg_fields = fields; | ||
129 | } | ||
130 | mailmessage_flush(msg); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | return MAIL_NO_ERROR; | ||
135 | } | ||
136 | |||
137 | |||
138 | #if 0 | ||
139 | static int is_search_header_only(struct mail_search_key * key) | ||
140 | { | ||
141 | clistiter * cur; | ||
142 | int result; | ||
143 | |||
144 | switch (key->type) { | ||
145 | case MAIL_SEARCH_KEY_ANSWERED: | ||
146 | case MAIL_SEARCH_KEY_BCC: | ||
147 | case MAIL_SEARCH_KEY_BEFORE: | ||
148 | case MAIL_SEARCH_KEY_CC: | ||
149 | case MAIL_SEARCH_KEY_DELETED: | ||
150 | case MAIL_SEARCH_KEY_FLAGGED: | ||
151 | case MAIL_SEARCH_KEY_FROM: | ||
152 | case MAIL_SEARCH_KEY_NEW: | ||
153 | case MAIL_SEARCH_KEY_OLD: | ||
154 | case MAIL_SEARCH_KEY_ON: | ||
155 | case MAIL_SEARCH_KEY_RECENT: | ||
156 | case MAIL_SEARCH_KEY_SEEN: | ||
157 | case MAIL_SEARCH_KEY_SINCE: | ||
158 | case MAIL_SEARCH_KEY_SUBJECT: | ||
159 | case MAIL_SEARCH_KEY_TO: | ||
160 | case MAIL_SEARCH_KEY_UNANSWERED: | ||
161 | case MAIL_SEARCH_KEY_UNDELETED: | ||
162 | case MAIL_SEARCH_KEY_UNFLAGGED: | ||
163 | case MAIL_SEARCH_KEY_UNSEEN: | ||
164 | case MAIL_SEARCH_KEY_HEADER: | ||
165 | case MAIL_SEARCH_KEY_LARGER: | ||
166 | case MAIL_SEARCH_KEY_NOT: | ||
167 | case MAIL_SEARCH_KEY_SMALLER: | ||
168 | case MAIL_SEARCH_KEY_ALL: | ||
169 | return TRUE; | ||
170 | |||
171 | case MAIL_SEARCH_KEY_BODY: | ||
172 | case MAIL_SEARCH_KEY_TEXT: | ||
173 | return FALSE; | ||
174 | |||
175 | case MAIL_SEARCH_KEY_OR: | ||
176 | return (is_search_header_only(key->or1) && | ||
177 | is_search_header_only(key->or2)); | ||
178 | |||
179 | case MAIL_SEARCH_KEY_MULTIPLE: | ||
180 | result = TRUE; | ||
181 | for (cur = clist_begin(key->multiple) ; cur != NULL ; | ||
182 | cur = clist_next(cur)) | ||
183 | result = result && is_search_header_only(clist_content(cur)); | ||
184 | return result; | ||
185 | |||
186 | default: | ||
187 | return TRUE; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | static int match_header(struct mailimf_fields * fields, | ||
192 | char * name, char * value) | ||
193 | { | ||
194 | clistiter * cur; | ||
195 | |||
196 | for(cur = clist_begin(fields->list) ; cur != NULL ; | ||
197 | cur = clist_content(cur)) { | ||
198 | struct mailimf_field * field; | ||
199 | struct mailimf_optional_field * opt_field; | ||
200 | |||
201 | field = clist_content(cur); | ||
202 | opt_field = field->optional_field; | ||
203 | if ((char) toupper((unsigned char) opt_field->name[0]) == | ||
204 | (char) toupper((unsigned char) name[0])) { | ||
205 | if (strcasecmp(opt_field->name, name) == 0) | ||
206 | if (strstr(opt_field->value, value) != NULL) | ||
207 | return TRUE; | ||
208 | } | ||
209 | } | ||
210 | return FALSE; | ||
211 | } | ||
212 | |||
213 | static int comp_date(struct mailimf_fields * fields, | ||
214 | struct mailimf_date_time * ref_date) | ||
215 | { | ||
216 | clistiter * cur; | ||
217 | struct mailimf_date_time * date; | ||
218 | int r; | ||
219 | |||
220 | date = NULL; | ||
221 | for(cur = clist_begin(fields->list) ; cur != NULL ; | ||
222 | cur = clist_content(cur)) { | ||
223 | struct mailimf_field * field; | ||
224 | struct mailimf_optional_field * opt_field; | ||
225 | |||
226 | field = clist_content(cur); | ||
227 | opt_field = field->optional_field; | ||
228 | if ((char) toupper((unsigned char) opt_field->name[0]) == 'D') { | ||
229 | if (strcasecmp(opt_field->name, "Date") == 0) { | ||
230 | size_t cur_token; | ||
231 | |||
232 | cur_token = 0; | ||
233 | r = mailimf_date_time_parse(opt_field->value, strlen(opt_field->value), | ||
234 | &cur_token, &date); | ||
235 | if (r == MAILIMF_NO_ERROR) | ||
236 | break; | ||
237 | else if (r == MAILIMF_ERROR_PARSE) { | ||
238 | /* do nothing */ | ||
239 | } | ||
240 | else | ||
241 | break; | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | |||
246 | if (date == NULL) | ||
247 | return 0; | ||
248 | |||
249 | return mailimf_date_time_comp(date, ref_date); | ||
250 | } | ||
251 | |||
252 | static int match_messages(char * message, | ||
253 | size_t size, | ||
254 | struct mailimf_fields * fields, | ||
255 | int32_t flags, | ||
256 | char * charset, | ||
257 | struct mail_search_key * key) | ||
258 | { | ||
259 | clistiter * cur; | ||
260 | size_t length; | ||
261 | size_t cur_token; | ||
262 | int r; | ||
263 | |||
264 | switch (key->type) { | ||
265 | |||
266 | /* flags */ | ||
267 | case MAIL_SEARCH_KEY_ANSWERED: | ||
268 | return ((flags & MAIL_FLAG_ANSWERED) != 0); | ||
269 | |||
270 | case MAIL_SEARCH_KEY_FLAGGED: | ||
271 | return ((flags & MAIL_FLAG_FLAGGED) != 0); | ||
272 | |||
273 | case MAIL_SEARCH_KEY_DELETED: | ||
274 | return ((flags & MAIL_FLAG_DELETED) != 0); | ||
275 | |||
276 | case MAIL_SEARCH_KEY_RECENT: | ||
277 | return ((flags & MAIL_FLAG_NEW) != 0) && | ||
278 | ((flags & MAIL_FLAG_SEEN) == 0); | ||
279 | |||
280 | case MAIL_SEARCH_KEY_SEEN: | ||
281 | return ((flags & MAIL_FLAG_SEEN) != 0); | ||
282 | |||
283 | case MAIL_SEARCH_KEY_NEW: | ||
284 | return ((flags & MAIL_FLAG_NEW) != 0); | ||
285 | |||
286 | case MAIL_SEARCH_KEY_OLD: | ||
287 | return ((flags & MAIL_FLAG_NEW) == 0); | ||
288 | |||
289 | case MAIL_SEARCH_KEY_UNANSWERED: | ||
290 | return ((flags & MAIL_FLAG_ANSWERED) == 0); | ||
291 | |||
292 | case MAIL_SEARCH_KEY_UNDELETED: | ||
293 | return ((flags & MAIL_FLAG_DELETED) == 0); | ||
294 | |||
295 | case MAIL_SEARCH_KEY_UNFLAGGED: | ||
296 | return ((flags & MAIL_FLAG_FLAGGED) == 0); | ||
297 | |||
298 | case MAIL_SEARCH_KEY_UNSEEN: | ||
299 | return ((flags & MAIL_FLAG_SEEN) == 0); | ||
300 | |||
301 | /* headers */ | ||
302 | case MAIL_SEARCH_KEY_BCC: | ||
303 | return match_header(fields, "Bcc", key->bcc); | ||
304 | |||
305 | case MAIL_SEARCH_KEY_CC: | ||
306 | return match_header(fields, "Cc", key->cc); | ||
307 | |||
308 | case MAIL_SEARCH_KEY_FROM: | ||
309 | return match_header(fields, "From", key->from); | ||
310 | |||
311 | case MAIL_SEARCH_KEY_SUBJECT: | ||
312 | return match_header(fields, "Subject", key->subject); | ||
313 | |||
314 | case MAIL_SEARCH_KEY_TO: | ||
315 | return match_header(fields, "To", key->to); | ||
316 | |||
317 | case MAIL_SEARCH_KEY_HEADER: | ||
318 | return match_header(fields, key->header_name, key->header_value); | ||
319 | |||
320 | /* date */ | ||
321 | case MAIL_SEARCH_KEY_BEFORE: | ||
322 | return (comp_date(fields, key->before) <= 0); | ||
323 | |||
324 | case MAIL_SEARCH_KEY_ON: | ||
325 | return (comp_date(fields, key->before) == 0); | ||
326 | |||
327 | case MAIL_SEARCH_KEY_SINCE: | ||
328 | return (comp_date(fields, key->before) >= 0); | ||
329 | |||
330 | /* boolean */ | ||
331 | case MAIL_SEARCH_KEY_NOT: | ||
332 | return (!match_messages(message, size, fields, flags, charset, key->not)); | ||
333 | case MAIL_SEARCH_KEY_OR: | ||
334 | return (match_messages(message, size, fields, flags, charset, key->or1) || | ||
335 | match_messages(message, size, fields, flags, charset, key->or2)); | ||
336 | |||
337 | case MAIL_SEARCH_KEY_MULTIPLE: | ||
338 | for(cur = clist_begin(key->multiple) ; cur != NULL ; | ||
339 | cur = clist_next(cur)) { | ||
340 | if (!match_messages(message, size, fields, flags, charset, | ||
341 | clist_content(cur))) | ||
342 | return FALSE; | ||
343 | } | ||
344 | |||
345 | return TRUE; | ||
346 | |||
347 | /* size */ | ||
348 | case MAIL_SEARCH_KEY_SMALLER: | ||
349 | return (size <= key->smaller); | ||
350 | |||
351 | case MAIL_SEARCH_KEY_LARGER: | ||
352 | return (size >= key->larger); | ||
353 | |||
354 | case MAIL_SEARCH_KEY_BODY: | ||
355 | length = strlen(message); | ||
356 | |||
357 | cur_token = 0; | ||
358 | while (1) { | ||
359 | r = mailimf_ignore_field_parse(message, length, &cur_token); | ||
360 | if (r == MAILIMF_NO_ERROR) { | ||
361 | /* do nothing */ | ||
362 | } | ||
363 | else | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | return (strstr(message + cur_token, key->body) != NULL); | ||
368 | |||
369 | case MAIL_SEARCH_KEY_TEXT: | ||
370 | return (strstr(message, key->body) != NULL); | ||
371 | |||
372 | case MAIL_SEARCH_KEY_ALL: | ||
373 | default: | ||
374 | return TRUE; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | int maildriver_generic_search_messages(mailsession * session, char * charset, | ||
379 | struct mail_search_key * key, | ||
380 | struct mail_search_result ** result) | ||
381 | { | ||
382 | int header; | ||
383 | clist * list; | ||
384 | struct mail_search_result * search_result; | ||
385 | int r; | ||
386 | struct mailmessage_list * env_list; | ||
387 | int res; | ||
388 | unsigned int i; | ||
389 | |||
390 | header = is_search_header_only(key); | ||
391 | |||
392 | r = mailsession_get_messages_list(session, &env_list); | ||
393 | if (r != MAIL_NO_ERROR) | ||
394 | return r; | ||
395 | |||
396 | list = NULL; | ||
397 | for(i = 0 ; i < carray_count(env_list->tab) ; i ++) { | ||
398 | char * message; | ||
399 | size_t length; | ||
400 | struct mail_info * info; | ||
401 | uint32_t flags; | ||
402 | struct mailimf_fields * fields; | ||
403 | size_t cur_token; | ||
404 | |||
405 | info = carray_get(env_list->tab, i); | ||
406 | |||
407 | if (!header) { | ||
408 | r = mailsession_fetch_message(session, info->index, &message, &length); | ||
409 | if (r != MAIL_NO_ERROR) { | ||
410 | res = r; | ||
411 | goto free_list; | ||
412 | } | ||
413 | |||
414 | cur_token = 0; | ||
415 | r = mailimf_optional_fields_parse(message, length, | ||
416 | &cur_token, &fields); | ||
417 | if (r != MAILIMF_NO_ERROR) { | ||
418 | res = MAIL_ERROR_PARSE; | ||
419 | goto free_list; | ||
420 | } | ||
421 | } | ||
422 | else { | ||
423 | char * msg_header; | ||
424 | int r; | ||
425 | size_t cur_token; | ||
426 | size_t header_len; | ||
427 | |||
428 | r = mailsession_fetch_message_header(session, info->index, &msg_header, | ||
429 | &header_len); | ||
430 | if (r != MAIL_NO_ERROR) { | ||
431 | res = r; | ||
432 | goto free_list; | ||
433 | } | ||
434 | |||
435 | message = NULL; | ||
436 | cur_token = 0; | ||
437 | r = mailimf_optional_fields_parse(msg_header, header_len, | ||
438 | &cur_token, &fields); | ||
439 | if (r != MAILIMF_NO_ERROR) { | ||
440 | res = MAIL_ERROR_PARSE; | ||
441 | goto free_list; | ||
442 | } | ||
443 | |||
444 | mailsession_fetch_result_free(session, msg_header); | ||
445 | } | ||
446 | |||
447 | r = mailsession_get_message_flags(session, info->index, &flags); | ||
448 | if (r != MAIL_NO_ERROR) { | ||
449 | res = r; | ||
450 | goto free_list; | ||
451 | } | ||
452 | |||
453 | if (match_messages(message, info->size, fields, flags, | ||
454 | charset, key)) { | ||
455 | uint32_t * pnum; | ||
456 | |||
457 | pnum = malloc(sizeof(* pnum)); | ||
458 | if (pnum == NULL) { | ||
459 | if (message != NULL) | ||
460 | mailsession_fetch_result_free(session, message); | ||
461 | res = MAIL_ERROR_MEMORY; | ||
462 | goto free_list; | ||
463 | } | ||
464 | |||
465 | * pnum = info->index; | ||
466 | |||
467 | r = clist_append(list, pnum); | ||
468 | if (r < 0) { | ||
469 | free(pnum); | ||
470 | if (message != NULL) | ||
471 | mailsession_fetch_result_free(session, message); | ||
472 | res = MAIL_ERROR_MEMORY; | ||
473 | goto free_list; | ||
474 | } | ||
475 | } | ||
476 | |||
477 | if (message != NULL) | ||
478 | mailsession_fetch_result_free(session, message); | ||
479 | } | ||
480 | |||
481 | search_result = mail_search_result_new(list); | ||
482 | if (search_result == NULL) { | ||
483 | res = MAIL_ERROR_MEMORY; | ||
484 | goto free_list; | ||
485 | } | ||
486 | |||
487 | * result = search_result; | ||
488 | |||
489 | return MAIL_NO_ERROR; | ||
490 | |||
491 | free_list: | ||
492 | clist_foreach(list, (clist_func) free, NULL); | ||
493 | clist_free(list); | ||
494 | mailmessage_list_free(env_list); | ||
495 | return res; | ||
496 | } | ||
497 | #endif | ||
498 | |||
499 | #if 0 | ||
500 | int maildriver_generic_search_messages(mailsession * session, char * charset, | ||
501 | struct mail_search_key * key, | ||
502 | struct mail_search_result ** result) | ||
503 | { | ||
504 | return MAIL_ERROR_NOT_IMPLEMENTED; | ||
505 | } | ||
506 | #endif | ||
507 | |||
508 | int | ||
509 | maildriver_env_list_to_msg_list(struct mailmessage_list * env_list, | ||
510 | clist ** result) | ||
511 | { | ||
512 | clist * msg_list; | ||
513 | int r; | ||
514 | int res; | ||
515 | unsigned int i; | ||
516 | |||
517 | msg_list = clist_new(); | ||
518 | if (msg_list == NULL) { | ||
519 | res = MAIL_ERROR_MEMORY; | ||
520 | goto err; | ||
521 | } | ||
522 | |||
523 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
524 | mailmessage * msg; | ||
525 | |||
526 | msg = carray_get(env_list->msg_tab, i); | ||
527 | |||
528 | if (msg->msg_fields == NULL) { | ||
529 | uint32_t * pindex; | ||
530 | |||
531 | pindex = malloc(sizeof(* pindex)); | ||
532 | if (pindex == NULL) { | ||
533 | res = MAIL_ERROR_MEMORY; | ||
534 | goto free_msg_list; | ||
535 | } | ||
536 | |||
537 | * pindex = msg->msg_index; | ||
538 | |||
539 | r = clist_append(msg_list, pindex); | ||
540 | if (r < 0) { | ||
541 | free(pindex); | ||
542 | res = MAIL_ERROR_MEMORY; | ||
543 | goto free_msg_list; | ||
544 | } | ||
545 | |||
546 | } | ||
547 | } | ||
548 | |||
549 | * result = msg_list; | ||
550 | |||
551 | return MAIL_NO_ERROR; | ||
552 | |||
553 | free_msg_list: | ||
554 | clist_foreach(msg_list, (clist_func) free, NULL); | ||
555 | clist_free(msg_list); | ||
556 | err: | ||
557 | return res; | ||
558 | } | ||
559 | |||
560 | |||
561 | int | ||
562 | maildriver_env_list_to_msg_list_no_flags(struct mailmessage_list * env_list, | ||
563 | clist ** result) | ||
564 | { | ||
565 | clist * msg_list; | ||
566 | int r; | ||
567 | int res; | ||
568 | unsigned int i; | ||
569 | |||
570 | msg_list = clist_new(); | ||
571 | if (msg_list == NULL) { | ||
572 | res = MAIL_ERROR_MEMORY; | ||
573 | goto err; | ||
574 | } | ||
575 | |||
576 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
577 | mailmessage * msg; | ||
578 | |||
579 | msg = carray_get(env_list->msg_tab, i); | ||
580 | |||
581 | if (msg->msg_flags == NULL) { | ||
582 | uint32_t * pindex; | ||
583 | |||
584 | pindex = malloc(sizeof(* pindex)); | ||
585 | if (pindex == NULL) { | ||
586 | res = MAIL_ERROR_MEMORY; | ||
587 | goto free_msg_list; | ||
588 | } | ||
589 | |||
590 | * pindex = msg->msg_index; | ||
591 | |||
592 | r = clist_append(msg_list, pindex); | ||
593 | if (r < 0) { | ||
594 | free(pindex); | ||
595 | res = MAIL_ERROR_MEMORY; | ||
596 | goto free_msg_list; | ||
597 | } | ||
598 | |||
599 | } | ||
600 | } | ||
601 | |||
602 | * result = msg_list; | ||
603 | |||
604 | return MAIL_NO_ERROR; | ||
605 | |||
606 | free_msg_list: | ||
607 | clist_foreach(msg_list, (clist_func) free, NULL); | ||
608 | clist_free(msg_list); | ||
609 | err: | ||
610 | return res; | ||
611 | } | ||
612 | |||
613 | |||
614 | |||
615 | int maildriver_imf_error_to_mail_error(int error) | ||
616 | { | ||
617 | switch (error) { | ||
618 | case MAILIMF_NO_ERROR: | ||
619 | return MAIL_NO_ERROR; | ||
620 | |||
621 | case MAILIMF_ERROR_PARSE: | ||
622 | return MAIL_ERROR_PARSE; | ||
623 | |||
624 | case MAILIMF_ERROR_MEMORY: | ||
625 | return MAIL_ERROR_MEMORY; | ||
626 | |||
627 | case MAILIMF_ERROR_INVAL: | ||
628 | return MAIL_ERROR_INVAL; | ||
629 | |||
630 | case MAILIMF_ERROR_FILE: | ||
631 | return MAIL_ERROR_FILE; | ||
632 | |||
633 | default: | ||
634 | return MAIL_ERROR_INVAL; | ||
635 | } | ||
636 | } | ||
637 | |||
638 | char * maildriver_quote_mailbox(char * mb) | ||
639 | { | ||
640 | MMAPString * gstr; | ||
641 | char * str; | ||
642 | |||
643 | gstr = mmap_string_new(""); | ||
644 | if (gstr == NULL) | ||
645 | return NULL; | ||
646 | |||
647 | while (* mb != 0) { | ||
648 | char hex[3]; | ||
649 | |||
650 | if (((* mb >= 'a') && (* mb <= 'z')) || | ||
651 | ((* mb >= 'A') && (* mb <= 'Z')) || | ||
652 | ((* mb >= '0') && (* mb <= '9'))) | ||
653 | mmap_string_append_c(gstr, * mb); | ||
654 | else { | ||
655 | if (mmap_string_append_c(gstr, '%') == NULL) | ||
656 | goto free; | ||
657 | snprintf(hex, 3, "%02x", (unsigned char) (* mb)); | ||
658 | if (mmap_string_append(gstr, hex) == NULL) | ||
659 | goto free; | ||
660 | } | ||
661 | mb ++; | ||
662 | } | ||
663 | |||
664 | str = strdup(gstr->str); | ||
665 | if (str == NULL) | ||
666 | goto free; | ||
667 | |||
668 | mmap_string_free(gstr); | ||
669 | |||
670 | return str; | ||
671 | |||
672 | free: | ||
673 | mmap_string_free(gstr); | ||
674 | return NULL; | ||
675 | } | ||
676 | |||
677 | |||
678 | |||
679 | int maildriver_cache_clean_up(struct mail_cache_db * cache_db_env, | ||
680 | struct mail_cache_db * cache_db_flags, | ||
681 | struct mailmessage_list * env_list) | ||
682 | { | ||
683 | chash * hash_exist; | ||
684 | int res; | ||
685 | int r; | ||
686 | char keyname[PATH_MAX]; | ||
687 | unsigned int i; | ||
688 | |||
689 | /* flush cache */ | ||
690 | |||
691 | hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL); | ||
692 | if (hash_exist == NULL) { | ||
693 | res = MAIL_ERROR_MEMORY; | ||
694 | goto err; | ||
695 | } | ||
696 | |||
697 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
698 | mailmessage * msg; | ||
699 | chashdatum key; | ||
700 | chashdatum value; | ||
701 | |||
702 | msg = carray_get(env_list->msg_tab, i); | ||
703 | |||
704 | value.data = NULL; | ||
705 | value.len = 0; | ||
706 | |||
707 | if (cache_db_env != NULL) { | ||
708 | snprintf(keyname, PATH_MAX, "%s-envelope", msg->msg_uid); | ||
709 | |||
710 | key.data = keyname; | ||
711 | key.len = strlen(keyname); | ||
712 | r = chash_set(hash_exist, &key, &value, NULL); | ||
713 | if (r < 0) { | ||
714 | res = MAIL_ERROR_MEMORY; | ||
715 | goto free; | ||
716 | } | ||
717 | } | ||
718 | |||
719 | if (cache_db_flags != NULL) { | ||
720 | snprintf(keyname, PATH_MAX, "%s-flags", msg->msg_uid); | ||
721 | |||
722 | key.data = keyname; | ||
723 | key.len = strlen(keyname); | ||
724 | r = chash_set(hash_exist, &key, &value, NULL); | ||
725 | if (r < 0) { | ||
726 | res = MAIL_ERROR_MEMORY; | ||
727 | goto free; | ||
728 | } | ||
729 | } | ||
730 | } | ||
731 | |||
732 | /* clean up */ | ||
733 | if (cache_db_env != NULL) | ||
734 | mail_cache_db_clean_up(cache_db_env, hash_exist); | ||
735 | if (cache_db_flags != NULL) | ||
736 | mail_cache_db_clean_up(cache_db_flags, hash_exist); | ||
737 | |||
738 | chash_free(hash_exist); | ||
739 | |||
740 | return MAIL_NO_ERROR; | ||
741 | |||
742 | free: | ||
743 | chash_free(hash_exist); | ||
744 | err: | ||
745 | return res; | ||
746 | } | ||
747 | |||
748 | |||
749 | /* | ||
750 | maildriver_message_cache_clean_up() | ||
751 | |||
752 | remove files in cache_dir that does not correspond to a message. | ||
753 | |||
754 | get_uid_from_filename() modifies the given filename so that it | ||
755 | is a uid when returning from the function. If get_uid_from_filename() | ||
756 | clears the content of file (set to empty string), this means that | ||
757 | this file should not be deleted. | ||
758 | */ | ||
759 | |||
760 | int maildriver_message_cache_clean_up(char * cache_dir, | ||
761 | struct mailmessage_list * env_list, | ||
762 | void (* get_uid_from_filename)(char *)) | ||
763 | { | ||
764 | chash * hash_exist; | ||
765 | DIR * d; | ||
766 | char cached_filename[PATH_MAX]; | ||
767 | struct dirent * ent; | ||
768 | char keyname[PATH_MAX]; | ||
769 | unsigned int i; | ||
770 | int res; | ||
771 | int r; | ||
772 | |||
773 | /* remove files */ | ||
774 | |||
775 | hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL); | ||
776 | if (hash_exist == NULL) { | ||
777 | res = MAIL_ERROR_MEMORY; | ||
778 | goto err; | ||
779 | } | ||
780 | |||
781 | for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { | ||
782 | mailmessage * msg; | ||
783 | chashdatum key; | ||
784 | chashdatum value; | ||
785 | |||
786 | msg = carray_get(env_list->msg_tab, i); | ||
787 | |||
788 | key.data = msg->msg_uid; | ||
789 | key.len = strlen(msg->msg_uid); | ||
790 | value.data = NULL; | ||
791 | value.len = 0; | ||
792 | r = chash_set(hash_exist, &key, &value, NULL); | ||
793 | if (r < 0) { | ||
794 | res = MAIL_ERROR_MEMORY; | ||
795 | goto free; | ||
796 | } | ||
797 | } | ||
798 | |||
799 | d = opendir(cache_dir); | ||
800 | while ((ent = readdir(d)) != NULL) { | ||
801 | chashdatum key; | ||
802 | chashdatum value; | ||
803 | |||
804 | if (strcmp(ent->d_name, ".") == 0) | ||
805 | continue; | ||
806 | |||
807 | if (strcmp(ent->d_name, "..") == 0) | ||
808 | continue; | ||
809 | |||
810 | if (strstr(ent->d_name, ".db") != NULL) | ||
811 | continue; | ||
812 | |||
813 | strncpy(keyname, ent->d_name, sizeof(keyname)); | ||
814 | keyname[sizeof(keyname) - 1] = '\0'; | ||
815 | |||
816 | get_uid_from_filename(keyname); | ||
817 | |||
818 | if (* keyname == '\0') | ||
819 | continue; | ||
820 | |||
821 | key.data = keyname; | ||
822 | key.len = strlen(keyname); | ||
823 | |||
824 | r = chash_get(hash_exist, &key, &value); | ||
825 | if (r < 0) { | ||
826 | snprintf(cached_filename, sizeof(cached_filename), | ||
827 | "%s/%s", cache_dir, ent->d_name); | ||
828 | unlink(cached_filename); | ||
829 | } | ||
830 | } | ||
831 | closedir(d); | ||
832 | |||
833 | chash_free(hash_exist); | ||
834 | |||
835 | return MAIL_NO_ERROR; | ||
836 | |||
837 | free: | ||
838 | chash_free(hash_exist); | ||
839 | err: | ||
840 | return res; | ||
841 | } | ||