2 * libEtPan! -- a mail stuff library
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
38 #include "mailmbox_parse.h"
42 #include <sys/types.h>
47 #define UID_HEADER "X-LibEtPan-UID:"
68 claws_mailmbox_fields_parse(char * str
, size_t length
,
88 r
= mailimf_ignore_field_parse(str
, length
, &cur_token
);
90 case MAILIMF_NO_ERROR
:
91 if (str
[begin
] == 'X') {
93 if (strncasecmp(str
+ begin
, UID_HEADER
, strlen(UID_HEADER
)) == 0) {
94 begin
+= strlen(UID_HEADER
);
96 while (str
[begin
] == ' ')
99 uid
= strtoul(str
+ begin
, NULL
, 10);
104 case MAILIMF_ERROR_PARSE
:
111 hlen
= cur_token
- * index
;
117 return MAILMBOX_NO_ERROR
;
137 claws_mailmbox_single_parse(char * str
, size_t length
,
142 size_t * pheaders_len
,
157 size_t message_length
;
171 if (cur_token
>= length
)
172 return MAILMBOX_ERROR_PARSE
;
178 if (cur_token
+ 5 < length
) {
179 if (strncmp(str
+ cur_token
, "From ", 5) == 0) {
181 while (str
[cur_token
] != '\n') {
183 if (cur_token
>= length
)
186 if (cur_token
< length
) {
189 start_len
= headers
- start
;
196 r
= claws_mailmbox_fields_parse(str
, length
, &cur_token
,
198 if (r
!= MAILMBOX_NO_ERROR
)
206 mailimf_crlf_parse(str
, length
, &cur_token
);
209 if (str
[cur_token
] == 'F') {
211 printf("%50.50s\n", str
+ cur_token
);
218 /* restore position */
219 /* cur_token = begin; */
228 while (state
!= OUT_MAIL
) {
230 if (cur_token
>= length
) {
231 if (state
== IN_MAIL
)
239 switch(str
[cur_token
]) {
247 if (cur_token
== body
) {
263 switch(str
[cur_token
]) {
281 switch(str
[cur_token
]) {
298 switch(str
[cur_token
]) {
319 switch(str
[cur_token
]) {
340 switch(str
[cur_token
]) {
354 switch(str
[cur_token
]) {
368 switch(str
[cur_token
]) {
382 switch(str
[cur_token
]) {
396 message_length
= end
- start
;
399 * pstart_len
= start_len
;
400 * pheaders
= headers
;
401 * pheaders_len
= headers_len
;
403 * pbody_len
= end
- body
;
404 * psize
= message_length
;
405 * ppadding
= next
- end
;
410 return MAILMBOX_NO_ERROR
;
415 claws_mailmbox_parse_additionnal(struct claws_mailmbox_folder
* folder
,
433 uint32_t first_index
;
439 /* remove temporary UID that we will parse */
441 first_index
= carray_count(folder
->mb_tab
);
443 for(i
= 0 ; i
< carray_count(folder
->mb_tab
) ; i
++) {
444 struct claws_mailmbox_msg_info
* info
;
446 info
= carray_get(folder
->mb_tab
, i
);
448 if (info
->msg_start
< cur_token
) {
452 if (!info
->msg_written_uid
) {
455 key
.data
= &info
->msg_uid
;
456 key
.len
= sizeof(info
->msg_uid
);
458 chash_delete(folder
->mb_hash
, &key
, NULL
);
459 carray_delete_fast(folder
->mb_tab
, i
);
460 claws_mailmbox_msg_info_free(info
);
466 /* make a sequence in the table */
468 max_uid
= folder
->mb_written_uid
;
472 while (i
< carray_count(folder
->mb_tab
)) {
473 struct claws_mailmbox_msg_info
* info
;
475 info
= carray_get(folder
->mb_tab
, i
);
477 carray_set(folder
->mb_tab
, j
, info
);
479 if (info
->msg_uid
> max_uid
)
480 max_uid
= info
->msg_uid
;
487 carray_set_size(folder
->mb_tab
, j
);
494 struct claws_mailmbox_msg_info
* info
;
498 r
= claws_mailmbox_single_parse(folder
->mb_mapping
, folder
->mb_mapping_size
,
501 &headers
, &headers_len
,
503 &size
, &padding
, &uid
);
504 if (r
== MAILMBOX_NO_ERROR
) {
507 else if (r
== MAILMBOX_ERROR_PARSE
) {
515 key
.len
= sizeof(uid
);
517 r
= chash_get(folder
->mb_hash
, &key
, &data
);
521 if (!info
->msg_written_uid
) {
522 /* some new mail has been written and override an
523 existing temporary UID */
525 chash_delete(folder
->mb_hash
, &key
, NULL
);
528 if (info
->msg_index
< first_index
)
529 first_index
= info
->msg_index
;
538 r
= claws_mailmbox_msg_info_update(folder
,
539 start
, start_len
, headers
, headers_len
,
540 body
, body_len
, size
, padding
, uid
);
541 if (r
!= MAILMBOX_NO_ERROR
) {
542 debug_print("claws_mailmbox_msg_info_update failed with %d\n", r
);
550 folder
->mb_written_uid
= max_uid
;
554 for(i
= first_index
; i
< carray_count(folder
->mb_tab
) ; i
++) {
555 struct claws_mailmbox_msg_info
* info
;
559 info
= carray_get(folder
->mb_tab
, i
);
561 if (info
->msg_uid
!= 0) {
566 info
->msg_uid
= max_uid
;
568 key
.data
= &info
->msg_uid
;
569 key
.len
= sizeof(info
->msg_uid
);
573 r
= chash_set(folder
->mb_hash
, &key
, &data
, NULL
);
575 debug_print("chash_set failed with %d\n", r
);
576 res
= MAILMBOX_ERROR_MEMORY
;
581 folder
->mb_max_uid
= max_uid
;
583 return MAILMBOX_NO_ERROR
;
589 static void flush_uid(struct claws_mailmbox_folder
* folder
)
593 for(i
= 0 ; i
< carray_count(folder
->mb_tab
) ; i
++) {
594 struct claws_mailmbox_msg_info
* info
;
596 info
= carray_get(folder
->mb_tab
, i
);
598 claws_mailmbox_msg_info_free(info
);
601 chash_clear(folder
->mb_hash
);
602 carray_set_size(folder
->mb_tab
, 0);
605 int claws_mailmbox_parse(struct claws_mailmbox_folder
* folder
)
615 r
= claws_mailmbox_parse_additionnal(folder
, &cur_token
);
617 if (r
!= MAILMBOX_NO_ERROR
) {
622 return MAILMBOX_NO_ERROR
;