summaryrefslogtreecommitdiffabout
path: root/libetpan/src/low-level/imf/mailimf_write.c
Unidiff
Diffstat (limited to 'libetpan/src/low-level/imf/mailimf_write.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/low-level/imf/mailimf_write.c2021
1 files changed, 2021 insertions, 0 deletions
diff --git a/libetpan/src/low-level/imf/mailimf_write.c b/libetpan/src/low-level/imf/mailimf_write.c
new file mode 100644
index 0000000..7301f37
--- a/dev/null
+++ b/libetpan/src/low-level/imf/mailimf_write.c
@@ -0,0 +1,2021 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimf_write.h"
37
38#include <time.h>
39#include <string.h>
40#include <ctype.h>
41
42#define MAX_MAIL_COL 72
43
44#ifndef TRUE
45#define TRUE 1
46#endif
47
48#ifndef FALSE
49#define FALSE 0
50#endif
51
52#define MAX_VALID_IMF_LINE 998
53
54static int mailimf_orig_date_write(FILE * f, int * col,
55 struct mailimf_orig_date * date);
56static int mailimf_date_time_write(FILE * f, int * col,
57 struct mailimf_date_time * date_time);
58static int mailimf_from_write(FILE * f, int * col,
59 struct mailimf_from * from);
60static int mailimf_sender_write(FILE * f, int * col,
61 struct mailimf_sender * sender);
62static int mailimf_reply_to_write(FILE * f, int * col,
63 struct mailimf_reply_to * reply_to);
64static int mailimf_to_write(FILE * f, int * col,
65 struct mailimf_to * to);
66static int mailimf_cc_write(FILE * f, int * col,
67 struct mailimf_cc * to);
68static int mailimf_bcc_write(FILE * f, int * col,
69 struct mailimf_bcc * to);
70static int mailimf_message_id_write(FILE * f, int * col,
71 struct mailimf_message_id * message_id);
72static int mailimf_msg_id_list_write(FILE * f, int * col,
73 clist * list);
74static int mailimf_in_reply_to_write(FILE * f, int * col,
75 struct mailimf_in_reply_to *
76 in_reply_to);
77static int mailimf_references_write(FILE * f, int * col,
78 struct mailimf_references * references);
79static int mailimf_subject_write(FILE * f, int * col,
80 struct mailimf_subject * subject);
81
82static int mailimf_address_write(FILE * f, int * col,
83 struct mailimf_address * addr);
84static int mailimf_group_write(FILE * f, int * col,
85 struct mailimf_group * group);
86
87static int mailimf_mailbox_write(FILE * f, int * col,
88 struct mailimf_mailbox * mb);
89
90static int mailimf_comments_write(FILE * f, int * col,
91 struct mailimf_comments * comments);
92
93static int mailimf_optional_field_write(FILE * f, int * col,
94 struct mailimf_optional_field * field);
95
96static int mailimf_keywords_write(FILE * f, int * col,
97 struct mailimf_keywords * keywords);
98
99static int mailimf_return_write(FILE * f, int * col,
100 struct mailimf_return * return_path);
101
102static int mailimf_path_write(FILE * f, int * col,
103 struct mailimf_path * path);
104
105static int mailimf_resent_date_write(FILE * f, int * col,
106 struct mailimf_orig_date * date);
107
108static int mailimf_resent_from_write(FILE * f, int * col,
109 struct mailimf_from * from);
110
111static int mailimf_resent_sender_write(FILE * f, int * col,
112 struct mailimf_sender * sender);
113
114static int mailimf_resent_to_write(FILE * f, int * col,
115 struct mailimf_to * to);
116
117static int mailimf_resent_cc_write(FILE * f, int * col,
118 struct mailimf_cc * cc);
119
120static int mailimf_resent_bcc_write(FILE * f, int * col,
121 struct mailimf_bcc * bcc);
122
123static int
124mailimf_resent_msg_id_write(FILE * f, int * col,
125 struct mailimf_message_id * message_id);
126
127
128
129/* ************************ */
130
131#if 0
132int mailimf_string_write(FILE * f, int * col,
133 char * str, size_t length)
134{
135 int r;
136
137 if (length != 0) {
138 r = fwrite(str, sizeof(char), length, f);
139 if (r < 0)
140 return MAILIMF_ERROR_FILE;
141 * col += length;
142 }
143
144 return MAILIMF_NO_ERROR;
145}
146#endif
147
148#define CRLF "\r\n"
149#define HEADER_FOLD "\r\n "
150
151static inline int flush_buf(FILE * f, const char * str, size_t length)
152{
153 if (length != 0) {
154 int r;
155
156 r = fwrite(str, 1, length, f);
157 if (r == 0)
158 return MAILIMF_ERROR_FILE;
159 }
160 return MAILIMF_NO_ERROR;
161}
162
163#define CUT_AT_MAX_VALID_IMF_LINE
164
165int mailimf_string_write(FILE * f, int * col,
166 const char * str, size_t length)
167{
168 int r;
169 size_t count;
170 const char * block_begin;
171 const char * p;
172 int done;
173
174 p = str;
175 block_begin = str;
176 count = 0;
177
178 while (length > 0) {
179#ifdef CUT_AT_MAX_VALID_IMF_LINE
180 if (count >= 998) {
181 /*
182 cut lines at maximum valid length for internet message
183 format standard (currently RFC 2822)
184
185 This should not happen.
186 In case there are some lines larger than 998 in body,
187 the encoding must be changed into base64 or quoted-printable
188 so that wrapping to 72 columns is done.
189 */
190
191 r = flush_buf(f, block_begin, count);
192 if (r != MAILIMF_NO_ERROR)
193 return r;
194
195 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
196 if (r == 0)
197 return MAILIMF_ERROR_FILE;
198
199 count = 0;
200 block_begin = p;
201
202 * col = 0;
203 }
204#endif
205 switch (* p) {
206 case '\n':
207 r = flush_buf(f, block_begin, count);
208 if (r != MAILIMF_NO_ERROR)
209 return r;
210
211 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
212 if (r == 0)
213 return MAILIMF_ERROR_FILE;
214
215 p ++;
216 length --;
217 count = 0;
218 block_begin = p;
219
220 * col = 0;
221 break;
222
223 case '\r':
224 done = 0;
225 if (length >= 2) {
226 if (* (p + 1) == '\n') {
227 r = flush_buf(f, block_begin, count);
228 if (r != MAILIMF_NO_ERROR)
229 return r;
230
231 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
232 if (r == 0)
233 return MAILIMF_ERROR_FILE;
234
235 p += 2;
236 length -= 2;
237 count = 0;
238 block_begin = p;
239
240 * col = 0;
241
242 done = 1;
243 }
244 }
245 if (!done) {
246 r = flush_buf(f, block_begin, count);
247 if (r != MAILIMF_NO_ERROR)
248 return r;
249
250 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
251 if (r == 0)
252 return MAILIMF_ERROR_FILE;
253
254 p ++;
255 length --;
256 count = 0;
257 block_begin = p;
258
259 * col = 0;
260 }
261 break;
262
263 default:
264 p ++;
265 count ++;
266 length --;
267 break;
268 }
269 }
270
271 r = flush_buf(f, block_begin, count);
272 if (r != MAILIMF_NO_ERROR)
273 return r;
274 * col += count;
275
276 return MAILIMF_NO_ERROR;
277}
278
279#if 0
280int mailimf_header_string_write(FILE * f, int * col,
281 char * str, size_t length)
282{
283 char * p;
284 char * block_begin;
285 int current_col;
286 char * last_cut;
287 int r;
288 int first;
289
290 if (* col + length < MAX_MAIL_COL)
291 return mailimf_string_write(f, col, str, length);
292
293 first = 1;
294 p = str;
295 block_begin = p;
296 last_cut = block_begin;
297 current_col = * col;
298
299 while (1) {
300 if (current_col >= MAX_MAIL_COL) {
301 /* if we reach the maximum recommanded size of line */
302 if (last_cut == block_begin) {
303 /* if we could not find any place to cut */
304 if (first) {
305 /* fold the header */
306 r = mailimf_string_write(f, col, HEADER_FOLD,
307 sizeof(HEADER_FOLD) - 1);
308 if (r != MAILIMF_NO_ERROR)
309 return r;
310 current_col = * col + p - block_begin;
311 first = 0;
312 }
313 else {
314 /* cut the header */
315 r = mailimf_string_write(f, col, block_begin, p - block_begin);
316 if (r != MAILIMF_NO_ERROR)
317 return r;
318 r = mailimf_string_write(f, col, HEADER_FOLD,
319 sizeof(HEADER_FOLD) - 1);
320 if (r != MAILIMF_NO_ERROR)
321 return r;
322 first = 0;
323 block_begin = p;
324 last_cut = block_begin;
325 current_col = * col + p - block_begin;
326 }
327 }
328 else {
329 /* if we found a place to cut */
330 r = mailimf_string_write(f, col, block_begin, last_cut - block_begin);
331 if (r != MAILIMF_NO_ERROR)
332 return r;
333 r = mailimf_string_write(f, col, HEADER_FOLD,
334 sizeof(HEADER_FOLD) - 1);
335 if (r != MAILIMF_NO_ERROR)
336 return r;
337 first = 0;
338 block_begin = last_cut;
339 last_cut = block_begin;
340 current_col = * col + p - block_begin;
341 continue;
342 }
343 }
344 else {
345 if (length == 0)
346 break;
347
348 switch (* p) {
349 case ' ':
350 case '\t':
351 last_cut = p;
352 current_col ++;
353 break;
354
355 case '\r':
356 case '\n':
357 current_col = 0;
358 break;
359
360 default:
361 current_col ++;
362 break;
363 }
364
365 p ++;
366 length --;
367 }
368 }
369
370 return mailimf_string_write(f, col, block_begin, p - block_begin);
371}
372#endif
373
374#if 0
375enum {
376 STATE_LOWER_72,
377 STATE_LOWER_72_CUT,
378 STATE_EQUAL_72,
379 STATE_LOWER_998,
380 STATE_EQUAL_998,
381};
382
383int mailimf_header_string_write(FILE * f, int * col,
384 const char * str, size_t length)
385{
386 int state;
387 const char * p;
388 const char * block_begin;
389 size_t size;
390 const char * cut;
391 int r;
392
393 if (* col < MAX_MAIL_COL)
394 state = STATE_LOWER_72_CUT;
395 else if (* col == MAX_MAIL_COL)
396 state = STATE_EQUAL_72;
397 else if (* col < MAX_VALID_IMF_LINE)
398 state = STATE_LOWER_998;
399 else
400 state = STATE_EQUAL_998;
401
402 p = str;
403 block_begin = p;
404 size = * col;
405 cut = p;
406
407 while (length > 0) {
408 switch (state) {
409 case STATE_LOWER_72:
410 switch (* p) {
411 case '\r':
412 case '\n':
413 p ++;
414 length --;
415 size = 0;
416 break;
417
418 case ' ':
419 case '\t':
420 cut = p;
421 p ++;
422 length --;
423 size ++;
424 state = STATE_LOWER_72_CUT;
425 break;
426
427 default:
428 if (size < MAX_MAIL_COL - 1) {
429 p ++;
430 length --;
431 size ++;
432 }
433 else {
434 state = STATE_EQUAL_72;
435 p ++;
436 length --;
437 size ++;
438 }
439 break;
440 }
441 break; /* end of STATE_LOWER_72 */
442
443 case STATE_LOWER_72_CUT:
444 switch (* p) {
445 case '\r':
446 case '\n':
447 p ++;
448 length --;
449 size = 0;
450 state = STATE_LOWER_72;
451 break;
452
453 case ' ':
454 case '\t':
455 cut = p;
456 p ++;
457 length --;
458 size ++;
459 break;
460
461 default:
462 if (size < MAX_MAIL_COL) {
463 p ++;
464 length --;
465 size ++;
466 }
467 else {
468 r = mailimf_string_write(f, col, block_begin, cut - block_begin);
469 if (r != MAILIMF_NO_ERROR)
470 return r;
471 r = mailimf_string_write(f, col, HEADER_FOLD,
472 sizeof(HEADER_FOLD) - 1);
473 if (r != MAILIMF_NO_ERROR)
474 return r;
475 p ++;
476 length --;
477 block_begin = cut;
478 if ((* block_begin == ' ') || (* block_begin == '\t'))
479 block_begin ++;
480 size = p - block_begin + * col;
481 state = STATE_LOWER_72;
482 }
483 break;
484 }
485 break; /* end of STATE_LOWER_72_CUT */
486
487 case STATE_EQUAL_72:
488 switch (* p) {
489 case '\r':
490 case '\n':
491 p ++;
492 length --;
493 size = 0;
494 state = STATE_LOWER_72;
495 break;
496
497 case ' ':
498 case '\t':
499 r = mailimf_string_write(f, col, block_begin, p - block_begin);
500 if (r != MAILIMF_NO_ERROR)
501 return r;
502 r = mailimf_string_write(f, col, HEADER_FOLD,
503 sizeof(HEADER_FOLD) - 1);
504 if (r != MAILIMF_NO_ERROR)
505 return r;
506 p ++;
507 length --;
508 block_begin = p;
509 size = p - block_begin + * col;
510 state = STATE_LOWER_72;
511 break;
512
513 default:
514 p ++;
515 length --;
516 size ++;
517 state = STATE_LOWER_998;
518 break;
519 }
520 break; /* end of STATE_EQUAL_72 */
521
522 case STATE_LOWER_998:
523 switch (* p) {
524 case '\r':
525 case '\n':
526 p ++;
527 length --;
528 size = 0;
529 state = STATE_LOWER_72;
530 break;
531
532 case ' ':
533 case '\t':
534 r = mailimf_string_write(f, col, block_begin, p - block_begin);
535 if (r != MAILIMF_NO_ERROR)
536 return r;
537 r = mailimf_string_write(f, col, HEADER_FOLD,
538 sizeof(HEADER_FOLD) - 1);
539 if (r != MAILIMF_NO_ERROR)
540 return r;
541 p ++;
542 length --;
543 block_begin = p;
544 size = p - block_begin + * col;
545 state = STATE_LOWER_72;
546 break;
547
548 default:
549 if (size < MAX_VALID_IMF_LINE - 1) {
550 p ++;
551 length --;
552 size ++;
553 }
554 else {
555 p ++;
556 length --;
557 size = 0;
558 state = STATE_EQUAL_998;
559 }
560 break;
561 }
562 break; /* end of STATE_LOWER_998 */
563
564 case STATE_EQUAL_998:
565 switch (* p) {
566 case '\r':
567 case '\n':
568 p ++;
569 length --;
570 size = 0;
571 state = STATE_LOWER_72;
572 break;
573
574 case ' ':
575 case '\t':
576 r = mailimf_string_write(f, col, block_begin, p - block_begin);
577 if (r != MAILIMF_NO_ERROR)
578 return r;
579 r = mailimf_string_write(f, col, HEADER_FOLD,
580 sizeof(HEADER_FOLD) - 1);
581 if (r != MAILIMF_NO_ERROR)
582 return r;
583 p ++;
584 length --;
585 block_begin = p;
586 size = p - block_begin + * col;
587 state = STATE_LOWER_72;
588 break;
589
590 default:
591#ifdef CUT_AT_MAX_VALID_IMF_LINE
592 r = mailimf_string_write(f, col, block_begin, p - block_begin);
593 if (r != MAILIMF_NO_ERROR)
594 return r;
595 r = mailimf_string_write(f, col, HEADER_FOLD,
596 sizeof(HEADER_FOLD) - 1);
597 if (r != MAILIMF_NO_ERROR)
598 return r;
599 p ++;
600 length --;
601 block_begin = p;
602 size = p - block_begin + * col;
603 state = STATE_LOWER_72;
604#else
605 p ++;
606 length --;
607 size ++;
608#endif
609 break;
610 }
611 break; /* end of STATE_EQUAL_998 */
612 }
613 }
614
615 r = mailimf_string_write(f, col, block_begin, p - block_begin);
616 if (r != MAILIMF_NO_ERROR)
617 return r;
618
619 return MAILIMF_NO_ERROR;
620}
621#endif
622
623enum {
624 STATE_BEGIN,
625 STATE_WORD,
626 STATE_SPACE,
627};
628
629int mailimf_header_string_write(FILE * f, int * col,
630 const char * str, size_t length)
631{
632 int state;
633 const char * p;
634 const char * word_begin;
635 const char * word_end;
636 const char * next_word;
637 int first;
638
639 state = STATE_BEGIN;
640
641 p = str;
642 word_begin = p;
643 word_end = p;
644 next_word = p;
645 first = 1;
646
647 while (length > 0) {
648 switch (state) {
649 case STATE_BEGIN:
650 switch (* p) {
651 case '\r':
652 case '\n':
653 case ' ':
654 case '\t':
655 p ++;
656 length --;
657 break;
658
659 default:
660 word_begin = p;
661 state = STATE_WORD;
662 break;
663 }
664 break;
665
666 case STATE_SPACE:
667 switch (* p) {
668 case '\r':
669 case '\n':
670 case ' ':
671 case '\t':
672 p ++;
673 length --;
674 break;
675
676 default:
677 word_begin = p;
678 state = STATE_WORD;
679 break;
680 }
681 break;
682
683 case STATE_WORD:
684 switch (* p) {
685 case '\r':
686 case '\n':
687 case ' ':
688 case '\t':
689 if (p - word_begin + (* col) + 1 > MAX_MAIL_COL)
690 mailimf_string_write(f, col, HEADER_FOLD,
691 sizeof(HEADER_FOLD) - 1);
692 else {
693 if (!first)
694 mailimf_string_write(f, col, " ", 1);
695 }
696 first = 0;
697 mailimf_string_write(f, col, word_begin, p - word_begin);
698 state = STATE_SPACE;
699 break;
700
701 default:
702 if (p - word_begin + (* col) >= MAX_VALID_IMF_LINE) {
703 mailimf_string_write(f, col, word_begin, p - word_begin);
704 mailimf_string_write(f, col, HEADER_FOLD,
705 sizeof(HEADER_FOLD) - 1);
706 word_begin = p;
707 }
708 p ++;
709 length --;
710 break;
711 }
712 break;
713 }
714 }
715
716 if (state == STATE_WORD) {
717 if (p - word_begin + (* col) >= MAX_MAIL_COL)
718 mailimf_string_write(f, col, HEADER_FOLD,
719 sizeof(HEADER_FOLD) - 1);
720 else {
721 if (!first)
722 mailimf_string_write(f, col, " ", 1);
723 }
724 first = 0;
725 mailimf_string_write(f, col, word_begin, p - word_begin);
726 }
727
728 return MAILIMF_NO_ERROR;
729}
730
731int mailimf_envelope_fields_write(FILE * f, int * col,
732 struct mailimf_fields * fields)
733{
734 clistiter * cur;
735
736 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
737 cur = clist_next(cur)) {
738 int r;
739 struct mailimf_field * field;
740
741 field = clist_content(cur);
742 if (field->fld_type != MAILIMF_FIELD_OPTIONAL_FIELD) {
743 r = mailimf_field_write(f, col, field);
744 if (r != MAILIMF_NO_ERROR)
745 return r;
746 }
747 }
748
749 return MAILIMF_NO_ERROR;
750}
751
752int mailimf_fields_write(FILE * f, int * col,
753 struct mailimf_fields * fields)
754{
755 clistiter * cur;
756
757 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
758 cur = clist_next(cur)) {
759 int r;
760
761 r = mailimf_field_write(f, col, clist_content(cur));
762 if (r != MAILIMF_NO_ERROR)
763 return r;
764 }
765
766 return MAILIMF_NO_ERROR;
767}
768
769#if 0
770int mailimf_unparsed_fields_write(FILE * f, int * col,
771 struct mailimf_unparsed_fields * fields)
772{
773 clistiter * cur;
774
775 for(cur = clist_begin(fields->list) ; cur != NULL ; cur = cur->next) {
776 int r;
777
778 r = mailimf_optional_field_write(f, col, cur->data);
779 if (r != MAILIMF_NO_ERROR)
780 return r;
781 }
782
783 return MAILIMF_NO_ERROR;
784}
785#endif
786
787int mailimf_field_write(FILE * f, int * col,
788 struct mailimf_field * field)
789{
790 int r;
791
792 switch (field->fld_type) {
793 case MAILIMF_FIELD_RETURN_PATH:
794 r = mailimf_return_write(f, col, field->fld_data.fld_return_path);
795 break;
796 case MAILIMF_FIELD_RESENT_DATE:
797 r = mailimf_resent_date_write(f, col, field->fld_data.fld_resent_date);
798 break;
799 case MAILIMF_FIELD_RESENT_FROM:
800 r = mailimf_resent_from_write(f, col, field->fld_data.fld_resent_from);
801 break;
802 case MAILIMF_FIELD_RESENT_SENDER:
803 r = mailimf_resent_sender_write(f, col, field->fld_data.fld_resent_sender);
804 break;
805 case MAILIMF_FIELD_RESENT_TO:
806 r = mailimf_resent_to_write(f, col, field->fld_data.fld_resent_to);
807 break;
808 case MAILIMF_FIELD_RESENT_CC:
809 r = mailimf_resent_cc_write(f, col, field->fld_data.fld_resent_cc);
810 break;
811 case MAILIMF_FIELD_RESENT_BCC:
812 r = mailimf_resent_bcc_write(f, col, field->fld_data.fld_resent_bcc);
813 break;
814 case MAILIMF_FIELD_RESENT_MSG_ID:
815 r = mailimf_resent_msg_id_write(f, col, field->fld_data.fld_resent_msg_id);
816 break;
817 case MAILIMF_FIELD_ORIG_DATE:
818 r = mailimf_orig_date_write(f, col, field->fld_data.fld_orig_date);
819 break;
820 case MAILIMF_FIELD_FROM:
821 r = mailimf_from_write(f, col, field->fld_data.fld_from);
822 break;
823 case MAILIMF_FIELD_SENDER:
824 r = mailimf_sender_write(f, col, field->fld_data.fld_sender);
825 break;
826 case MAILIMF_FIELD_REPLY_TO:
827 r = mailimf_reply_to_write(f, col, field->fld_data.fld_reply_to);
828 break;
829 case MAILIMF_FIELD_TO:
830 r = mailimf_to_write(f, col, field->fld_data.fld_to);
831 break;
832 case MAILIMF_FIELD_CC:
833 r = mailimf_cc_write(f, col, field->fld_data.fld_cc);
834 break;
835 case MAILIMF_FIELD_BCC:
836 r = mailimf_bcc_write(f, col, field->fld_data.fld_bcc);
837 break;
838 case MAILIMF_FIELD_MESSAGE_ID:
839 r = mailimf_message_id_write(f, col, field->fld_data.fld_message_id);
840 break;
841 case MAILIMF_FIELD_IN_REPLY_TO:
842 r = mailimf_in_reply_to_write(f, col, field->fld_data.fld_in_reply_to);
843 break;
844 case MAILIMF_FIELD_REFERENCES:
845 r = mailimf_references_write(f, col, field->fld_data.fld_references);
846 break;
847 case MAILIMF_FIELD_SUBJECT:
848 r = mailimf_subject_write(f, col, field->fld_data.fld_subject);
849 break;
850 case MAILIMF_FIELD_COMMENTS:
851 r = mailimf_comments_write(f, col, field->fld_data.fld_comments);
852 break;
853 case MAILIMF_FIELD_KEYWORDS:
854 r = mailimf_keywords_write(f, col, field->fld_data.fld_keywords);
855 break;
856 case MAILIMF_FIELD_OPTIONAL_FIELD:
857 r = mailimf_optional_field_write(f, col, field->fld_data.fld_optional_field);
858 break;
859 default:
860 r = MAILIMF_ERROR_INVAL;
861 break;
862 }
863
864 if (r != MAILIMF_NO_ERROR)
865 return r;
866
867 return MAILIMF_NO_ERROR;
868}
869
870
871static int mailimf_orig_date_write(FILE * f, int * col,
872 struct mailimf_orig_date * date)
873{
874 int r;
875
876 r = mailimf_string_write(f, col, "Date: ", 6);
877 if (r != MAILIMF_NO_ERROR)
878 return r;
879
880 r = mailimf_date_time_write(f, col, date->dt_date_time);
881 if (r != MAILIMF_NO_ERROR)
882 return r;
883
884 r = mailimf_string_write(f, col, "\r\n", 2);
885 if (r != MAILIMF_NO_ERROR)
886 return r;
887#if 0
888 * col = 0;
889#endif
890
891 return MAILIMF_NO_ERROR;
892}
893
894#define MAX_DATE_STR 256
895
896/* 0 = Sunday */
897/* y > 1752 */
898
899static int dayofweek(int year, int month, int day)
900{
901 static int offset[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
902
903 year -= month < 3;
904
905 return (year + year/4 - year/100 + year/400 + offset[month-1] + day) % 7;
906}
907
908static const char * week_of_day_str[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
909 "Fri", "Sat"};
910static const char * month_str[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
911 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
912
913static int mailimf_date_time_write(FILE * f, int * col,
914 struct mailimf_date_time * date_time)
915{
916 int r;
917 char date_str[MAX_DATE_STR];
918#if 0
919 struct tm tmval;
920 time_t timeval;
921#endif
922 int wday;
923
924#if 0
925 tmval.tm_sec = date_time->sec;
926 tmval.tm_min = date_time->min;
927 tmval.tm_hour = date_time->hour;
928 tmval.tm_sec = date_time->sec;
929 tmval.tm_mday = date_time->day;
930 tmval.tm_mon = date_time->month - 1;
931 tmval.tm_year = date_time->year - 1900;
932 tmval.tm_isdst = 1;
933
934 timeval = mktime(&tmval);
935
936 localtime_r(&timeval, &tmval);
937#endif
938
939 wday = dayofweek(date_time->dt_year, date_time->dt_month, date_time->dt_day);
940
941 snprintf(date_str, MAX_DATE_STR, "%s, %i %s %i %02i:%02i:%02i %+05i",
942 week_of_day_str[wday], date_time->dt_day,
943 month_str[date_time->dt_month - 1],
944 date_time->dt_year, date_time->dt_hour,
945 date_time->dt_min, date_time->dt_sec,
946 date_time->dt_zone);
947
948 r = mailimf_string_write(f, col, date_str, strlen(date_str));
949
950 if (r != MAILIMF_NO_ERROR)
951 return r;
952
953 return MAILIMF_NO_ERROR;
954}
955
956static int mailimf_from_write(FILE * f, int * col,
957 struct mailimf_from * from)
958{
959 int r;
960
961 r = mailimf_string_write(f, col, "From: ", 6);
962 if (r != MAILIMF_NO_ERROR)
963 return r;
964
965 r = mailimf_mailbox_list_write(f, col, from->frm_mb_list);
966 if (r != MAILIMF_NO_ERROR)
967 return r;
968
969 r = mailimf_string_write(f, col, "\r\n", 2);
970 if (r != MAILIMF_NO_ERROR)
971 return r;
972#if 0
973 * col = 0;
974#endif
975
976 return MAILIMF_NO_ERROR;
977}
978
979static int mailimf_sender_write(FILE * f, int * col,
980 struct mailimf_sender * sender)
981{
982 int r;
983
984 r = mailimf_string_write(f, col, "Sender: ", 8);
985 if (r != MAILIMF_NO_ERROR)
986 return r;
987
988 r = mailimf_mailbox_write(f, col, sender->snd_mb);
989 if (r != MAILIMF_NO_ERROR)
990 return r;
991
992 r = mailimf_string_write(f, col, "\r\n", 2);
993 if (r != MAILIMF_NO_ERROR)
994 return r;
995#if 0
996 * col = 0;
997#endif
998
999 return MAILIMF_NO_ERROR;
1000}
1001
1002static int mailimf_reply_to_write(FILE * f, int * col,
1003 struct mailimf_reply_to * reply_to)
1004{
1005 int r;
1006
1007 r = mailimf_string_write(f, col, "Reply-To: ", 10);
1008 if (r != MAILIMF_NO_ERROR)
1009 return r;
1010
1011 r = mailimf_address_list_write(f, col, reply_to->rt_addr_list);
1012 if (r != MAILIMF_NO_ERROR)
1013 return r;
1014
1015 r = mailimf_string_write(f, col, "\r\n", 2);
1016 if (r != MAILIMF_NO_ERROR)
1017 return r;
1018#if 0
1019 * col = 0;
1020#endif
1021
1022 return MAILIMF_NO_ERROR;
1023}
1024
1025
1026static int mailimf_to_write(FILE * f, int * col,
1027 struct mailimf_to * to)
1028{
1029 int r;
1030
1031 r = mailimf_string_write(f, col, "To: ", 4);
1032 if (r != MAILIMF_NO_ERROR)
1033 return r;
1034
1035 r = mailimf_address_list_write(f, col, to->to_addr_list);
1036 if (r != MAILIMF_NO_ERROR)
1037 return r;
1038
1039 r = mailimf_string_write(f, col, "\r\n", 2);
1040 if (r != MAILIMF_NO_ERROR)
1041 return r;
1042#if 0
1043 * col = 0;
1044#endif
1045
1046 return MAILIMF_NO_ERROR;
1047}
1048
1049
1050static int mailimf_cc_write(FILE * f, int * col,
1051 struct mailimf_cc * cc)
1052{
1053 int r;
1054
1055 r = mailimf_string_write(f, col, "Cc: ", 4);
1056 if (r != MAILIMF_NO_ERROR)
1057 return r;
1058
1059 r = mailimf_address_list_write(f, col, cc->cc_addr_list);
1060 if (r != MAILIMF_NO_ERROR)
1061 return r;
1062
1063 r = mailimf_string_write(f, col, "\r\n", 2);
1064 if (r != MAILIMF_NO_ERROR)
1065 return r;
1066#if 0
1067 * col = 0;
1068#endif
1069
1070 return MAILIMF_NO_ERROR;
1071}
1072
1073
1074static int mailimf_bcc_write(FILE * f, int * col,
1075 struct mailimf_bcc * bcc)
1076{
1077 int r;
1078
1079 r = mailimf_string_write(f, col, "Bcc: ", 5);
1080 if (r != MAILIMF_NO_ERROR)
1081 return r;
1082
1083 if (bcc->bcc_addr_list != NULL) {
1084 r = mailimf_address_list_write(f, col, bcc->bcc_addr_list);
1085 if (r != MAILIMF_NO_ERROR)
1086 return r;
1087 }
1088
1089 r = mailimf_string_write(f, col, "\r\n", 2);
1090 if (r != MAILIMF_NO_ERROR)
1091 return r;
1092#if 0
1093 * col = 0;
1094#endif
1095
1096 return MAILIMF_NO_ERROR;
1097}
1098
1099
1100static int mailimf_message_id_write(FILE * f, int * col,
1101 struct mailimf_message_id * message_id)
1102{
1103 int r;
1104
1105 r = mailimf_string_write(f, col, "Message-ID: ", 12);
1106 if (r != MAILIMF_NO_ERROR)
1107 return r;
1108
1109 r = mailimf_string_write(f, col, "<", 1);
1110 if (r != MAILIMF_NO_ERROR)
1111 return r;
1112
1113 r = mailimf_string_write(f, col,
1114 message_id->mid_value,
1115 strlen(message_id->mid_value));
1116 if (r != MAILIMF_NO_ERROR)
1117 return r;
1118
1119 r = mailimf_string_write(f, col, ">", 1);
1120 if (r != MAILIMF_NO_ERROR)
1121 return r;
1122
1123 r = mailimf_string_write(f, col, "\r\n", 2);
1124 if (r != MAILIMF_NO_ERROR)
1125 return r;
1126#if 0
1127 * col = 0;
1128#endif
1129
1130 return MAILIMF_NO_ERROR;
1131}
1132
1133
1134static int mailimf_msg_id_list_write(FILE * f, int * col, clist * mid_list)
1135{
1136 clistiter * cur;
1137 int r;
1138 int first;
1139
1140 first = TRUE;
1141
1142 for(cur = clist_begin(mid_list) ; cur != NULL ; cur = clist_next(cur)) {
1143 char * msgid;
1144 size_t len;
1145
1146 msgid = clist_content(cur);
1147 len = strlen(msgid);
1148
1149 /*
1150 XXX - if this is the first message ID, don't fold.
1151 This is a workaround for a bug of old versions of INN.
1152 */
1153 if (!first) {
1154 if (* col > 1) {
1155
1156 if (* col + len >= MAX_MAIL_COL) {
1157 r = mailimf_string_write(f, col, "\r\n ", 3);
1158 if (r != MAILIMF_NO_ERROR)
1159 return r;
1160#if 0
1161 * col = 1;
1162#endif
1163 first = TRUE;
1164 }
1165 }
1166 }
1167
1168 if (!first) {
1169 r = mailimf_string_write(f, col, " ", 1);
1170 if (r != MAILIMF_NO_ERROR)
1171 return r;
1172 }
1173 else {
1174 first = FALSE;
1175 }
1176
1177 r = mailimf_string_write(f, col, "<", 1);
1178 if (r != MAILIMF_NO_ERROR)
1179 return r;
1180
1181 r = mailimf_string_write(f, col, msgid, len);
1182 if (r != MAILIMF_NO_ERROR)
1183 return r;
1184
1185 r = mailimf_string_write(f, col, ">", 1);
1186 if (r != MAILIMF_NO_ERROR)
1187 return r;
1188 }
1189
1190 return MAILIMF_NO_ERROR;
1191}
1192
1193
1194static int mailimf_in_reply_to_write(FILE * f, int * col,
1195 struct mailimf_in_reply_to * in_reply_to)
1196{
1197 int r;
1198
1199 r = mailimf_string_write(f, col, "In-Reply-To: ", 13);
1200 if (r != MAILIMF_NO_ERROR)
1201 return r;
1202
1203 r = mailimf_msg_id_list_write(f, col, in_reply_to->mid_list);
1204 if (r != MAILIMF_NO_ERROR)
1205 return r;
1206
1207 r = mailimf_string_write(f, col, "\r\n", 2);
1208 if (r != MAILIMF_NO_ERROR)
1209 return r;
1210#if 0
1211 * col = 0;
1212#endif
1213
1214 return MAILIMF_NO_ERROR;
1215}
1216
1217
1218static int mailimf_references_write(FILE * f, int * col,
1219 struct mailimf_references * references)
1220{
1221 int r;
1222
1223 r = mailimf_string_write(f, col, "References: ", 12);
1224 if (r != MAILIMF_NO_ERROR)
1225 return r;
1226
1227 r = mailimf_msg_id_list_write(f, col, references->mid_list);
1228 if (r != MAILIMF_NO_ERROR)
1229 return r;
1230
1231 r = mailimf_string_write(f, col, "\r\n", 2);
1232 if (r != MAILIMF_NO_ERROR)
1233 return r;
1234#if 0
1235 * col = 0;
1236#endif
1237
1238 return MAILIMF_NO_ERROR;
1239}
1240
1241
1242
1243static int mailimf_subject_write(FILE * f, int * col,
1244 struct mailimf_subject * subject)
1245{
1246 int r;
1247
1248 r = mailimf_string_write(f, col, "Subject: ", 9);
1249 if (r != MAILIMF_NO_ERROR)
1250 return r;
1251
1252 r = mailimf_header_string_write(f, col,
1253 subject->sbj_value, strlen(subject->sbj_value));
1254 if (r != MAILIMF_NO_ERROR)
1255 return r;
1256
1257 r = mailimf_string_write(f, col, "\r\n", 2);
1258 if (r != MAILIMF_NO_ERROR)
1259 return r;
1260#if 0
1261 * col = 0;
1262#endif
1263
1264 return MAILIMF_NO_ERROR;
1265}
1266
1267int mailimf_address_list_write(FILE * f, int * col,
1268 struct mailimf_address_list * addr_list)
1269{
1270 clistiter * cur;
1271 int r;
1272 int first;
1273
1274 first = TRUE;
1275
1276 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
1277 cur = clist_next(cur)) {
1278 struct mailimf_address * addr;
1279
1280 addr = clist_content(cur);
1281
1282 if (!first) {
1283 r = mailimf_string_write(f, col, ", ", 2);
1284 if (r != MAILIMF_NO_ERROR)
1285 return r;
1286 }
1287 else {
1288 first = FALSE;
1289 }
1290
1291 r = mailimf_address_write(f, col, addr);
1292 if (r != MAILIMF_NO_ERROR)
1293 return r;
1294 }
1295
1296 return MAILIMF_NO_ERROR;
1297}
1298
1299
1300static int mailimf_address_write(FILE * f, int * col,
1301 struct mailimf_address * addr)
1302{
1303 int r;
1304
1305 switch(addr->ad_type) {
1306 case MAILIMF_ADDRESS_MAILBOX:
1307 r = mailimf_mailbox_write(f, col, addr->ad_data.ad_mailbox);
1308 if (r != MAILIMF_NO_ERROR)
1309 return r;
1310
1311 break;
1312
1313 case MAILIMF_ADDRESS_GROUP:
1314 r = mailimf_group_write(f, col, addr->ad_data.ad_group);
1315 if (r != MAILIMF_NO_ERROR)
1316 return r;
1317
1318 break;
1319 }
1320
1321 return MAILIMF_NO_ERROR;
1322}
1323
1324
1325static int mailimf_group_write(FILE * f, int * col,
1326 struct mailimf_group * group)
1327{
1328 int r;
1329
1330 r = mailimf_header_string_write(f, col, group->grp_display_name,
1331 strlen(group->grp_display_name));
1332 if (r != MAILIMF_NO_ERROR)
1333 return r;
1334
1335 r = mailimf_string_write(f, col, ": ", 2);
1336 if (r != MAILIMF_NO_ERROR)
1337 return r;
1338
1339 if (group->grp_mb_list != NULL) {
1340 r = mailimf_mailbox_list_write(f, col, group->grp_mb_list);
1341 if (r != MAILIMF_NO_ERROR)
1342 return r;
1343 }
1344
1345 r = mailimf_string_write(f, col, ";", 1);
1346 if (r != MAILIMF_NO_ERROR)
1347 return r;
1348
1349 return MAILIMF_NO_ERROR;
1350}
1351
1352
1353int mailimf_mailbox_list_write(FILE * f, int * col,
1354 struct mailimf_mailbox_list * mb_list)
1355{
1356 clistiter * cur;
1357 int r;
1358 int first;
1359
1360 first = TRUE;
1361
1362 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
1363 cur = clist_next(cur)) {
1364 struct mailimf_mailbox * mb;
1365
1366 mb = clist_content(cur);
1367
1368 if (!first) {
1369 r = mailimf_string_write(f, col, ", ", 2);
1370 if (r != MAILIMF_NO_ERROR)
1371 return r;
1372 }
1373 else {
1374 first = FALSE;
1375 }
1376
1377 r = mailimf_mailbox_write(f, col, mb);
1378 if (r != MAILIMF_NO_ERROR)
1379 return r;
1380 }
1381
1382 return MAILIMF_NO_ERROR;
1383}
1384
1385
1386int mailimf_quoted_string_write(FILE * f, int * col,
1387 const char * string, size_t len)
1388{
1389 int r;
1390 size_t i;
1391
1392 fputc('\"', f);
1393 for(i = 0 ; i < len ; i ++) {
1394 switch (string[i]) {
1395 case '\\':
1396 case '\"':
1397 r = fputc('\\', f);
1398 if (r < 0)
1399 return MAILIMF_ERROR_FILE;
1400 r = fputc(string[i], f);
1401 if (r < 0)
1402 return MAILIMF_ERROR_FILE;
1403 (* col) += 2;
1404 break;
1405
1406 default:
1407 r = fputc(string[i], f);
1408 if (r < 0)
1409 return MAILIMF_ERROR_FILE;
1410 (* col) ++;
1411 break;
1412 }
1413 }
1414 fputc('\"', f);
1415
1416 return MAILIMF_NO_ERROR;
1417}
1418
1419
1420/*
1421static int
1422atext = ALPHA / DIGIT / ; Any character except controls,
1423 "!" / "#" / ; SP, and specials.
1424 "$" / "%" / ; Used for atoms
1425 "&" / "'" /
1426 "*" / "+" /
1427 "-" / "/" /
1428 "=" / "?" /
1429 "^" / "_" /
1430 "`" / "{" /
1431 "|" / "}" /
1432 "~"
1433*/
1434
1435static int is_atext(const char * s)
1436{
1437 const char * p;
1438
1439 for(p = s ; * p != 0 ; p ++) {
1440 if (isalpha((unsigned char) * p))
1441 continue;
1442 if (isdigit((unsigned char) * p))
1443 continue;
1444 switch (*p) {
1445 case ' ':
1446 case '\t':
1447 case '!':
1448 case '#':
1449 case '$':
1450 case '%':
1451 case '&':
1452 case '\'':
1453 case '*':
1454 case '+':
1455 case '-':
1456 case '/':
1457 case '=':
1458 case '?':
1459 case '^':
1460 case '_':
1461 case '`':
1462 case '{':
1463 case '|':
1464 case '}':
1465 case '~':
1466 break;
1467 default:
1468 return 0;
1469 }
1470 }
1471
1472 return 1;
1473}
1474
1475static int mailimf_mailbox_write(FILE * f, int * col,
1476 struct mailimf_mailbox * mb)
1477{
1478 int r;
1479 int do_fold;
1480
1481#if 0
1482 if (* col > 1) {
1483
1484 if (mb->mb_display_name != NULL) {
1485 if (* col + strlen(mb->mb_display_name) >= MAX_MAIL_COL) {
1486 r = mailimf_string_write(f, col, "\r\n ", 3);
1487 if (r != MAILIMF_NO_ERROR)
1488 return r;
1489#if 0
1490 * col = 1;
1491#endif
1492 }
1493 }
1494 }
1495#endif
1496
1497 if (mb->mb_display_name) {
1498
1499 if (is_atext(mb->mb_display_name)) {
1500 r = mailimf_header_string_write(f, col, mb->mb_display_name,
1501 strlen(mb->mb_display_name));
1502 if (r != MAILIMF_NO_ERROR)
1503 return r;
1504 }
1505 else {
1506 if (mb->mb_display_name != NULL) {
1507 if (* col + strlen(mb->mb_display_name) >= MAX_MAIL_COL) {
1508 r = mailimf_string_write(f, col, "\r\n ", 3);
1509 if (r != MAILIMF_NO_ERROR)
1510 return r;
1511 }
1512 }
1513
1514 if (strlen(mb->mb_display_name) > MAX_VALID_IMF_LINE / 2)
1515 return MAILIMF_ERROR_INVAL;
1516
1517 r = mailimf_quoted_string_write(f, col, mb->mb_display_name,
1518 strlen(mb->mb_display_name));
1519 if (r != MAILIMF_NO_ERROR)
1520 return r;
1521 }
1522
1523 do_fold = 0;
1524 if (* col > 1) {
1525
1526 if (* col + strlen(mb->mb_addr_spec) + 3 >= MAX_MAIL_COL) {
1527 r = mailimf_string_write(f, col, "\r\n ", 3);
1528 if (r != MAILIMF_NO_ERROR)
1529 return r;
1530#if 0
1531 * col = 1;
1532#endif
1533 do_fold = 1;
1534 }
1535 }
1536
1537 if (do_fold)
1538 r = mailimf_string_write(f, col, "<", 1);
1539 else
1540 r = mailimf_string_write(f, col, " <", 2);
1541 if (r != MAILIMF_NO_ERROR)
1542 return r;
1543
1544 r = mailimf_string_write(f, col, mb->mb_addr_spec,
1545 strlen(mb->mb_addr_spec));
1546 if (r != MAILIMF_NO_ERROR)
1547 return r;
1548
1549 r = mailimf_string_write(f, col, ">", 1);
1550 if (r != MAILIMF_NO_ERROR)
1551 return r;
1552 }
1553 else {
1554 if (* col + strlen(mb->mb_addr_spec) >= MAX_MAIL_COL) {
1555 r = mailimf_string_write(f, col, "\r\n ", 3);
1556 if (r != MAILIMF_NO_ERROR)
1557 return r;
1558 }
1559
1560 r = mailimf_string_write(f, col,
1561 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
1562 if (r != MAILIMF_NO_ERROR)
1563 return r;
1564 }
1565
1566
1567 return MAILIMF_NO_ERROR;
1568}
1569
1570static int mailimf_comments_write(FILE * f, int * col,
1571 struct mailimf_comments * comments)
1572{
1573 int r;
1574
1575 r = mailimf_string_write(f, col, "Comments: ", 10);
1576 if (r != MAILIMF_NO_ERROR)
1577 return r;
1578
1579 r = mailimf_header_string_write(f, col,
1580 comments->cm_value, strlen(comments->cm_value));
1581 if (r != MAILIMF_NO_ERROR)
1582 return r;
1583
1584 r = mailimf_string_write(f, col, "\r\n", 2);
1585 if (r != MAILIMF_NO_ERROR)
1586 return r;
1587#if 0
1588 * col = 0;
1589#endif
1590
1591 return MAILIMF_NO_ERROR;
1592}
1593
1594static int mailimf_optional_field_write(FILE * f, int * col,
1595 struct mailimf_optional_field * field)
1596{
1597 int r;
1598
1599 if (strlen(field->fld_name) + 2 > MAX_VALID_IMF_LINE)
1600 return MAILIMF_ERROR_INVAL;
1601
1602 r = mailimf_string_write(f, col, field->fld_name, strlen(field->fld_name));
1603 if (r != MAILIMF_NO_ERROR)
1604 return r;
1605
1606 r = mailimf_string_write(f, col, ": ", 2);
1607 if (r != MAILIMF_NO_ERROR)
1608 return r;
1609
1610 r = mailimf_header_string_write(f, col, field->fld_value,
1611 strlen(field->fld_value));
1612 if (r != MAILIMF_NO_ERROR)
1613 return r;
1614
1615#if 0
1616 /* XXX parsing debug */
1617 mailimf_string_write(f, col, " (X)", 4);
1618#endif
1619
1620 r = mailimf_string_write(f, col, "\r\n", 2);
1621 if (r != MAILIMF_NO_ERROR)
1622 return r;
1623#if 0
1624 * col = 0;
1625#endif
1626
1627 return MAILIMF_NO_ERROR;
1628}
1629
1630static int mailimf_keywords_write(FILE * f, int * col,
1631 struct mailimf_keywords * keywords)
1632{
1633 int r;
1634 clistiter * cur;
1635 int first;
1636
1637 r = mailimf_string_write(f, col, "Keywords: ", 10);
1638 if (r != MAILIMF_NO_ERROR)
1639 return r;
1640
1641 first = TRUE;
1642
1643 for(cur = clist_begin(keywords->kw_list) ; cur != NULL ;
1644 cur = clist_next(cur)) {
1645 char * keyword;
1646 size_t len;
1647
1648 keyword = clist_content(cur);
1649 len = strlen(keyword);
1650
1651 if (!first) {
1652 r = mailimf_string_write(f, col, ", ", 2);
1653 if (r != MAILIMF_NO_ERROR)
1654 return r;
1655 }
1656 else {
1657 first = FALSE;
1658 }
1659
1660#if 0
1661 if (* col > 1) {
1662
1663 if (* col + len >= MAX_MAIL_COL) {
1664 r = mailimf_string_write(f, col, "\r\n ", 3);
1665 if (r != MAILIMF_NO_ERROR)
1666 return r;
1667#if 0
1668 * col = 1;
1669#endif
1670 }
1671 }
1672#endif
1673
1674 r = mailimf_header_string_write(f, col, keyword, len);
1675 if (r != MAILIMF_NO_ERROR)
1676 return r;
1677 }
1678
1679 r = mailimf_string_write(f, col, "\r\n", 2);
1680 if (r != MAILIMF_NO_ERROR)
1681 return r;
1682#if 0
1683 * col = 0;
1684#endif
1685
1686 return MAILIMF_NO_ERROR;
1687}
1688
1689#if 0
1690static int mailimf_delivering_info_write(FILE * f, int * col,
1691 struct mailimf_delivering_info * info)
1692{
1693 clistiter * cur;
1694 int r;
1695
1696 for(cur = clist_begin(info->received_fields) ;
1697 cur != NULL ; cur = cur->next) {
1698 struct mailimf_trace_resent_fields * field;
1699
1700 field = cur->data;
1701
1702 r = mailimf_trace_resent_fields_write(f, col, field);
1703 if (r != MAILIMF_NO_ERROR)
1704 return r;
1705 }
1706
1707 return MAILIMF_NO_ERROR;
1708}
1709
1710
1711static int
1712mailimf_trace_resent_fields_write(FILE * f, int * col,
1713 struct mailimf_trace_resent_fields * field)
1714{
1715 int r;
1716
1717 if (field->return_path != NULL) {
1718 r = mailimf_return_write(f, col, field->return_path);
1719 if (r != MAILIMF_NO_ERROR)
1720 return r;
1721 }
1722
1723 if (field->resent_fields != NULL) {
1724 r = mailimf_resent_fields_write(f, col, field->resent_fields);
1725 if (r != MAILIMF_NO_ERROR)
1726 return r;
1727 }
1728
1729 return MAILIMF_NO_ERROR;
1730}
1731#endif
1732
1733static int mailimf_return_write(FILE * f, int * col,
1734 struct mailimf_return * return_path)
1735{
1736 int r;
1737
1738 r = mailimf_string_write(f, col, "Return-Path: ", 13);
1739 if (r != MAILIMF_NO_ERROR)
1740 return r;
1741
1742 r = mailimf_path_write(f, col, return_path->ret_path);
1743 if (r != MAILIMF_NO_ERROR)
1744 return r;
1745
1746 r = mailimf_string_write(f, col, "\r\n", 2);
1747 if (r != MAILIMF_NO_ERROR)
1748 return r;
1749#if 0
1750 * col = 0;
1751#endif
1752
1753 return MAILIMF_NO_ERROR;
1754}
1755
1756static int mailimf_path_write(FILE * f, int * col,
1757 struct mailimf_path * path)
1758{
1759 int r;
1760
1761 r = mailimf_string_write(f, col, "<", 1);
1762 if (r != MAILIMF_NO_ERROR)
1763 return r;
1764
1765 r = mailimf_string_write(f, col, path->pt_addr_spec,
1766 strlen(path->pt_addr_spec));
1767 if (r != MAILIMF_NO_ERROR)
1768 return r;
1769
1770 r = mailimf_string_write(f, col, ">", 1);
1771 if (r != MAILIMF_NO_ERROR)
1772 return r;
1773
1774 return MAILIMF_NO_ERROR;
1775}
1776
1777#if 0
1778static int mailimf_resent_fields_write(FILE * f, int * col,
1779 struct mailimf_resent_fields_list *
1780 resent_fields)
1781{
1782 clistiter * cur;
1783 int r;
1784
1785 for(cur = clist_begin(resent_fields->list) ; cur != NULL ; cur = cur->next) {
1786 struct mailimf_resent_field * field;
1787
1788 field = cur->data;
1789
1790 r = mailimf_resent_field_write(f, col, field);
1791 if (r != MAILIMF_NO_ERROR)
1792 return r;
1793 }
1794
1795 return MAILIMF_NO_ERROR;
1796}
1797
1798
1799
1800static int mailimf_resent_field_write(FILE * f, int * col,
1801 struct mailimf_resent_field *
1802 resent_field)
1803{
1804 int r;
1805
1806 switch (resent_field->type) {
1807 case MAILIMF_RESENT_FIELD_DATE:
1808 r = mailimf_resent_date_write(f, col, resent_field->resent_date);
1809 break;
1810
1811 case MAILIMF_RESENT_FIELD_FROM:
1812 r = mailimf_resent_from_write(f, col, resent_field->resent_from);
1813 break;
1814
1815 case MAILIMF_RESENT_FIELD_SENDER:
1816 r = mailimf_resent_sender_write(f, col, resent_field->resent_sender);
1817 break;
1818
1819 case MAILIMF_RESENT_FIELD_TO:
1820 r = mailimf_resent_to_write(f, col, resent_field->resent_to);
1821 break;
1822
1823 case MAILIMF_RESENT_FIELD_CC:
1824 r = mailimf_resent_cc_write(f, col, resent_field->resent_cc);
1825 break;
1826
1827 case MAILIMF_RESENT_FIELD_BCC:
1828 r = mailimf_resent_bcc_write(f, col, resent_field->resent_bcc);
1829 break;
1830
1831 case MAILIMF_RESENT_FIELD_MSG_ID:
1832 r = mailimf_resent_msg_id_write(f, col, resent_field->resent_msg_id);
1833 break;
1834 default:
1835 r = MAILIMF_ERROR_INVAL;
1836 break;
1837 }
1838
1839
1840 if (r != MAILIMF_NO_ERROR)
1841 return r;
1842
1843 return MAILIMF_NO_ERROR;
1844}
1845#endif
1846
1847static int mailimf_resent_date_write(FILE * f, int * col,
1848 struct mailimf_orig_date * date)
1849{
1850 int r;
1851
1852 r = mailimf_string_write(f, col, "Resent-Date: ", 13);
1853 if (r != MAILIMF_NO_ERROR)
1854 return r;
1855
1856 r = mailimf_date_time_write(f, col, date->dt_date_time);
1857 if (r != MAILIMF_NO_ERROR)
1858 return r;
1859
1860 r = mailimf_string_write(f, col, "\r\n", 2);
1861 if (r != MAILIMF_NO_ERROR)
1862 return r;
1863#if 0
1864 * col = 0;
1865#endif
1866
1867 return MAILIMF_NO_ERROR;
1868}
1869
1870static int mailimf_resent_from_write(FILE * f, int * col,
1871 struct mailimf_from * from)
1872{
1873 int r;
1874
1875 r = mailimf_string_write(f, col, "Resent-From: ", 13);
1876 if (r != MAILIMF_NO_ERROR)
1877 return r;
1878
1879 r = mailimf_mailbox_list_write(f, col, from->frm_mb_list);
1880 if (r != MAILIMF_NO_ERROR)
1881 return r;
1882
1883 r = mailimf_string_write(f, col, "\r\n", 2);
1884 if (r != MAILIMF_NO_ERROR)
1885 return r;
1886#if 0
1887 * col = 0;
1888#endif
1889
1890 return MAILIMF_NO_ERROR;
1891}
1892
1893static int mailimf_resent_sender_write(FILE * f, int * col,
1894 struct mailimf_sender * sender)
1895{
1896 int r;
1897
1898 r = mailimf_string_write(f, col, "Resent-Sender: ", 15);
1899 if (r != MAILIMF_NO_ERROR)
1900 return r;
1901
1902 r = mailimf_mailbox_write(f, col, sender->snd_mb);
1903 if (r != MAILIMF_NO_ERROR)
1904 return r;
1905
1906 r = mailimf_string_write(f, col, "\r\n", 2);
1907 if (r != MAILIMF_NO_ERROR)
1908 return r;
1909#if 0
1910 * col = 0;
1911#endif
1912
1913 return MAILIMF_NO_ERROR;
1914}
1915
1916static int mailimf_resent_to_write(FILE * f, int * col,
1917 struct mailimf_to * to)
1918{
1919 int r;
1920
1921 r = mailimf_string_write(f, col, "Resent-To: ", 11);
1922 if (r != MAILIMF_NO_ERROR)
1923 return r;
1924
1925 r = mailimf_address_list_write(f, col, to->to_addr_list);
1926 if (r != MAILIMF_NO_ERROR)
1927 return r;
1928
1929 r = mailimf_string_write(f, col, "\r\n", 2);
1930 if (r != MAILIMF_NO_ERROR)
1931 return r;
1932#if 0
1933 * col = 0;
1934#endif
1935
1936 return MAILIMF_NO_ERROR;
1937}
1938
1939
1940static int mailimf_resent_cc_write(FILE * f, int * col,
1941 struct mailimf_cc * cc)
1942{
1943 int r;
1944
1945 r = mailimf_string_write(f, col, "Resent-Cc: ", 11);
1946 if (r != MAILIMF_NO_ERROR)
1947 return r;
1948
1949 r = mailimf_address_list_write(f, col, cc->cc_addr_list);
1950 if (r != MAILIMF_NO_ERROR)
1951 return r;
1952
1953 r = mailimf_string_write(f, col, "\r\n", 2);
1954 if (r != MAILIMF_NO_ERROR)
1955 return r;
1956#if 0
1957 * col = 0;
1958#endif
1959
1960 return MAILIMF_NO_ERROR;
1961}
1962
1963
1964static int mailimf_resent_bcc_write(FILE * f, int * col,
1965 struct mailimf_bcc * bcc)
1966{
1967 int r;
1968
1969 r = mailimf_string_write(f, col, "Resent-Bcc: ", 12);
1970 if (r != MAILIMF_NO_ERROR)
1971 return r;
1972
1973 if (bcc->bcc_addr_list != NULL) {
1974 r = mailimf_address_list_write(f, col, bcc->bcc_addr_list);
1975 if (r != MAILIMF_NO_ERROR)
1976 return r;
1977 }
1978
1979 r = mailimf_string_write(f, col, "\r\n", 2);
1980 if (r != MAILIMF_NO_ERROR)
1981 return r;
1982#if 0
1983 * col = 0;
1984#endif
1985
1986 return MAILIMF_NO_ERROR;
1987}
1988
1989
1990static int
1991mailimf_resent_msg_id_write(FILE * f, int * col,
1992 struct mailimf_message_id * message_id)
1993{
1994 int r;
1995
1996 r = mailimf_string_write(f, col, "Resent-Message-ID: ", 19);
1997 if (r != MAILIMF_NO_ERROR)
1998 return r;
1999
2000 r = mailimf_string_write(f, col, "<", 1);
2001 if (r != MAILIMF_NO_ERROR)
2002 return r;
2003
2004 r = mailimf_string_write(f, col,
2005 message_id->mid_value, strlen(message_id->mid_value));
2006 if (r != MAILIMF_NO_ERROR)
2007 return r;
2008
2009 r = mailimf_string_write(f, col, ">", 1);
2010 if (r != MAILIMF_NO_ERROR)
2011 return r;
2012
2013 r = mailimf_string_write(f, col, "\r\n", 2);
2014 if (r != MAILIMF_NO_ERROR)
2015 return r;
2016#if 0
2017 * col = 0;
2018#endif
2019
2020 return MAILIMF_NO_ERROR;
2021}