summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/mbox
Unidiff
Diffstat (limited to 'kmicromail/libetpan/mbox') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/mbox/.libs/libmailmbox.abin0 -> 63290 bytes
-rw-r--r--kmicromail/libetpan/mbox/TODO0
-rw-r--r--kmicromail/libetpan/mbox/mailmbox.c1424
-rw-r--r--kmicromail/libetpan/mbox/mailmbox.h140
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_parse.c620
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_parse.h56
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_types.c250
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_types.h142
8 files changed, 2632 insertions, 0 deletions
diff --git a/kmicromail/libetpan/mbox/.libs/libmailmbox.a b/kmicromail/libetpan/mbox/.libs/libmailmbox.a
new file mode 100644
index 0000000..7b92e2d
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/.libs/libmailmbox.a
Binary files differ
diff --git a/kmicromail/libetpan/mbox/TODO b/kmicromail/libetpan/mbox/TODO
new file mode 100644
index 0000000..e69de29
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/TODO
diff --git a/kmicromail/libetpan/mbox/mailmbox.c b/kmicromail/libetpan/mbox/mailmbox.c
new file mode 100644
index 0000000..280c313
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox.c
@@ -0,0 +1,1424 @@
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 "mailmbox.h"
37
38#include <sys/file.h>
39#include <sys/stat.h>
40#include <unistd.h>
41#include <sys/mman.h>
42#include <fcntl.h>
43#include <time.h>
44#include <sys/types.h>
45#include <unistd.h>
46
47#include <string.h>
48#include <ctype.h>
49#include <stdlib.h>
50#include <stdio.h>
51
52#include "libetpan-config.h"
53
54#include "mmapstring.h"
55#include "mailmbox_parse.h"
56#include "maillock.h"
57
58/*
59 http://www.qmail.org/qmail-manual-html/man5/mbox.html
60 RFC 2076
61*/
62
63#define TMPDIR "/tmp"
64
65/* mbox is a file with a corresponding filename */
66
67#define UID_HEADER "X-LibEtPan-UID:"
68
69#ifndef TRUE
70#define TRUE 1
71#endif
72
73#ifndef FALSE
74#define FALSE 0
75#endif
76
77int mailmbox_write_lock(struct mailmbox_folder * folder)
78{
79 int r;
80
81 if (folder->mb_read_only)
82 return MAILMBOX_ERROR_READONLY;
83
84 r = maillock_write_lock(folder->mb_filename, folder->mb_fd);
85 if (r == 0)
86 return MAILMBOX_NO_ERROR;
87 else
88 return MAILMBOX_ERROR_FILE;
89}
90
91int mailmbox_write_unlock(struct mailmbox_folder * folder)
92{
93 int r;
94
95 r = maillock_write_unlock(folder->mb_filename, folder->mb_fd);
96 if (r == 0)
97 return MAILMBOX_NO_ERROR;
98 else
99 return MAILMBOX_ERROR_FILE;
100}
101
102int mailmbox_read_lock(struct mailmbox_folder * folder)
103{
104 int r;
105
106 r = maillock_read_lock(folder->mb_filename, folder->mb_fd);
107 if (r == 0)
108 return MAILMBOX_NO_ERROR;
109 else
110 return MAILMBOX_ERROR_FILE;
111}
112
113int mailmbox_read_unlock(struct mailmbox_folder * folder)
114{
115 int r;
116
117 r = maillock_read_unlock(folder->mb_filename, folder->mb_fd);
118 if (r == 0)
119 return MAILMBOX_NO_ERROR;
120 else
121 return MAILMBOX_ERROR_FILE;
122}
123
124
125/*
126 map the file into memory.
127 the file must be locked.
128*/
129
130int mailmbox_map(struct mailmbox_folder * folder)
131{
132 char * str;
133 struct stat buf;
134 int res;
135 int r;
136
137 r = stat(folder->mb_filename, &buf);
138 if (r < 0) {
139 res = MAILMBOX_ERROR_FILE;
140 goto err;
141 }
142
143 if (folder->mb_read_only)
144 str = (char *) mmap(0, buf.st_size, PROT_READ,
145 MAP_PRIVATE, folder->mb_fd, 0);
146 else
147 str = (char *) mmap(0, buf.st_size, PROT_READ | PROT_WRITE,
148 MAP_SHARED, folder->mb_fd, 0);
149 if (str == MAP_FAILED) {
150 res = MAILMBOX_ERROR_FILE;
151 goto err;
152 }
153
154 folder->mb_mapping = str;
155 folder->mb_mapping_size = buf.st_size;
156
157 return MAILMBOX_NO_ERROR;
158
159 err:
160 return res;
161}
162
163/*
164 unmap the file
165*/
166
167void mailmbox_unmap(struct mailmbox_folder * folder)
168{
169 munmap(folder->mb_mapping, folder->mb_mapping_size);
170 folder->mb_mapping = NULL;
171 folder->mb_mapping_size = 0;
172}
173
174void mailmbox_sync(struct mailmbox_folder * folder)
175{
176 msync(folder->mb_mapping, folder->mb_mapping_size, MS_SYNC);
177}
178
179void mailmbox_timestamp(struct mailmbox_folder * folder)
180{
181 int r;
182 struct stat buf;
183
184 r = stat(folder->mb_filename, &buf);
185 if (r < 0)
186 folder->mb_mtime = (time_t) -1;
187 else
188 folder->mb_mtime = buf.st_mtime;
189}
190
191/*
192 open the file
193*/
194
195int mailmbox_open(struct mailmbox_folder * folder)
196{
197 int fd;
198 int read_only;
199
200 if (!folder->mb_read_only) {
201 read_only = FALSE;
202 fd = open(folder->mb_filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
203 }
204
205 if (folder->mb_read_only || (fd < 0)) {
206 read_only = TRUE;
207 fd = open(folder->mb_filename, O_RDONLY);
208 if (fd < 0)
209 return MAILMBOX_ERROR_FILE_NOT_FOUND;
210 }
211
212 folder->mb_fd = fd;
213 folder->mb_read_only = read_only;
214
215 return MAILMBOX_NO_ERROR;
216}
217
218/*
219 close the file
220*/
221
222void mailmbox_close(struct mailmbox_folder * folder)
223{
224 close(folder->mb_fd);
225 folder->mb_fd = -1;
226}
227
228
229static int mailmbox_validate_lock(struct mailmbox_folder * folder,
230 int (* custom_lock)(struct mailmbox_folder *),
231 int (* custom_unlock)(struct mailmbox_folder *))
232{
233 struct stat buf;
234 int res;
235 int r;
236
237 r = stat(folder->mb_filename, &buf);
238 if (r < 0) {
239 buf.st_mtime = (time_t) -1;
240 }
241
242 if ((buf.st_mtime != folder->mb_mtime) ||
243 ((size_t) buf.st_size != folder->mb_mapping_size)) {
244 int r;
245
246 mailmbox_unmap(folder);
247 mailmbox_close(folder);
248
249 r = mailmbox_open(folder);
250 if (r != MAILMBOX_NO_ERROR) {
251 res = r;
252 goto err;
253 }
254
255 r = custom_lock(folder);
256 if (r != MAILMBOX_NO_ERROR) {
257 res = r;
258 goto err;
259 }
260
261 r = mailmbox_map(folder);
262 if (r != MAILMBOX_NO_ERROR) {
263 res = r;
264 goto err_unlock;
265 }
266
267 r = mailmbox_parse(folder);
268 if (r != MAILMBOX_NO_ERROR) {
269 res = r;
270 goto err_unlock;
271 }
272
273 folder->mb_mtime = buf.st_mtime;
274
275 return MAILMBOX_NO_ERROR;
276 }
277 else {
278 r = custom_lock(folder);
279 if (r != MAILMBOX_NO_ERROR) {
280 res = r;
281 goto err;
282 }
283 }
284
285 return MAILMBOX_NO_ERROR;
286
287 err_unlock:
288 custom_unlock(folder);
289 err:
290 return res;
291}
292
293
294int mailmbox_validate_write_lock(struct mailmbox_folder * folder)
295{
296 return mailmbox_validate_lock(folder,
297 mailmbox_write_lock,
298 mailmbox_write_unlock);
299}
300
301
302int mailmbox_validate_read_lock(struct mailmbox_folder * folder)
303{
304 return mailmbox_validate_lock(folder,
305 mailmbox_read_lock,
306 mailmbox_read_unlock);
307}
308
309
310/* ********************************************************************** */
311/* append messages */
312
313#define MAX_FROM_LINE_SIZE 256
314
315static inline size_t get_line(const char * line, size_t length,
316 const char ** pnext_line, size_t * pcount)
317{
318 size_t count;
319
320 count = 0;
321
322 while (1) {
323 if (length == 0)
324 break;
325
326 if (* line == '\r') {
327 line ++;
328
329 count ++;
330 length --;
331
332 if (length > 0) {
333 if (* line == '\n') {
334 line ++;
335
336 count ++;
337 length --;
338
339 break;
340 }
341 }
342 }
343 else if (* line == '\n') {
344 line ++;
345
346 count ++;
347 length --;
348
349 break;
350 }
351 else {
352 line ++;
353 length --;
354 count ++;
355 }
356 }
357
358 * pnext_line = line;
359 * pcount = count;
360
361 return count;
362}
363
364/*
365 TODO : should strip \r\n if any
366 see also in write_fixed_line
367*/
368
369static inline size_t get_fixed_line_size(const char * line, size_t length,
370 const char ** pnext_line, size_t * pcount,
371 size_t * pfixed_count)
372{
373 size_t count;
374 const char * next_line;
375 size_t fixed_count;
376
377 if (!get_line(line, length, &next_line, &count))
378 return 0;
379
380 fixed_count = count;
381 if (count >= 5) {
382 if (line[0] == 'F') {
383 if (strncmp(line, "From ", 5) == 0)
384 fixed_count ++;
385 }
386 }
387
388 * pnext_line = next_line;
389 * pcount = count;
390 * pfixed_count = fixed_count;
391
392 return count;
393}
394
395static size_t get_fixed_message_size(const char * message, size_t size,
396 uint32_t uid, int force_no_uid)
397{
398 size_t fixed_size;
399 size_t cur_token;
400 size_t left;
401 const char * next;
402 const char * cur;
403 int end;
404 int r;
405 uint32_t tmp_uid;
406
407 cur_token = 0;
408
409 fixed_size = 0;
410
411 /* headers */
412
413 end = FALSE;
414 while (!end) {
415 size_t begin;
416 int ignore;
417
418 ignore = FALSE;
419 begin = cur_token;
420 if (cur_token + strlen(UID_HEADER) <= size) {
421 if (message[cur_token] == 'X') {
422 if (strncasecmp(message + cur_token, UID_HEADER,
423 strlen(UID_HEADER)) == 0) {
424 ignore = TRUE;
425 }
426 }
427 }
428
429 r = mailimf_ignore_field_parse(message, size, &cur_token);
430 switch (r) {
431 case MAILIMF_NO_ERROR:
432 if (!ignore)
433 fixed_size += cur_token - begin;
434 break;
435 case MAILIMF_ERROR_PARSE:
436 default:
437 end = TRUE;
438 break;
439 }
440 }
441
442 if (!force_no_uid) {
443 /* UID header */
444
445 fixed_size += strlen(UID_HEADER " \r\n");
446
447 tmp_uid = uid;
448 while (tmp_uid >= 10) {
449 tmp_uid /= 10;
450 fixed_size ++;
451 }
452 fixed_size ++;
453 }
454
455 /* body */
456
457 left = size - cur_token;
458 next = message + cur_token;
459 while (left > 0) {
460 size_t count;
461 size_t fixed_count;
462
463 cur = next;
464
465 if (!get_fixed_line_size(cur, left, &next, &count, &fixed_count))
466 break;
467
468 fixed_size += fixed_count;
469 left -= count;
470 }
471
472 return fixed_size;
473}
474
475static inline char * write_fixed_line(char * str,
476 const char * line, size_t length,
477 const char ** pnext_line, size_t * pcount)
478{
479 size_t count;
480 const char * next_line;
481
482 if (!get_line(line, length, &next_line, &count))
483 return str;
484
485 if (count >= 5) {
486 if (line[0] == 'F') {
487 if (strncmp(line, "From ", 5) == 0) {
488 * str = '>';
489 str ++;
490 }
491 }
492 }
493
494 memcpy(str, line, count);
495
496 * pnext_line = next_line;
497 * pcount = count;
498 str += count;
499
500 return str;
501}
502
503static char * write_fixed_message(char * str,
504 const char * message, size_t size,
505 uint32_t uid, int force_no_uid)
506{
507 size_t fixed_size;
508 size_t cur_token;
509 size_t left;
510 int end;
511 int r;
512 const char * cur_src;
513 size_t numlen;
514
515 cur_token = 0;
516
517 fixed_size = 0;
518
519 /* headers */
520
521 end = FALSE;
522 while (!end) {
523 size_t begin;
524 int ignore;
525
526 ignore = FALSE;
527 begin = cur_token;
528 if (cur_token + strlen(UID_HEADER) <= size) {
529 if (message[cur_token] == 'X') {
530 if (strncasecmp(message + cur_token, UID_HEADER,
531 strlen(UID_HEADER)) == 0) {
532 ignore = TRUE;
533 }
534 }
535 }
536
537 r = mailimf_ignore_field_parse(message, size, &cur_token);
538 switch (r) {
539 case MAILIMF_NO_ERROR:
540 if (!ignore) {
541 memcpy(str, message + begin, cur_token - begin);
542 str += cur_token - begin;
543 }
544 break;
545 case MAILIMF_ERROR_PARSE:
546 default:
547 end = TRUE;
548 break;
549 }
550 }
551
552 if (!force_no_uid) {
553 /* UID header */
554
555 memcpy(str, UID_HEADER " ", strlen(UID_HEADER " "));
556 str += strlen(UID_HEADER " ");
557 numlen = snprintf(str, 20, "%i\r\n", uid);
558 str += numlen;
559 }
560
561 /* body */
562
563 cur_src = message + cur_token;
564 left = size - cur_token;
565 while (left > 0) {
566 size_t count;
567 const char * next;
568
569 str = write_fixed_line(str, cur_src, left, &next, &count);
570
571 cur_src = next;
572 left -= count;
573 }
574
575 return str;
576}
577
578#define DEFAULT_FROM_LINE "From - Wed Jun 30 21:49:08 1993\n"
579
580int
581mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder,
582 carray * append_tab)
583{
584 size_t extra_size;
585 int r;
586 char from_line[MAX_FROM_LINE_SIZE] = DEFAULT_FROM_LINE;
587 struct tm time_info;
588 time_t date;
589 int res;
590 size_t old_size;
591 char * str;
592 unsigned int i;
593 size_t from_size;
594 size_t maxuid;
595 size_t left;
596 size_t crlf_count;
597
598 if (folder->mb_read_only) {
599 res = MAILMBOX_ERROR_READONLY;
600 goto err;
601 }
602
603 date = time(NULL);
604 from_size = strlen(DEFAULT_FROM_LINE);
605 if (localtime_r(&date, &time_info) != NULL)
606 from_size = strftime(from_line, MAX_FROM_LINE_SIZE, "From - %c\n", &time_info);
607
608 maxuid = /* */ folder->mb_max_uid;
609
610 extra_size = 0;
611 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
612 struct mailmbox_append_info * info;
613
614 info = carray_get(append_tab, i);
615 extra_size += from_size;
616 extra_size += get_fixed_message_size(info->ai_message, info->ai_size,
617 folder->mb_max_uid + i + 1,
618 folder->mb_no_uid);
619 extra_size += 2; /* CR LF */
620 }
621
622 left = folder->mb_mapping_size;
623 crlf_count = 0;
624 while (left >= 1) {
625 if (folder->mb_mapping[left - 1] == '\n') {
626 crlf_count ++;
627 left --;
628 }
629 else if (folder->mb_mapping[left - 1] == '\r') {
630 left --;
631 }
632 else
633 break;
634
635 if (crlf_count == 2)
636 break;
637 }
638
639 old_size = folder->mb_mapping_size;
640 mailmbox_unmap(folder);
641
642 if (old_size != 0) {
643 if (crlf_count != 2)
644 extra_size += (2 - crlf_count) * 2;
645 }
646
647 r = ftruncate(folder->mb_fd, extra_size + old_size);
648 if (r < 0) {
649 mailmbox_map(folder);
650 res = MAILMBOX_ERROR_FILE;
651 goto err;
652 }
653
654 r = mailmbox_map(folder);
655 if (r < 0) {
656 ftruncate(folder->mb_fd, old_size);
657 return MAILMBOX_ERROR_FILE;
658 }
659
660 str = folder->mb_mapping + old_size;
661
662 if (old_size != 0) {
663 for(i = 0 ; i < 2 - crlf_count ; i ++) {
664 * str = '\r';
665 str ++;
666 * str = '\n';
667 str ++;
668 }
669 }
670
671 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
672 struct mailmbox_append_info * info;
673
674 info = carray_get(append_tab, i);
675
676 memcpy(str, from_line, from_size);
677
678 str += strlen(from_line);
679
680 str = write_fixed_message(str, info->ai_message, info->ai_size,
681 folder->mb_max_uid + i + 1,
682 folder->mb_no_uid);
683
684 * str = '\r';
685 str ++;
686 * str = '\n';
687 str ++;
688 }
689
690 folder->mb_max_uid += carray_count(append_tab);
691
692 return MAILMBOX_NO_ERROR;
693
694 err:
695 return res;
696}
697
698int
699mailmbox_append_message_list(struct mailmbox_folder * folder,
700 carray * append_tab)
701{
702 int r;
703 int res;
704 size_t cur_token;
705
706 r = mailmbox_validate_write_lock(folder);
707 if (r != MAILMBOX_NO_ERROR) {
708 res = r;
709 goto err;
710 }
711
712 r = mailmbox_expunge_no_lock(folder);
713 if (r != MAILMBOX_NO_ERROR) {
714 res = r;
715 goto unlock;
716 }
717
718 cur_token = folder->mb_mapping_size;
719
720 r = mailmbox_append_message_list_no_lock(folder, append_tab);
721 if (r != MAILMBOX_NO_ERROR) {
722 res = r;
723 goto unlock;
724 }
725
726 mailmbox_sync(folder);
727
728 r = mailmbox_parse_additionnal(folder, &cur_token);
729 if (r != MAILMBOX_NO_ERROR) {
730 res = r;
731 goto unlock;
732 }
733
734 mailmbox_timestamp(folder);
735
736 mailmbox_write_unlock(folder);
737
738 return MAILMBOX_NO_ERROR;
739
740 unlock:
741 mailmbox_write_unlock(folder);
742 err:
743 return res;
744}
745
746int
747mailmbox_append_message(struct mailmbox_folder * folder,
748 const char * data, size_t len)
749{
750 carray * tab;
751 struct mailmbox_append_info * append_info;
752 int res;
753 int r;
754
755 tab = carray_new(1);
756 if (tab == NULL) {
757 res = MAILMBOX_ERROR_MEMORY;
758 goto err;
759 }
760
761 append_info = mailmbox_append_info_new(data, len);
762 if (append_info == NULL) {
763 res = MAILMBOX_ERROR_MEMORY;
764 goto free_list;
765 }
766
767 r = carray_add(tab, append_info, NULL);
768 if (r < 0) {
769 res = MAILMBOX_ERROR_MEMORY;
770 goto free_append_info;
771 }
772
773 r = mailmbox_append_message_list(folder, tab);
774
775 mailmbox_append_info_free(append_info);
776 carray_free(tab);
777
778 return r;
779
780 free_append_info:
781 mailmbox_append_info_free(append_info);
782 free_list:
783 carray_free(tab);
784 err:
785 return res;
786}
787
788/* ********************************************************************** */
789
790int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder,
791 uint32_t num, char ** result,
792 size_t * result_len)
793{
794 struct mailmbox_msg_info * info;
795 int res;
796 chashdatum key;
797 chashdatum data;
798 int r;
799
800 key.data = &num;
801 key.len = sizeof(num);
802
803 r = chash_get(folder->mb_hash, &key, &data);
804 if (r < 0) {
805 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
806 goto err;
807 }
808
809 info = data.data;
810
811 if (info->msg_deleted) {
812 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
813 goto err;
814 }
815
816 * result = folder->mb_mapping + info->msg_headers;
817 * result_len = info->msg_size - info->msg_start_len;
818
819 return MAILMBOX_NO_ERROR;
820
821 err:
822 return res;
823}
824
825int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder,
826 uint32_t num, char ** result,
827 size_t * result_len)
828{
829 struct mailmbox_msg_info * info;
830 int res;
831 chashdatum key;
832 chashdatum data;
833 int r;
834
835 key.data = &num;
836 key.len = sizeof(num);
837
838 r = chash_get(folder->mb_hash, &key, &data);
839 if (r < 0) {
840 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
841 goto err;
842 }
843
844 info = data.data;
845
846 if (info->msg_deleted) {
847 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
848 goto err;
849 }
850
851 * result = folder->mb_mapping + info->msg_headers;
852 * result_len = info->msg_headers_len;
853
854 return MAILMBOX_NO_ERROR;
855
856 err:
857 return res;
858}
859
860int mailmbox_fetch_msg(struct mailmbox_folder * folder,
861 uint32_t num, char ** result,
862 size_t * result_len)
863{
864 MMAPString * mmapstr;
865 int res;
866 char * data;
867 size_t len;
868 int r;
869 size_t fixed_size;
870 char * end;
871
872 r = mailmbox_validate_read_lock(folder);
873 if (r != MAILMBOX_NO_ERROR) {
874 res = r;
875 goto err;
876 }
877
878 r = mailmbox_fetch_msg_no_lock(folder, num, &data, &len);
879 if (r != MAILMBOX_NO_ERROR) {
880 res = r;
881 goto unlock;
882 }
883
884 /* size with no uid */
885 fixed_size = get_fixed_message_size(data, len, 0, 1 /* force no uid */);
886
887#if 0
888 mmapstr = mmap_string_new_len(data, fixed_size);
889 if (mmapstr == NULL) {
890 res = MAILMBOX_ERROR_MEMORY;
891 goto unlock;
892 }
893#endif
894 mmapstr = mmap_string_sized_new(fixed_size);
895 if (mmapstr == NULL) {
896 res = MAILMBOX_ERROR_MEMORY;
897 goto unlock;
898 }
899
900 end = write_fixed_message(mmapstr->str, data, len, 0, 1 /* force no uid */);
901 * end = '\0';
902 mmapstr->len = fixed_size;
903
904 r = mmap_string_ref(mmapstr);
905 if (r < 0) {
906 mmap_string_free(mmapstr);
907 res = MAILMBOX_ERROR_MEMORY;
908 goto unlock;
909 }
910
911 * result = mmapstr->str;
912 * result_len = mmapstr->len;
913
914 mailmbox_read_unlock(folder);
915
916 return MAILMBOX_NO_ERROR;
917
918 unlock:
919 mailmbox_read_unlock(folder);
920 err:
921 return res;
922}
923
924int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder,
925 uint32_t num, char ** result,
926 size_t * result_len)
927{
928 MMAPString * mmapstr;
929 int res;
930 char * data;
931 size_t len;
932 int r;
933 size_t fixed_size;
934 char * end;
935
936 r = mailmbox_validate_read_lock(folder);
937 if (r != MAILMBOX_NO_ERROR) {
938 res = r;
939 goto err;
940 }
941
942 r = mailmbox_fetch_msg_headers_no_lock(folder, num, &data, &len);
943 if (r != MAILMBOX_NO_ERROR) {
944 res = r;
945 goto unlock;
946 }
947
948#if 0
949 mmapstr = mmap_string_new_len(data, len);
950 if (mmapstr == NULL) {
951 res = MAILMBOX_ERROR_MEMORY;
952 goto unlock;
953 }
954#endif
955 /* size with no uid */
956 fixed_size = get_fixed_message_size(data, len, 0, 1 /* force no uid */);
957
958 mmapstr = mmap_string_sized_new(fixed_size);
959 if (mmapstr == NULL) {
960 res = MAILMBOX_ERROR_MEMORY;
961 goto unlock;
962 }
963
964 end = write_fixed_message(mmapstr->str, data, len, 0, 1 /* force no uid */);
965 * end = '\0';
966 mmapstr->len = fixed_size;
967
968 r = mmap_string_ref(mmapstr);
969 if (r < 0) {
970 mmap_string_free(mmapstr);
971 res = MAILMBOX_ERROR_MEMORY;
972 goto unlock;
973 }
974
975 * result = mmapstr->str;
976 * result_len = mmapstr->len;
977
978 mailmbox_read_unlock(folder);
979
980 return MAILMBOX_NO_ERROR;
981
982 unlock:
983 mailmbox_read_unlock(folder);
984 err:
985 return res;
986}
987
988void mailmbox_fetch_result_free(char * msg)
989{
990 mmap_string_unref(msg);
991}
992
993
994int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder,
995 struct mailmbox_folder * src_folder,
996 carray * tab)
997{
998 int r;
999 int res;
1000 carray * append_tab;
1001 unsigned int i;
1002
1003 r = mailmbox_validate_read_lock(src_folder);
1004 if (r != MAILMBOX_NO_ERROR) {
1005 res = r;
1006 goto err;
1007 }
1008
1009 append_tab = carray_new(carray_count(tab));
1010 if (append_tab == NULL) {
1011 res = MAILMBOX_ERROR_MEMORY;
1012 goto src_unlock;
1013 }
1014
1015 for(i = 0 ; i < carray_count(tab) ; i ++) {
1016 struct mailmbox_append_info * append_info;
1017 char * data;
1018 size_t len;
1019 uint32_t uid;
1020
1021 uid = * ((uint32_t *) carray_get(tab, i));
1022
1023 r = mailmbox_fetch_msg_no_lock(src_folder, uid, &data, &len);
1024 if (r != MAILMBOX_NO_ERROR) {
1025 res = r;
1026 goto free_list;
1027 }
1028
1029 append_info = mailmbox_append_info_new(data, len);
1030 if (append_info == NULL) {
1031 res = MAILMBOX_ERROR_MEMORY;
1032 goto free_list;
1033 }
1034
1035 r = carray_add(append_tab, append_info, NULL);
1036 if (r < 0) {
1037 mailmbox_append_info_free(append_info);
1038 res = MAILMBOX_ERROR_MEMORY;
1039 goto free_list;
1040 }
1041 }
1042
1043 r = mailmbox_append_message_list(dest_folder, append_tab);
1044 if (r != MAILMBOX_NO_ERROR) {
1045 res = r;
1046 goto src_unlock;
1047 }
1048
1049 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
1050 struct mailmbox_append_info * append_info;
1051
1052 append_info = carray_get(append_tab, i);
1053 mailmbox_append_info_free(append_info);
1054 }
1055 carray_free(append_tab);
1056
1057 mailmbox_read_unlock(src_folder);
1058
1059 return MAILMBOX_NO_ERROR;
1060
1061 free_list:
1062 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
1063 struct mailmbox_append_info * append_info;
1064
1065 append_info = carray_get(append_tab, i);
1066 mailmbox_append_info_free(append_info);
1067 }
1068 carray_free(append_tab);
1069 src_unlock:
1070 mailmbox_read_unlock(src_folder);
1071 err:
1072 return res;
1073}
1074
1075int mailmbox_copy_msg(struct mailmbox_folder * dest_folder,
1076 struct mailmbox_folder * src_folder,
1077 uint32_t uid)
1078{
1079 carray * tab;
1080 int res;
1081 uint32_t * puid;
1082 int r;
1083
1084 tab = carray_new(1);
1085 if (tab == NULL) {
1086 res = MAILMBOX_ERROR_MEMORY;
1087 goto err;
1088 }
1089
1090 puid = malloc(sizeof(* puid));
1091 if (puid == NULL) {
1092 res = MAILMBOX_ERROR_MEMORY;
1093 goto free_array;
1094 }
1095 * puid = uid;
1096
1097 r = mailmbox_copy_msg_list(dest_folder, src_folder, tab);
1098 res = r;
1099
1100 free(puid);
1101 free_array:
1102 carray_free(tab);
1103 err:
1104 return res;
1105}
1106
1107static int mailmbox_expunge_to_file_no_lock(char * dest_filename, int dest_fd,
1108 struct mailmbox_folder * folder,
1109 size_t * result_size)
1110{
1111 int r;
1112 int res;
1113 unsigned long i;
1114 size_t cur_offset;
1115 char * dest;
1116 size_t size;
1117
1118 size = 0;
1119 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
1120 struct mailmbox_msg_info * info;
1121
1122 info = carray_get(folder->mb_tab, i);
1123
1124 if (!info->msg_deleted) {
1125 size += info->msg_size + info->msg_padding;
1126
1127 if (!folder->mb_no_uid) {
1128 if (!info->msg_written_uid) {
1129 uint32_t uid;
1130
1131 size += strlen(UID_HEADER " \r\n");
1132
1133 uid = info->msg_uid;
1134 while (uid >= 10) {
1135 uid /= 10;
1136 size ++;
1137 }
1138 size ++;
1139 }
1140 }
1141 }
1142 }
1143
1144 r = ftruncate(dest_fd, size);
1145 if (r < 0) {
1146 res = MAILMBOX_ERROR_FILE;
1147 goto err;
1148 }
1149
1150 dest = (char *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, dest_fd, 0);
1151 if (dest == MAP_FAILED) {
1152 res = MAILMBOX_ERROR_FILE;
1153 goto err;
1154 }
1155
1156 cur_offset = 0;
1157 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
1158 struct mailmbox_msg_info * info;
1159
1160 info = carray_get(folder->mb_tab, i);
1161
1162 if (!info->msg_deleted) {
1163 memcpy(dest + cur_offset, folder->mb_mapping + info->msg_start,
1164 info->msg_headers_len + info->msg_start_len);
1165 cur_offset += info->msg_headers_len + info->msg_start_len;
1166
1167 if (!folder->mb_no_uid) {
1168 if (!info->msg_written_uid) {
1169 size_t numlen;
1170
1171 memcpy(dest + cur_offset, UID_HEADER " ", strlen(UID_HEADER " "));
1172 cur_offset += strlen(UID_HEADER " ");
1173 numlen = snprintf(dest + cur_offset, size - cur_offset,
1174 "%i\r\n", info->msg_uid);
1175 cur_offset += numlen;
1176 }
1177 }
1178
1179 memcpy(dest + cur_offset,
1180 folder->mb_mapping + info->msg_headers + info->msg_headers_len,
1181 info->msg_size - (info->msg_start_len + info->msg_headers_len)
1182 + info->msg_padding);
1183
1184 cur_offset += info->msg_size -
1185 (info->msg_start_len + info->msg_headers_len)
1186 + info->msg_padding;
1187 }
1188 }
1189 fflush(stdout);
1190
1191 msync(dest, size, MS_SYNC);
1192 munmap(dest, size);
1193
1194 * result_size = size;
1195
1196 return MAILMBOX_NO_ERROR;
1197
1198 err:
1199 return res;
1200}
1201
1202int mailmbox_expunge_no_lock(struct mailmbox_folder * folder)
1203{
1204 char tmpfile[PATH_MAX];
1205 int r;
1206 int res;
1207 int dest_fd;
1208 size_t size;
1209
1210 if (folder->mb_read_only)
1211 return MAILMBOX_ERROR_READONLY;
1212
1213 if (((folder->mb_written_uid >= folder->mb_max_uid) || folder->mb_no_uid) &&
1214 (!folder->mb_changed)) {
1215 /* no need to expunge */
1216 return MAILMBOX_NO_ERROR;
1217 }
1218
1219 snprintf(tmpfile, PATH_MAX, "%sXXXXXX", folder->mb_filename);
1220 dest_fd = mkstemp(tmpfile);
1221
1222 if (dest_fd < 0) {
1223 res = MAILMBOX_ERROR_FILE;
1224 goto unlink;
1225 }
1226
1227 r = mailmbox_expunge_to_file_no_lock(tmpfile, dest_fd,
1228 folder, &size);
1229 if (r != MAILMBOX_NO_ERROR) {
1230 res = r;
1231 goto unlink;
1232 }
1233
1234 close(dest_fd);
1235
1236 r = rename(tmpfile, folder->mb_filename);
1237 if (r < 0) {
1238 res = r;
1239 goto err;
1240 }
1241
1242 mailmbox_unmap(folder);
1243 mailmbox_close(folder);
1244
1245 r = mailmbox_open(folder);
1246 if (r != MAILMBOX_NO_ERROR) {
1247 res = r;
1248 goto err;
1249 }
1250
1251 r = mailmbox_map(folder);
1252 if (r != MAILMBOX_NO_ERROR) {
1253 res = r;
1254 goto err;
1255 }
1256
1257 r = mailmbox_parse(folder);
1258 if (r != MAILMBOX_NO_ERROR) {
1259 res = r;
1260 goto err;
1261 }
1262
1263 mailmbox_timestamp(folder);
1264
1265 folder->mb_changed = FALSE;
1266 folder->mb_deleted_count = 0;
1267
1268 return MAILMBOX_NO_ERROR;
1269
1270 unlink:
1271 close(dest_fd);
1272 unlink(tmpfile);
1273 err:
1274 return res;
1275}
1276
1277int mailmbox_expunge(struct mailmbox_folder * folder)
1278{
1279 int r;
1280 int res;
1281
1282 r = mailmbox_validate_write_lock(folder);
1283 if (r != MAILMBOX_NO_ERROR) {
1284 res = r;
1285 goto err;
1286 }
1287
1288 r = mailmbox_expunge_no_lock(folder);
1289 res = r;
1290
1291 mailmbox_write_unlock(folder);
1292 err:
1293 return res;
1294}
1295
1296int mailmbox_delete_msg(struct mailmbox_folder * folder, uint32_t uid)
1297{
1298 struct mailmbox_msg_info * info;
1299 int res;
1300 chashdatum key;
1301 chashdatum data;
1302 int r;
1303
1304 if (folder->mb_read_only) {
1305 res = MAILMBOX_ERROR_READONLY;
1306 goto err;
1307 }
1308
1309 key.data = &uid;
1310 key.len = sizeof(uid);
1311
1312 r = chash_get(folder->mb_hash, &key, &data);
1313 if (r < 0) {
1314 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
1315 goto err;
1316 }
1317
1318 info = data.data;
1319
1320 if (info->msg_deleted) {
1321 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
1322 goto err;
1323 }
1324
1325 info->msg_deleted = TRUE;
1326 folder->mb_changed = TRUE;
1327 folder->mb_deleted_count ++;
1328
1329 return MAILMBOX_NO_ERROR;
1330
1331 err:
1332 return res;
1333}
1334
1335
1336/*
1337 INIT of MBOX
1338
1339 - open file
1340 - map the file
1341
1342 - lock the file
1343
1344 - parse memory
1345
1346 - unlock the file
1347*/
1348
1349int mailmbox_init(const char * filename,
1350 int force_readonly,
1351 int force_no_uid,
1352 uint32_t default_written_uid,
1353 struct mailmbox_folder ** result_folder)
1354{
1355 struct mailmbox_folder * folder;
1356 int r;
1357 int res;
1358
1359 folder = mailmbox_folder_new(filename);
1360 if (folder == NULL) {
1361 res = MAILMBOX_ERROR_MEMORY;
1362 goto err;
1363 }
1364 folder->mb_no_uid = force_no_uid;
1365 folder->mb_read_only = force_readonly;
1366 folder->mb_written_uid = default_written_uid;
1367
1368 folder->mb_changed = FALSE;
1369 folder->mb_deleted_count = 0;
1370
1371 r = mailmbox_open(folder);
1372 if (r != MAILMBOX_NO_ERROR) {
1373 res = r;
1374 goto free;
1375 }
1376
1377 r = mailmbox_map(folder);
1378 if (r != MAILMBOX_NO_ERROR) {
1379 res = r;
1380 goto close;
1381 }
1382
1383 r = mailmbox_validate_read_lock(folder);
1384 if (r != MAILMBOX_NO_ERROR) {
1385 res = r;
1386 goto unmap;
1387 }
1388
1389 mailmbox_read_unlock(folder);
1390
1391 * result_folder = folder;
1392
1393 return MAILMBOX_NO_ERROR;
1394
1395 unmap:
1396 mailmbox_unmap(folder);
1397 close:
1398 mailmbox_close(folder);
1399 free:
1400 mailmbox_folder_free(folder);
1401 err:
1402 return res;
1403}
1404
1405
1406/*
1407 when MBOX is DONE
1408
1409 - check for changes
1410
1411 - unmap the file
1412 - close file
1413*/
1414
1415void mailmbox_done(struct mailmbox_folder * folder)
1416{
1417 if (!folder->mb_read_only)
1418 mailmbox_expunge(folder);
1419
1420 mailmbox_unmap(folder);
1421 mailmbox_close(folder);
1422
1423 mailmbox_folder_free(folder);
1424}
diff --git a/kmicromail/libetpan/mbox/mailmbox.h b/kmicromail/libetpan/mbox/mailmbox.h
new file mode 100644
index 0000000..8be086c
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox.h
@@ -0,0 +1,140 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_H
37
38#define MAILMBOX_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmbox_types.h>
45
46int
47mailmbox_append_message_list(struct mailmbox_folder * folder,
48 carray * append_tab);
49
50int
51mailmbox_append_message(struct mailmbox_folder * folder,
52 const char * data, size_t len);
53
54int mailmbox_fetch_msg(struct mailmbox_folder * folder,
55 uint32_t num, char ** result,
56 size_t * result_len);
57
58int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder,
59 uint32_t num, char ** result,
60 size_t * result_len);
61
62void mailmbox_fetch_result_free(char * msg);
63
64int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder,
65 struct mailmbox_folder * src_folder,
66 carray * tab);
67
68int mailmbox_copy_msg(struct mailmbox_folder * dest_folder,
69 struct mailmbox_folder * src_folder,
70 uint32_t uid);
71
72int mailmbox_expunge(struct mailmbox_folder * folder);
73
74int mailmbox_delete_msg(struct mailmbox_folder * folder, uint32_t uid);
75
76int mailmbox_init(const char * filename,
77 int force_readonly,
78 int force_no_uid,
79 uint32_t default_written_uid,
80 struct mailmbox_folder ** result_folder);
81
82void mailmbox_done(struct mailmbox_folder * folder);
83
84/* low-level access primitives */
85
86int mailmbox_write_lock(struct mailmbox_folder * folder);
87
88int mailmbox_write_unlock(struct mailmbox_folder * folder);
89
90int mailmbox_read_lock(struct mailmbox_folder * folder);
91
92int mailmbox_read_unlock(struct mailmbox_folder * folder);
93
94
95/* memory map */
96
97int mailmbox_map(struct mailmbox_folder * folder);
98
99void mailmbox_unmap(struct mailmbox_folder * folder);
100
101void mailmbox_sync(struct mailmbox_folder * folder);
102
103
104/* open & close file */
105
106int mailmbox_open(struct mailmbox_folder * folder);
107
108void mailmbox_close(struct mailmbox_folder * folder);
109
110
111/* validate cache */
112
113int mailmbox_validate_write_lock(struct mailmbox_folder * folder);
114
115int mailmbox_validate_read_lock(struct mailmbox_folder * folder);
116
117
118/* fetch message */
119
120int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder,
121 uint32_t num, char ** result,
122 size_t * result_len);
123
124int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder,
125 uint32_t num, char ** result,
126 size_t * result_len);
127
128/* append message */
129
130int
131mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder,
132 carray * append_tab);
133
134int mailmbox_expunge_no_lock(struct mailmbox_folder * folder);
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif
diff --git a/kmicromail/libetpan/mbox/mailmbox_parse.c b/kmicromail/libetpan/mbox/mailmbox_parse.c
new file mode 100644
index 0000000..927159c
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_parse.c
@@ -0,0 +1,620 @@
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 "mailmbox_parse.h"
37
38#include "mailmbox.h"
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <string.h>
43#include <stdlib.h>
44
45#define UID_HEADER "X-LibEtPan-UID:"
46
47#ifndef TRUE
48#define TRUE 1
49#endif
50
51#ifndef FALSE
52#define FALSE 0
53#endif
54
55enum {
56 UNSTRUCTURED_START,
57 UNSTRUCTURED_CR,
58 UNSTRUCTURED_LF,
59 UNSTRUCTURED_WSP,
60 UNSTRUCTURED_OUT
61};
62
63static inline int
64mailmbox_fields_parse(char * str, size_t length,
65 size_t * index,
66 uint32_t * puid,
67 size_t * phlen)
68{
69 size_t cur_token;
70 int r;
71 size_t hlen;
72 size_t uid;
73 int end;
74
75 cur_token = * index;
76
77 end = FALSE;
78 uid = 0;
79 while (!end) {
80 size_t begin;
81
82 begin = cur_token;
83
84 r = mailimf_ignore_field_parse(str, length, &cur_token);
85 switch (r) {
86 case MAILIMF_NO_ERROR:
87 if (str[begin] == 'X') {
88
89 if (strncasecmp(str + begin, UID_HEADER, strlen(UID_HEADER)) == 0) {
90 begin += strlen(UID_HEADER);
91
92 while (str[begin] == ' ')
93 begin ++;
94
95 uid = strtoul(str + begin, NULL, 10);
96 }
97 }
98
99 break;
100 case MAILIMF_ERROR_PARSE:
101 default:
102 end = TRUE;
103 break;
104 }
105 }
106
107 hlen = cur_token - * index;
108
109 * phlen = hlen;
110 * puid = uid;
111 * index = cur_token;
112
113 return MAILMBOX_NO_ERROR;
114}
115
116enum {
117 IN_MAIL,
118 FIRST_CR,
119 FIRST_LF,
120 SECOND_CR,
121 SECOND_LF,
122 PARSING_F,
123 PARSING_R,
124 PARSING_O,
125 PARSING_M,
126 OUT_MAIL
127};
128
129
130
131
132static inline int
133mailmbox_single_parse(char * str, size_t length,
134 size_t * index,
135 size_t * pstart,
136 size_t * pstart_len,
137 size_t * pheaders,
138 size_t * pheaders_len,
139 size_t * pbody,
140 size_t * pbody_len,
141 size_t * psize,
142 size_t * ppadding,
143 uint32_t * puid)
144{
145 size_t cur_token;
146 size_t start;
147 size_t start_len;
148 size_t headers;
149 size_t headers_len;
150 size_t body;
151 size_t end;
152 size_t next;
153 size_t message_length;
154 uint32_t uid;
155 int r;
156#if 0
157 int in_mail_data;
158#endif
159#if 0
160 size_t begin;
161#endif
162
163 int state;
164
165 cur_token = * index;
166
167 if (cur_token >= length)
168 return MAILMBOX_ERROR_PARSE;
169
170 start = cur_token;
171 start_len = 0;
172 headers = cur_token;
173
174 if (cur_token + 5 < length) {
175 if (strncmp(str + cur_token, "From ", 5) == 0) {
176 cur_token += 5;
177 while (str[cur_token] != '\n') {
178 cur_token ++;
179 if (cur_token >= length)
180 break;
181 }
182 if (cur_token < length) {
183 cur_token ++;
184 headers = cur_token;
185 start_len = headers - start;
186 }
187 }
188 }
189
190 next = length;
191
192 r = mailmbox_fields_parse(str, length, &cur_token,
193 &uid, &headers_len);
194 if (r != MAILMBOX_NO_ERROR)
195 return r;
196
197 /* save position */
198#if 0
199 begin = cur_token;
200#endif
201
202 mailimf_crlf_parse(str, length, &cur_token);
203
204#if 0
205 if (str[cur_token] == 'F') {
206 printf("start !\n");
207 printf("%50.50s\n", str + cur_token);
208 getchar();
209 }
210#endif
211
212 body = cur_token;
213
214 /* restore position */
215 /* cur_token = begin; */
216
217 state = FIRST_LF;
218
219 end = length;
220
221#if 0
222 in_mail_data = 0;
223#endif
224 while (state != OUT_MAIL) {
225
226 if (cur_token >= length) {
227 if (state == IN_MAIL)
228 end = length;
229 next = length;
230 break;
231 }
232
233 switch(state) {
234 case IN_MAIL:
235 switch(str[cur_token]) {
236 case '\r':
237 state = FIRST_CR;
238 break;
239 case '\n':
240 state = FIRST_LF;
241 break;
242 case 'F':
243 if (cur_token == body) {
244 end = cur_token;
245 next = cur_token;
246 state = PARSING_F;
247 }
248 break;
249#if 0
250 default:
251 in_mail_data = 1;
252 break;
253#endif
254 }
255 break;
256
257 case FIRST_CR:
258 end = cur_token;
259 switch(str[cur_token]) {
260 case '\r':
261 state = SECOND_CR;
262 break;
263 case '\n':
264 state = FIRST_LF;
265 break;
266 default:
267 state = IN_MAIL;
268#if 0
269 in_mail_data = 1;
270#endif
271 break;
272 }
273 break;
274
275 case FIRST_LF:
276 end = cur_token;
277 switch(str[cur_token]) {
278 case '\r':
279 state = SECOND_CR;
280 break;
281 case '\n':
282 state = SECOND_LF;
283 break;
284 default:
285 state = IN_MAIL;
286#if 0
287 in_mail_data = 1;
288#endif
289 break;
290 }
291 break;
292
293 case SECOND_CR:
294 switch(str[cur_token]) {
295 case '\r':
296 end = cur_token;
297 break;
298 case '\n':
299 state = SECOND_LF;
300 break;
301 case 'F':
302 next = cur_token;
303 state = PARSING_F;
304 break;
305 default:
306 state = IN_MAIL;
307#if 0
308 in_mail_data = 1;
309#endif
310 break;
311 }
312 break;
313
314 case SECOND_LF:
315 switch(str[cur_token]) {
316 case '\r':
317 state = SECOND_CR;
318 break;
319 case '\n':
320 end = cur_token;
321 break;
322 case 'F':
323 next = cur_token;
324 state = PARSING_F;
325 break;
326 default:
327 state = IN_MAIL;
328#if 0
329 in_mail_data = 1;
330#endif
331 break;
332 }
333 break;
334
335 case PARSING_F:
336 switch(str[cur_token]) {
337 case 'r':
338 state = PARSING_R;
339 break;
340 default:
341 state = IN_MAIL;
342#if 0
343 in_mail_data = 1;
344#endif
345 break;
346 }
347 break;
348
349 case PARSING_R:
350 switch(str[cur_token]) {
351 case 'o':
352 state = PARSING_O;
353 break;
354 default:
355 state = IN_MAIL;
356#if 0
357 in_mail_data = 1;
358#endif
359 break;
360 }
361 break;
362
363 case PARSING_O:
364 switch(str[cur_token]) {
365 case 'm':
366 state = PARSING_M;
367 break;
368 default:
369 state = IN_MAIL;
370#if 0
371 in_mail_data = 1;
372#endif
373 break;
374 }
375 break;
376
377 case PARSING_M:
378 switch(str[cur_token]) {
379 case ' ':
380 state = OUT_MAIL;
381 break;
382 default:
383 state = IN_MAIL;
384 break;
385 }
386 break;
387 }
388
389 cur_token ++;
390 }
391
392 message_length = end - start;
393
394 * pstart = start;
395 * pstart_len = start_len;
396 * pheaders = headers;
397 * pheaders_len = headers_len;
398 * pbody = body;
399 * pbody_len = end - body;
400 * psize = message_length;
401 * ppadding = next - end;
402 * puid = uid;
403
404 * index = next;
405
406 return MAILMBOX_NO_ERROR;
407}
408
409
410int
411mailmbox_parse_additionnal(struct mailmbox_folder * folder,
412 size_t * index)
413{
414 size_t cur_token;
415
416 size_t start;
417 size_t start_len;
418 size_t headers;
419 size_t headers_len;
420 size_t body;
421 size_t body_len;
422 size_t size;
423 size_t padding;
424 uint32_t uid;
425 int r;
426 int res;
427
428 uint32_t max_uid;
429 uint32_t first_index;
430 unsigned int i;
431 unsigned int j;
432
433 cur_token = * index;
434
435 /* remove temporary UID that we will parse */
436
437 first_index = carray_count(folder->mb_tab);
438
439 for(i = 0 ; i < carray_count(folder->mb_tab) ; i++) {
440 struct mailmbox_msg_info * info;
441
442 info = carray_get(folder->mb_tab, i);
443
444 if (info->msg_start < cur_token) {
445 continue;
446 }
447
448 if (!info->msg_written_uid) {
449 chashdatum key;
450
451 key.data = &info->msg_uid;
452 key.len = sizeof(info->msg_uid);
453
454 chash_delete(folder->mb_hash, &key, NULL);
455 carray_delete_fast(folder->mb_tab, i);
456 mailmbox_msg_info_free(info);
457 if (i < first_index)
458 first_index = i;
459 }
460 }
461
462 /* make a sequence in the table */
463
464 max_uid = folder->mb_written_uid;
465
466 i = 0;
467 j = 0;
468 while (i < carray_count(folder->mb_tab)) {
469 struct mailmbox_msg_info * info;
470
471 info = carray_get(folder->mb_tab, i);
472 if (info != NULL) {
473 carray_set(folder->mb_tab, j, info);
474
475 if (info->msg_uid > max_uid)
476 max_uid = info->msg_uid;
477
478 info->msg_index = j;
479 j ++;
480 }
481 i ++;
482 }
483 carray_set_size(folder->mb_tab, j);
484
485 /* parse content */
486
487 first_index = j;
488
489 while (1) {
490 struct mailmbox_msg_info * info;
491 chashdatum key;
492 chashdatum data;
493
494 r = mailmbox_single_parse(folder->mb_mapping, folder->mb_mapping_size,
495 &cur_token,
496 &start, &start_len,
497 &headers, &headers_len,
498 &body, &body_len,
499 &size, &padding, &uid);
500 if (r == MAILMBOX_NO_ERROR) {
501 /* do nothing */
502 }
503 else if (r == MAILMBOX_ERROR_PARSE)
504 break;
505 else {
506 res = r;
507 goto err;
508 }
509
510 key.data = &uid;
511 key.len = sizeof(uid);
512
513 r = chash_get(folder->mb_hash, &key, &data);
514 if (r == 0) {
515 info = data.data;
516
517 if (!info->msg_written_uid) {
518 /* some new mail has been written and override an
519 existing temporary UID */
520
521 chash_delete(folder->mb_hash, &key, NULL);
522 info->msg_uid = 0;
523
524 if (info->msg_index < first_index)
525 first_index = info->msg_index;
526 }
527 else
528 uid = 0;
529 }
530
531 if (uid > max_uid)
532 max_uid = uid;
533
534 r = mailmbox_msg_info_update(folder,
535 start, start_len, headers, headers_len,
536 body, body_len, size, padding, uid);
537 if (r != MAILMBOX_NO_ERROR) {
538 res = r;
539 goto err;
540 }
541 }
542
543 * index = cur_token;
544
545 folder->mb_written_uid = max_uid;
546
547 /* attribute uid */
548
549 for(i = first_index ; i < carray_count(folder->mb_tab) ; i ++) {
550 struct mailmbox_msg_info * info;
551 chashdatum key;
552 chashdatum data;
553
554 info = carray_get(folder->mb_tab, i);
555
556 if (info->msg_uid != 0) {
557 continue;
558 }
559
560 max_uid ++;
561 info->msg_uid = max_uid;
562
563 key.data = &info->msg_uid;
564 key.len = sizeof(info->msg_uid);
565 data.data = info;
566 data.len = 0;
567
568 r = chash_set(folder->mb_hash, &key, &data, NULL);
569 if (r < 0) {
570 res = MAILMBOX_ERROR_MEMORY;
571 goto err;
572 }
573 }
574
575 folder->mb_max_uid = max_uid;
576
577 return MAILMBOX_NO_ERROR;
578
579 err:
580 return res;
581}
582
583static void flush_uid(struct mailmbox_folder * folder)
584{
585 unsigned int i;
586
587 for(i = 0 ; i < carray_count(folder->mb_tab) ; i++) {
588 struct mailmbox_msg_info * info;
589
590 info = carray_get(folder->mb_tab, i);
591 if (info != NULL)
592 mailmbox_msg_info_free(info);
593 }
594
595 chash_clear(folder->mb_hash);
596 carray_set_size(folder->mb_tab, 0);
597}
598
599int mailmbox_parse(struct mailmbox_folder * folder)
600{
601 int r;
602 int res;
603 size_t cur_token;
604
605 flush_uid(folder);
606
607 cur_token = 0;
608
609 r = mailmbox_parse_additionnal(folder, &cur_token);
610
611 if (r != MAILMBOX_NO_ERROR) {
612 res = r;
613 goto err;
614 }
615
616 return MAILMBOX_NO_ERROR;
617
618 err:
619 return res;
620}
diff --git a/kmicromail/libetpan/mbox/mailmbox_parse.h b/kmicromail/libetpan/mbox/mailmbox_parse.h
new file mode 100644
index 0000000..8d3d1d8
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_parse.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_PARSE_H
37
38#define MAILMBOX_PARSE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailmbox_types.h"
45
46int mailmbox_parse(struct mailmbox_folder * folder);
47
48int
49mailmbox_parse_additionnal(struct mailmbox_folder * folder,
50 size_t * index);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/mbox/mailmbox_types.c b/kmicromail/libetpan/mbox/mailmbox_types.c
new file mode 100644
index 0000000..1986182
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_types.c
@@ -0,0 +1,250 @@
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 "mailmbox_types.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#ifndef TRUE
42#define TRUE 1
43#endif
44
45#ifndef FALSE
46#define FALSE 0
47#endif
48
49/* *********************************************************************** */
50
51int mailmbox_msg_info_update(struct mailmbox_folder * folder,
52 size_t msg_start, size_t msg_start_len,
53 size_t msg_headers, size_t msg_headers_len,
54 size_t msg_body, size_t msg_body_len,
55 size_t msg_size, size_t msg_padding,
56 uint32_t msg_uid)
57{
58 struct mailmbox_msg_info * info;
59 int res;
60 chashdatum key;
61 chashdatum data;
62 int r;
63
64 key.data = &msg_uid;
65 key.len = sizeof(msg_uid);
66 r = chash_get(folder->mb_hash, &key, &data);
67 if (r < 0) {
68 unsigned int index;
69
70 info = mailmbox_msg_info_new(msg_start, msg_start_len,
71 msg_headers, msg_headers_len,
72 msg_body, msg_body_len, msg_size, msg_padding, msg_uid);
73 if (info == NULL) {
74 res = MAILMBOX_ERROR_MEMORY;
75 goto err;
76 }
77
78 r = carray_add(folder->mb_tab, info, &index);
79 if (r < 0) {
80 mailmbox_msg_info_free(info);
81 res = MAILMBOX_ERROR_MEMORY;
82 goto err;
83 }
84
85 if (msg_uid != 0) {
86 chashdatum key;
87 chashdatum data;
88
89 key.data = &msg_uid;
90 key.len = sizeof(msg_uid);
91 data.data = info;
92 data.len = 0;
93
94 r = chash_set(folder->mb_hash, &key, &data, NULL);
95 if (r < 0) {
96 mailmbox_msg_info_free(info);
97 carray_delete(folder->mb_tab, index);
98 res = MAILMBOX_ERROR_MEMORY;
99 goto err;
100 }
101 }
102
103 info->msg_index = index;
104 }
105 else {
106 info = data.data;
107
108 info->msg_start = msg_start;
109 info->msg_start_len = msg_start_len;
110 info->msg_headers = msg_headers;
111 info->msg_headers_len = msg_headers_len;
112 info->msg_body = msg_body;
113 info->msg_body_len = msg_body_len;
114 info->msg_size = msg_size;
115 info->msg_padding = msg_padding;
116 }
117
118 return MAILMBOX_NO_ERROR;
119
120 err:
121 return res;
122}
123
124
125struct mailmbox_msg_info *
126mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len,
127 size_t msg_headers, size_t msg_headers_len,
128 size_t msg_body, size_t msg_body_len,
129 size_t msg_size, size_t msg_padding,
130 uint32_t msg_uid)
131{
132 struct mailmbox_msg_info * info;
133
134 info = malloc(sizeof(* info));
135 if (info == NULL)
136 return NULL;
137
138 info->msg_index = 0;
139 info->msg_uid = msg_uid;
140 if (msg_uid != 0)
141 info->msg_written_uid = TRUE;
142 else
143 info->msg_written_uid = FALSE;
144 info->msg_deleted = FALSE;
145
146 info->msg_start = msg_start;
147 info->msg_start_len = msg_start_len;
148
149 info->msg_headers = msg_headers;
150 info->msg_headers_len = msg_headers_len;
151
152 info->msg_body = msg_body;
153 info->msg_body_len = msg_body_len;
154
155 info->msg_size = msg_size;
156
157 info->msg_padding = msg_padding;
158
159 return info;
160}
161
162void mailmbox_msg_info_free(struct mailmbox_msg_info * info)
163{
164 free(info);
165}
166
167
168/* append info */
169
170struct mailmbox_append_info *
171mailmbox_append_info_new(const char * ai_message, size_t ai_size)
172{
173 struct mailmbox_append_info * info;
174
175 info = malloc(sizeof(* info));
176 if (info == NULL)
177 return NULL;
178
179 info->ai_message = ai_message;
180 info->ai_size = ai_size;
181
182 return info;
183}
184
185void mailmbox_append_info_free(struct mailmbox_append_info * info)
186{
187 free(info);
188}
189
190struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename)
191{
192 struct mailmbox_folder * folder;
193
194 folder = malloc(sizeof(* folder));
195 if (folder == NULL)
196 goto err;
197
198 strncpy(folder->mb_filename, mb_filename, PATH_MAX);
199
200 folder->mb_mtime = (time_t) -1;
201
202 folder->mb_fd = -1;
203 folder->mb_read_only = TRUE;
204 folder->mb_no_uid = TRUE;
205
206 folder->mb_changed = FALSE;
207 folder->mb_deleted_count = 0;
208
209 folder->mb_mapping = NULL;
210 folder->mb_mapping_size = 0;
211
212 folder->mb_written_uid = 0;
213 folder->mb_max_uid = 0;
214
215 folder->mb_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
216 if (folder->mb_hash == NULL)
217 goto free;
218
219 folder->mb_tab = carray_new(128);
220 if (folder->mb_tab == NULL)
221 goto free_hash;
222
223 return folder;
224
225 free_hash:
226 chash_free(folder->mb_hash);
227 free:
228 free(folder);
229 err:
230 return NULL;
231}
232
233void mailmbox_folder_free(struct mailmbox_folder * folder)
234{
235 unsigned int i;
236
237 for(i = 0 ; i < carray_count(folder->mb_tab) ; i++) {
238 struct mailmbox_msg_info * info;
239
240 info = carray_get(folder->mb_tab, i);
241 if (info != NULL)
242 mailmbox_msg_info_free(info);
243 }
244
245 carray_free(folder->mb_tab);
246
247 chash_free(folder->mb_hash);
248
249 free(folder);
250}
diff --git a/kmicromail/libetpan/mbox/mailmbox_types.h b/kmicromail/libetpan/mbox/mailmbox_types.h
new file mode 100644
index 0000000..dd6758c
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_types.h
@@ -0,0 +1,142 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_TYPES_H
37
38#define MAILMBOX_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45
46#include <libetpan/libetpan-config.h>
47
48#include <libetpan/mailimf.h>
49#include <libetpan/carray.h>
50#include <libetpan/chash.h>
51
52enum {
53 MAILMBOX_NO_ERROR = 0,
54 MAILMBOX_ERROR_PARSE,
55 MAILMBOX_ERROR_INVAL,
56 MAILMBOX_ERROR_FILE_NOT_FOUND,
57 MAILMBOX_ERROR_MEMORY,
58 MAILMBOX_ERROR_TEMPORARY_FILE,
59 MAILMBOX_ERROR_FILE,
60 MAILMBOX_ERROR_MSG_NOT_FOUND,
61 MAILMBOX_ERROR_READONLY,
62};
63
64
65struct mailmbox_folder {
66 char mb_filename[PATH_MAX];
67
68 time_t mb_mtime;
69
70 int mb_fd;
71 int mb_read_only;
72 int mb_no_uid;
73
74 int mb_changed;
75 unsigned int mb_deleted_count;
76
77 char * mb_mapping;
78 size_t mb_mapping_size;
79
80 uint32_t mb_written_uid;
81 uint32_t mb_max_uid;
82
83 chash * mb_hash;
84 carray * mb_tab;
85};
86
87struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename);
88void mailmbox_folder_free(struct mailmbox_folder * folder);
89
90
91struct mailmbox_msg_info {
92 unsigned int msg_index;
93 uint32_t msg_uid;
94 int msg_written_uid;
95 int msg_deleted;
96
97 size_t msg_start;
98 size_t msg_start_len;
99
100 size_t msg_headers;
101 size_t msg_headers_len;
102
103 size_t msg_body;
104 size_t msg_body_len;
105
106 size_t msg_size;
107
108 size_t msg_padding;
109};
110
111
112int mailmbox_msg_info_update(struct mailmbox_folder * folder,
113 size_t msg_start, size_t msg_start_len,
114 size_t msg_headers, size_t msg_headers_len,
115 size_t msg_body, size_t msg_body_len,
116 size_t msg_size, size_t msg_padding,
117 uint32_t msg_uid);
118
119struct mailmbox_msg_info *
120mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len,
121 size_t msg_headers, size_t msg_headers_len,
122 size_t msg_body, size_t msg_body_len,
123 size_t msg_size, size_t msg_padding,
124 uint32_t msg_uid);
125
126void mailmbox_msg_info_free(struct mailmbox_msg_info * info);
127
128struct mailmbox_append_info {
129 const char * ai_message;
130 size_t ai_size;
131};
132
133struct mailmbox_append_info *
134mailmbox_append_info_new(const char * ai_message, size_t ai_size);
135
136void mailmbox_append_info_free(struct mailmbox_append_info * info);
137
138#ifdef __cplusplus
139}
140#endif
141
142#endif