summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/tests/readmsg-common.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/tests/readmsg-common.c') (more/less context) (show whitespace changes)
-rw-r--r--kmicromail/libetpan/tests/readmsg-common.c720
1 files changed, 720 insertions, 0 deletions
diff --git a/kmicromail/libetpan/tests/readmsg-common.c b/kmicromail/libetpan/tests/readmsg-common.c
new file mode 100644
index 0000000..060497d
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-common.c
@@ -0,0 +1,720 @@
1#include "readmsg-common.h"
2
3#include <sys/stat.h>
4#include <sys/mman.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdlib.h>
9
10/* returns TRUE is given MIME part is a text part */
11
12int etpan_mime_is_text(struct mailmime * build_info)
13{
14 if (build_info->mm_type == MAILMIME_SINGLE) {
15 if (build_info->mm_content_type != NULL) {
16 if (build_info->mm_content_type->ct_type->tp_type ==
17 MAILMIME_TYPE_DISCRETE_TYPE) {
18 if (build_info->mm_content_type->ct_type->tp_data.tp_discrete_type->dt_type ==
19 MAILMIME_DISCRETE_TYPE_TEXT)
20 return 1;
21 }
22 }
23 else
24 return 1;
25 }
26
27 return 0;
28}
29
30
31/* display content type */
32
33int show_part_info(FILE * f,
34 struct mailmime_single_fields * mime_fields,
35 struct mailmime_content * content)
36{
37 char * description;
38 char * filename;
39 int col;
40 int r;
41
42 description = mime_fields->fld_description;
43 filename = mime_fields->fld_disposition_filename;
44
45 col = 0;
46
47 r = fprintf(f, " [ Part ");
48 if (r < 0)
49 goto err;
50
51 if (content != NULL) {
52 r = mailmime_content_type_write(f, &col, content);
53 if (r != MAILIMF_NO_ERROR)
54 goto err;
55 }
56
57 if (filename != NULL) {
58 r = fprintf(f, " (%s)", filename);
59 if (r < 0)
60 goto err;
61 }
62
63 if (description != NULL) {
64 r = fprintf(f, " : %s", description);
65 if (r < 0)
66 goto err;
67 }
68
69 r = fprintf(f, " ]\n\n");
70 if (r < 0)
71 goto err;
72
73 return NO_ERROR;
74
75 err:
76 return ERROR_FILE;
77}
78
79/*
80 fetch the data of the mailmime_data structure whether it is a file
81 or a string.
82
83 data must be freed with mmap_string_unref()
84*/
85
86#if 0
87static int fetch_data(struct mailmime_data * data,
88 char ** result, size_t * result_len)
89{
90 int fd;
91 int r;
92 char * text;
93 struct stat buf;
94 int res;
95 MMAPString * mmapstr;
96
97 switch (data->dt_type) {
98 case MAILMIME_DATA_TEXT:
99 mmapstr = mmap_string_new_len(data->dt_data.dt_text.dt_data,
100 data->dt_data.dt_text.dt_length);
101 if (mmapstr == NULL) {
102 res = ERROR_MEMORY;
103 goto err;
104 }
105
106 * result = mmapstr->str;
107 * result_len = mmapstr->len;
108
109 return NO_ERROR;
110
111 case MAILMIME_DATA_FILE:
112 fd = open(data->dt_data.dt_filename, O_RDONLY);
113 if (fd < 0) {
114 res = ERROR_FILE;
115 goto err;
116 }
117
118 r = fstat(fd, &buf);
119 if (r < 0) {
120 res = ERROR_FILE;
121 goto close;
122 }
123
124 if (buf.st_size != 0) {
125 text = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
126 if (text == MAP_FAILED) {
127 res = ERROR_FILE;
128 goto close;
129 }
130
131 mmapstr = mmap_string_new_len(text, buf.st_size);
132 if (mmapstr == NULL) {
133 res = r;
134 goto unmap;
135 }
136
137 munmap(text, buf.st_size);
138 }
139 else {
140 mmapstr = mmap_string_new("");
141 if (mmapstr == NULL) {
142 res = r;
143 goto close;
144 }
145 }
146
147 close(fd);
148
149 * result = mmapstr->str;
150 * result_len = mmapstr->len;
151
152 return NO_ERROR;
153
154 default:
155 return ERROR_INVAL;
156 }
157
158 unmap:
159 munmap(text, buf.st_size);
160 close:
161 close(fd);
162 err:
163 return res;
164}
165#endif
166
167/* fetch message and decode if it is base64 or quoted-printable */
168
169int etpan_fetch_message(mailmessage * msg_info,
170 struct mailmime * mime_part,
171 struct mailmime_single_fields * fields,
172 char ** result, size_t * result_len)
173{
174 char * data;
175 size_t len;
176 int r;
177 int encoding;
178 char * decoded;
179 size_t decoded_len;
180 size_t cur_token;
181 int res;
182 int encoded;
183
184 encoded = 0;
185
186 r = mailmessage_fetch_section(msg_info,
187 mime_part, &data, &len);
188 if (r != MAIL_NO_ERROR) {
189 res = ERROR_FETCH;
190 goto err;
191 }
192
193 encoded = 1;
194
195 /* decode message */
196
197 if (encoded) {
198 if (fields->fld_encoding != NULL)
199 encoding = fields->fld_encoding->enc_type;
200 else
201 encoding = MAILMIME_MECHANISM_8BIT;
202 }
203 else {
204 encoding = MAILMIME_MECHANISM_8BIT;
205 }
206
207 cur_token = 0;
208 r = mailmime_part_parse(data, len, &cur_token,
209 encoding, &decoded, &decoded_len);
210 if (r != MAILIMF_NO_ERROR) {
211 res = ERROR_FETCH;
212 goto free;
213 }
214
215 mailmessage_fetch_result_free(msg_info, data);
216
217 * result = decoded;
218 * result_len = decoded_len;
219
220 return NO_ERROR;
221
222 free:
223 mailmessage_fetch_result_free(msg_info, data);
224 err:
225 return res;
226}
227
228
229/* fetch fields */
230
231struct mailimf_fields * fetch_fields(mailmessage * msg_info,
232 struct mailmime * mime)
233{
234 char * data;
235 size_t len;
236 int r;
237 size_t cur_token;
238 struct mailimf_fields * fields;
239
240 r = mailmessage_fetch_section_header(msg_info, mime, &data, &len);
241 if (r != MAIL_NO_ERROR)
242 return NULL;
243
244 cur_token = 0;
245 r = mailimf_fields_parse(data, len, &cur_token, &fields);
246 if (r != MAILIMF_NO_ERROR) {
247 mailmessage_fetch_result_free(msg_info, data);
248 return NULL;
249 }
250
251 mailmessage_fetch_result_free(msg_info, data);
252
253 return fields;
254}
255
256
257
258#define MAX_MAIL_COL 72
259
260/* write decoded mailbox */
261
262static int
263etpan_mailbox_write(FILE * f, int * col,
264 struct mailimf_mailbox * mb)
265{
266 int r;
267
268 if (* col > 1) {
269
270 if (* col + strlen(mb->mb_addr_spec) >= MAX_MAIL_COL) {
271 r = mailimf_string_write(f, col, "\r\n ", 3);
272 if (r != MAILIMF_NO_ERROR)
273 return ERROR_FILE;
274 * col = 1;
275 }
276 }
277
278 if (mb->mb_display_name) {
279 char * decoded_from;
280 size_t cur_token;
281
282 cur_token = 0;
283 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
284 mb->mb_display_name, strlen(mb->mb_display_name),
285 &cur_token, DEST_CHARSET,
286 &decoded_from);
287 if (r != MAILIMF_NO_ERROR) {
288 decoded_from = strdup(mb->mb_display_name);
289 if (decoded_from == NULL)
290 return ERROR_MEMORY;
291 }
292
293 r = mailimf_quoted_string_write(f, col, decoded_from,
294 strlen(decoded_from));
295 if (r != MAILIMF_NO_ERROR) {
296 free(decoded_from);
297 return ERROR_FILE;
298 }
299
300 if (* col > 1) {
301
302 if (* col + strlen(decoded_from) + 3 >= MAX_MAIL_COL) {
303 r = mailimf_string_write(f, col, "\r\n ", 3);
304 if (r != MAILIMF_NO_ERROR) {
305 free(decoded_from);
306 return r;
307 }
308 * col = 1;
309 }
310 }
311
312 free(decoded_from);
313
314 r = mailimf_string_write(f, col, " <", 2);
315 if (r != MAILIMF_NO_ERROR)
316 return ERROR_FILE;
317
318 r = mailimf_string_write(f, col,
319 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
320 if (r != MAILIMF_NO_ERROR)
321 return ERROR_FILE;
322
323 r = mailimf_string_write(f, col, ">", 1);
324 if (r != MAILIMF_NO_ERROR)
325 return ERROR_FILE;
326 }
327 else {
328 r = mailimf_string_write(f, col,
329 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
330 if (r != MAILIMF_NO_ERROR)
331 return ERROR_FILE;
332 }
333
334
335 return NO_ERROR;
336
337}
338
339/* write decoded mailbox list */
340
341int
342etpan_mailbox_list_write(FILE * f, int * col,
343 struct mailimf_mailbox_list * mb_list)
344{
345 clistiter * cur;
346 int r;
347 int first;
348
349 first = 1;
350
351 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
352 cur = clist_next(cur)) {
353 struct mailimf_mailbox * mb;
354
355 mb = cur->data;
356
357 if (!first) {
358 r = mailimf_string_write(f, col, ", ", 2);
359 if (r != MAILIMF_NO_ERROR)
360 return ERROR_FILE;
361 }
362 else {
363 first = 0;
364 }
365
366 r = etpan_mailbox_write(f, col, mb);
367 if (r != NO_ERROR)
368 return r;
369 }
370
371 return NO_ERROR;
372}
373
374/* write decoded group */
375
376static int
377etpan_group_write(FILE * f, int * col,
378 struct mailimf_group * group)
379{
380 int r;
381
382 r = mailimf_string_write(f, col, group->grp_display_name,
383 strlen(group->grp_display_name));
384 if (r != MAILIMF_NO_ERROR)
385 return ERROR_FILE;
386
387 r = mailimf_string_write(f, col, ": ", 2);
388 if (r != MAILIMF_NO_ERROR)
389 return ERROR_FILE;
390
391 if (group->grp_mb_list != NULL) {
392 r = etpan_mailbox_list_write(f, col, group->grp_mb_list);
393 if (r != NO_ERROR)
394 return r;
395 }
396
397 r = mailimf_string_write(f, col, ";", 1);
398 if (r != MAILIMF_NO_ERROR)
399 return ERROR_FILE;
400
401 return NO_ERROR;
402}
403
404/* write decoded address */
405
406int
407etpan_address_write(FILE * f, int * col,
408 struct mailimf_address * addr)
409{
410 int r;
411
412 switch(addr->ad_type) {
413 case MAILIMF_ADDRESS_MAILBOX:
414 r = etpan_mailbox_write(f, col, addr->ad_data.ad_mailbox);
415 if (r != NO_ERROR)
416 return r;
417
418 break;
419
420 case MAILIMF_ADDRESS_GROUP:
421 r = etpan_group_write(f, col, addr->ad_data.ad_group);
422 if (r != NO_ERROR)
423 return r;
424
425 break;
426 }
427
428 return MAILIMF_NO_ERROR;
429}
430
431/* write decoded address list */
432
433int
434etpan_address_list_write(FILE * f, int * col,
435 struct mailimf_address_list * addr_list)
436{
437 clistiter * cur;
438 int r;
439 int first;
440
441 first = 1;
442
443 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
444 cur = clist_next(cur)) {
445 struct mailimf_address * addr;
446
447 addr = clist_content(cur);
448
449 if (!first) {
450 r = mailimf_string_write(f, col, ", ", 2);
451 if (r != MAILIMF_NO_ERROR)
452 return ERROR_FILE;
453 }
454 else {
455 first = 0;
456 }
457
458 r = etpan_address_write(f, col, addr);
459 if (r != NO_ERROR)
460 return r;
461 }
462
463 return NO_ERROR;
464}
465
466/* write decoded subject */
467
468static int etpan_subject_write(FILE * f, int * col,
469 char * subject)
470{
471 int r;
472 char * decoded_subject;
473 size_t cur_token;
474
475 r = mailimf_string_write(f, col, "Subject: ", 9);
476 if (r != MAILIMF_NO_ERROR) {
477 return ERROR_FILE;
478 }
479
480 cur_token = 0;
481 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
482 subject, strlen(subject),
483 &cur_token, DEST_CHARSET,
484 &decoded_subject);
485 if (r != MAILIMF_NO_ERROR) {
486 decoded_subject = strdup(subject);
487 if (decoded_subject == NULL)
488 return ERROR_MEMORY;
489 }
490
491 r = mailimf_string_write(f, col, decoded_subject, strlen(decoded_subject));
492 if (r != MAILIMF_NO_ERROR) {
493 free(decoded_subject);
494 return ERROR_FILE;
495 }
496
497 free(decoded_subject);
498
499 r = mailimf_string_write(f, col, "\r\n", 2);
500 if (r != MAILIMF_NO_ERROR) {
501 return ERROR_FILE;
502 }
503 * col = 0;
504
505 return NO_ERROR;
506}
507
508/* write decoded fields */
509
510int fields_write(FILE * f, int * col,
511 struct mailimf_fields * fields)
512{
513 clistiter * cur;
514 int r;
515
516 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
517 cur = clist_next(cur)) {
518 struct mailimf_field * field;
519
520 field = clist_content(cur);
521
522 switch (field->fld_type) {
523 case MAILIMF_FIELD_FROM:
524 r = mailimf_string_write(f, col, "From: ", 6);
525 if (r != MAILIMF_NO_ERROR)
526 goto err;
527
528 r = etpan_mailbox_list_write(f, col,
529 field->fld_data.fld_from->frm_mb_list);
530 if (r != NO_ERROR)
531 goto err;
532
533 r = mailimf_string_write(f, col, "\r\n", 2);
534 if (r != MAILIMF_NO_ERROR)
535 goto err;
536 * col = 0;
537
538 break;
539
540 case MAILIMF_FIELD_REPLY_TO:
541 r = mailimf_string_write(f, col, "Reply-To: ", 10);
542 if (r != MAILIMF_NO_ERROR)
543 goto err;
544
545 r = etpan_address_list_write(f, col,
546 field->fld_data.fld_reply_to->rt_addr_list);
547 if (r != NO_ERROR)
548 goto err;
549
550 r = mailimf_string_write(f, col, "\r\n", 2);
551 if (r != MAILIMF_NO_ERROR)
552 goto err;
553 * col = 0;
554
555 break;
556
557 case MAILIMF_FIELD_TO:
558 r = mailimf_string_write(f, col, "To: ", 4);
559 if (r != MAILIMF_NO_ERROR)
560 goto err;
561
562 r = etpan_address_list_write(f, col,
563 field->fld_data.fld_to->to_addr_list);
564 if (r != NO_ERROR)
565 goto err;
566
567 r = mailimf_string_write(f, col, "\r\n", 2);
568 if (r != MAILIMF_NO_ERROR)
569 goto err;
570 * col = 0;
571
572 break;
573
574 case MAILIMF_FIELD_CC:
575 r = mailimf_string_write(f, col, "Cc: ", 4);
576 if (r != MAILIMF_NO_ERROR)
577 goto err;
578
579 r = etpan_address_list_write(f, col,
580 field->fld_data.fld_cc->cc_addr_list);
581 if (r != NO_ERROR)
582 goto err;
583
584 r = mailimf_string_write(f, col, "\r\n", 2);
585 if (r != MAILIMF_NO_ERROR)
586 goto err;
587 * col = 0;
588
589 break;
590
591 case MAILIMF_FIELD_BCC:
592 r = mailimf_string_write(f, col, "Bcc: ", 10);
593 if (r != MAILIMF_NO_ERROR)
594 goto err;
595
596 if (field->fld_data.fld_bcc->bcc_addr_list != NULL) {
597 r = etpan_address_list_write(f, col,
598 field->fld_data.fld_bcc->bcc_addr_list);
599 if (r != NO_ERROR)
600 goto err;
601 }
602
603 r = mailimf_string_write(f, col, "\r\n", 2);
604 if (r != MAILIMF_NO_ERROR)
605 goto err;
606 * col = 0;
607
608 break;
609
610 case MAILIMF_FIELD_SUBJECT:
611 r = etpan_subject_write(f, col, field->fld_data.fld_subject->sbj_value);
612 if (r != MAILIMF_NO_ERROR)
613 goto err;
614 break;
615
616 case MAILIMF_FIELD_RESENT_FROM:
617 r = mailimf_string_write(f, col, "Resent-From: ", 13);
618 if (r != MAILIMF_NO_ERROR)
619 goto err;
620
621 r = etpan_mailbox_list_write(f, col,
622 field->fld_data.fld_resent_from->frm_mb_list);
623 if (r != NO_ERROR)
624 goto err;
625
626 r = mailimf_string_write(f, col, "\r\n", 2);
627 if (r != MAILIMF_NO_ERROR)
628 goto err;
629 * col = 0;
630 break;
631
632 case MAILIMF_FIELD_RESENT_TO:
633 r = mailimf_string_write(f, col, "Resent-To: ", 11);
634 if (r != MAILIMF_NO_ERROR)
635 goto err;
636
637 r = etpan_address_list_write(f, col,
638 field->fld_data.fld_resent_to->to_addr_list);
639 if (r != NO_ERROR)
640 goto err;
641
642 r = mailimf_string_write(f, col, "\r\n", 2);
643 if (r != MAILIMF_NO_ERROR)
644 goto err;
645 * col = 0;
646
647 break;
648 case MAILIMF_FIELD_RESENT_CC:
649 r = mailimf_string_write(f, col, "Resent-Cc: ", 11);
650 if (r != MAILIMF_NO_ERROR)
651 goto err;
652
653 r = etpan_address_list_write(f, col,
654 field->fld_data.fld_resent_cc->cc_addr_list);
655 if (r != NO_ERROR)
656 goto err;
657
658 r = mailimf_string_write(f, col, "\r\n", 2);
659 if (r != MAILIMF_NO_ERROR)
660 goto err;
661 * col = 0;
662
663 break;
664 case MAILIMF_FIELD_RESENT_BCC:
665 r = mailimf_string_write(f, col, "Resent-Bcc: ", 12);
666 if (r != MAILIMF_NO_ERROR)
667 goto err;
668
669 if (field->fld_data.fld_resent_bcc->bcc_addr_list != NULL) {
670 r = etpan_address_list_write(f, col,
671 field->fld_data.fld_resent_bcc->bcc_addr_list);
672 if (r != NO_ERROR)
673 goto err;
674 }
675
676 r = mailimf_string_write(f, col, "\r\n", 2);
677 if (r != MAILIMF_NO_ERROR)
678 goto err;
679 * col = 0;
680
681 break;
682
683 case MAILIMF_FIELD_ORIG_DATE:
684 case MAILIMF_FIELD_RESENT_DATE:
685 r = mailimf_field_write(f, col, field);
686 if (r != MAILIMF_NO_ERROR)
687 goto err;
688 break;
689
690 case MAILIMF_FIELD_OPTIONAL_FIELD:
691 if ((strcasecmp(field->fld_data.fld_optional_field->fld_name,
692 "X-Mailer") == 0)
693 || (strncasecmp(field->fld_data.fld_optional_field->fld_name,
694 "Resent-", 7) == 0)
695 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
696 "Newsgroups") == 0)
697 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
698 "Followup-To") == 0)
699 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
700 "User-Agent") == 0)) {
701 r = mailimf_field_write(f, col, field);
702 if (r != MAILIMF_NO_ERROR)
703 goto err;
704 }
705 break;
706
707 case MAILIMF_FIELD_MESSAGE_ID:
708 case MAILIMF_FIELD_SENDER:
709 case MAILIMF_FIELD_IN_REPLY_TO:
710 case MAILIMF_FIELD_REFERENCES:
711 default:
712 break;
713 }
714 }
715
716 return NO_ERROR;
717
718 err:
719 return ERROR_FILE;
720}