summaryrefslogtreecommitdiffabout
path: root/libetpan/src/low-level/imf/mailimf_write_generic.c
Side-by-side diff
Diffstat (limited to 'libetpan/src/low-level/imf/mailimf_write_generic.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/low-level/imf/mailimf_write_generic.c2028
1 files changed, 2028 insertions, 0 deletions
diff --git a/libetpan/src/low-level/imf/mailimf_write_generic.c b/libetpan/src/low-level/imf/mailimf_write_generic.c
new file mode 100644
index 0000000..74c1d43
--- a/dev/null
+++ b/libetpan/src/low-level/imf/mailimf_write_generic.c
@@ -0,0 +1,2028 @@
+/*
+ * libEtPan! -- a mail stuff library
+ *
+ * Copyright (C) 2001, 2005 - DINH Viet Hoa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the libEtPan! project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "mailimf_write_generic.h"
+
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+
+#define MAX_MAIL_COL 72
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define MAX_VALID_IMF_LINE 998
+
+static int mailimf_orig_date_write_driver(int (* do_write)(void *, const char *, size_t), void * data,
+ int * col,
+ struct mailimf_orig_date * date);
+static int mailimf_date_time_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_date_time * date_time);
+static int mailimf_from_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_from * from);
+static int mailimf_sender_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_sender * sender);
+static int mailimf_reply_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_reply_to * reply_to);
+static int mailimf_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_to * to);
+static int mailimf_cc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_cc * to);
+static int mailimf_bcc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_bcc * to);
+static int mailimf_message_id_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_message_id * message_id);
+static int mailimf_msg_id_list_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ clist * list);
+static int mailimf_in_reply_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_in_reply_to *
+ in_reply_to);
+static int mailimf_references_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_references * references);
+static int mailimf_subject_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_subject * subject);
+
+static int mailimf_address_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_address * addr);
+static int mailimf_group_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_group * group);
+
+static int mailimf_mailbox_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_mailbox * mb);
+
+static int mailimf_comments_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_comments * comments);
+
+static int mailimf_optional_field_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_optional_field * field);
+
+static int mailimf_keywords_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_keywords * keywords);
+
+static int mailimf_return_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_return * return_path);
+
+static int mailimf_path_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_path * path);
+
+static int mailimf_resent_date_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_orig_date * date);
+
+static int mailimf_resent_from_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_from * from);
+
+static int mailimf_resent_sender_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_sender * sender);
+
+static int mailimf_resent_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_to * to);
+
+static int mailimf_resent_cc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_cc * cc);
+
+static int mailimf_resent_bcc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_bcc * bcc);
+
+static int
+mailimf_resent_msg_id_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_message_id * message_id);
+
+
+
+/* ************************ */
+
+#if 0
+int mailimf_string_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ char * str, size_t length)
+{
+ int r;
+
+ if (length != 0) {
+ r = fwrite(str, sizeof(char), length, f);
+ if (r < 0)
+ return MAILIMF_ERROR_FILE;
+ * col += length;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+#endif
+
+#define CRLF "\r\n"
+#define HEADER_FOLD "\r\n "
+
+static inline int flush_buf(int (* do_write)(void *, const char *, size_t), void * data, const char * str, size_t length)
+{
+ if (length != 0) {
+ int r;
+
+ if (length > 0) {
+ r = do_write(data, str, length);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+ }
+ }
+ return MAILIMF_NO_ERROR;
+}
+
+#define CUT_AT_MAX_VALID_IMF_LINE
+
+int mailimf_string_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ const char * str, size_t length)
+{
+ int r;
+ size_t count;
+ const char * block_begin;
+ const char * p;
+ int done;
+
+ p = str;
+ block_begin = str;
+ count = 0;
+
+ while (length > 0) {
+#ifdef CUT_AT_MAX_VALID_IMF_LINE
+ if (count >= 998) {
+ /*
+ cut lines at maximum valid length for internet message
+ format standard (currently RFC 2822)
+
+ This should not happen.
+ In case there are some lines larger than 998 in body,
+ the encoding must be changed into base64 or quoted-printable
+ so that wrapping to 72 columns is done.
+ */
+
+ r = flush_buf(do_write, data, block_begin, count);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = do_write(data, CRLF, sizeof(CRLF) - 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+
+ count = 0;
+ block_begin = p;
+
+ * col = 0;
+ }
+#endif
+ switch (* p) {
+ case '\n':
+ r = flush_buf(do_write, data, block_begin, count);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = do_write(data, CRLF, sizeof(CRLF) - 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+
+ p ++;
+ length --;
+ count = 0;
+ block_begin = p;
+
+ * col = 0;
+ break;
+
+ case '\r':
+ done = 0;
+ if (length >= 2) {
+ if (* (p + 1) == '\n') {
+ r = flush_buf(do_write, data, block_begin, count);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = do_write(data, CRLF, sizeof(CRLF) - 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+
+ p += 2;
+ length -= 2;
+ count = 0;
+ block_begin = p;
+
+ * col = 0;
+
+ done = 1;
+ }
+ }
+ if (!done) {
+ r = flush_buf(do_write, data, block_begin, count);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = do_write(data, CRLF, sizeof(CRLF) - 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+
+ p ++;
+ length --;
+ count = 0;
+ block_begin = p;
+
+ * col = 0;
+ }
+ break;
+
+ default:
+ p ++;
+ count ++;
+ length --;
+ break;
+ }
+ }
+
+ r = flush_buf(do_write, data, block_begin, count);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ * col += count;
+
+ return MAILIMF_NO_ERROR;
+}
+
+#if 0
+int mailimf_header_string_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ char * str, size_t length)
+{
+ char * p;
+ char * block_begin;
+ int current_col;
+ char * last_cut;
+ int r;
+ int first;
+
+ if (* col + length < MAX_MAIL_COL)
+ return mailimf_string_write_driver(do_write, data, col, str, length);
+
+ first = 1;
+ p = str;
+ block_begin = p;
+ last_cut = block_begin;
+ current_col = * col;
+
+ while (1) {
+ if (current_col >= MAX_MAIL_COL) {
+ /* if we reach the maximum recommanded size of line */
+ if (last_cut == block_begin) {
+ /* if we could not find any place to cut */
+ if (first) {
+ /* fold the header */
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ current_col = * col + p - block_begin;
+ first = 0;
+ }
+ else {
+ /* cut the header */
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, p - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ first = 0;
+ block_begin = p;
+ last_cut = block_begin;
+ current_col = * col + p - block_begin;
+ }
+ }
+ else {
+ /* if we found a place to cut */
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, last_cut - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ first = 0;
+ block_begin = last_cut;
+ last_cut = block_begin;
+ current_col = * col + p - block_begin;
+ continue;
+ }
+ }
+ else {
+ if (length == 0)
+ break;
+
+ switch (* p) {
+ case ' ':
+ case '\t':
+ last_cut = p;
+ current_col ++;
+ break;
+
+ case '\r':
+ case '\n':
+ current_col = 0;
+ break;
+
+ default:
+ current_col ++;
+ break;
+ }
+
+ p ++;
+ length --;
+ }
+ }
+
+ return mailimf_string_write_driver(do_write, data, col, block_begin, p - block_begin);
+}
+#endif
+
+#if 0
+enum {
+ STATE_LOWER_72,
+ STATE_LOWER_72_CUT,
+ STATE_EQUAL_72,
+ STATE_LOWER_998,
+ STATE_EQUAL_998,
+};
+
+int mailimf_header_string_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ const char * str, size_t length)
+{
+ int state;
+ const char * p;
+ const char * block_begin;
+ size_t size;
+ const char * cut;
+ int r;
+
+ if (* col < MAX_MAIL_COL)
+ state = STATE_LOWER_72_CUT;
+ else if (* col == MAX_MAIL_COL)
+ state = STATE_EQUAL_72;
+ else if (* col < MAX_VALID_IMF_LINE)
+ state = STATE_LOWER_998;
+ else
+ state = STATE_EQUAL_998;
+
+ p = str;
+ block_begin = p;
+ size = * col;
+ cut = p;
+
+ while (length > 0) {
+ switch (state) {
+ case STATE_LOWER_72:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ p ++;
+ length --;
+ size = 0;
+ break;
+
+ case ' ':
+ case '\t':
+ cut = p;
+ p ++;
+ length --;
+ size ++;
+ state = STATE_LOWER_72_CUT;
+ break;
+
+ default:
+ if (size < MAX_MAIL_COL - 1) {
+ p ++;
+ length --;
+ size ++;
+ }
+ else {
+ state = STATE_EQUAL_72;
+ p ++;
+ length --;
+ size ++;
+ }
+ break;
+ }
+ break; /* end of STATE_LOWER_72 */
+
+ case STATE_LOWER_72_CUT:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ p ++;
+ length --;
+ size = 0;
+ state = STATE_LOWER_72;
+ break;
+
+ case ' ':
+ case '\t':
+ cut = p;
+ p ++;
+ length --;
+ size ++;
+ break;
+
+ default:
+ if (size < MAX_MAIL_COL) {
+ p ++;
+ length --;
+ size ++;
+ }
+ else {
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, cut - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ p ++;
+ length --;
+ block_begin = cut;
+ if ((* block_begin == ' ') || (* block_begin == '\t'))
+ block_begin ++;
+ size = p - block_begin + * col;
+ state = STATE_LOWER_72;
+ }
+ break;
+ }
+ break; /* end of STATE_LOWER_72_CUT */
+
+ case STATE_EQUAL_72:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ p ++;
+ length --;
+ size = 0;
+ state = STATE_LOWER_72;
+ break;
+
+ case ' ':
+ case '\t':
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, p - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ p ++;
+ length --;
+ block_begin = p;
+ size = p - block_begin + * col;
+ state = STATE_LOWER_72;
+ break;
+
+ default:
+ p ++;
+ length --;
+ size ++;
+ state = STATE_LOWER_998;
+ break;
+ }
+ break; /* end of STATE_EQUAL_72 */
+
+ case STATE_LOWER_998:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ p ++;
+ length --;
+ size = 0;
+ state = STATE_LOWER_72;
+ break;
+
+ case ' ':
+ case '\t':
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, p - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ p ++;
+ length --;
+ block_begin = p;
+ size = p - block_begin + * col;
+ state = STATE_LOWER_72;
+ break;
+
+ default:
+ if (size < MAX_VALID_IMF_LINE - 1) {
+ p ++;
+ length --;
+ size ++;
+ }
+ else {
+ p ++;
+ length --;
+ size = 0;
+ state = STATE_EQUAL_998;
+ }
+ break;
+ }
+ break; /* end of STATE_LOWER_998 */
+
+ case STATE_EQUAL_998:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ p ++;
+ length --;
+ size = 0;
+ state = STATE_LOWER_72;
+ break;
+
+ case ' ':
+ case '\t':
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, p - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ p ++;
+ length --;
+ block_begin = p;
+ size = p - block_begin + * col;
+ state = STATE_LOWER_72;
+ break;
+
+ default:
+#ifdef CUT_AT_MAX_VALID_IMF_LINE
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, p - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ r = mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ p ++;
+ length --;
+ block_begin = p;
+ size = p - block_begin + * col;
+ state = STATE_LOWER_72;
+#else
+ p ++;
+ length --;
+ size ++;
+#endif
+ break;
+ }
+ break; /* end of STATE_EQUAL_998 */
+ }
+ }
+
+ r = mailimf_string_write_driver(do_write, data, col, block_begin, p - block_begin);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ return MAILIMF_NO_ERROR;
+}
+#endif
+
+enum {
+ STATE_BEGIN,
+ STATE_WORD,
+ STATE_SPACE,
+};
+
+int mailimf_header_string_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ const char * str, size_t length)
+{
+ int state;
+ const char * p;
+ const char * word_begin;
+ const char * word_end;
+ const char * next_word;
+ int first;
+
+ state = STATE_BEGIN;
+
+ p = str;
+ word_begin = p;
+ word_end = p;
+ next_word = p;
+ first = 1;
+
+ while (length > 0) {
+ switch (state) {
+ case STATE_BEGIN:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ case ' ':
+ case '\t':
+ p ++;
+ length --;
+ break;
+
+ default:
+ word_begin = p;
+ state = STATE_WORD;
+ break;
+ }
+ break;
+
+ case STATE_SPACE:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ case ' ':
+ case '\t':
+ p ++;
+ length --;
+ break;
+
+ default:
+ word_begin = p;
+ state = STATE_WORD;
+ break;
+ }
+ break;
+
+ case STATE_WORD:
+ switch (* p) {
+ case '\r':
+ case '\n':
+ case ' ':
+ case '\t':
+ if (p - word_begin + (* col) + 1 > MAX_MAIL_COL)
+ mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ else {
+ if (!first)
+ mailimf_string_write_driver(do_write, data, col, " ", 1);
+ }
+ first = 0;
+ mailimf_string_write_driver(do_write, data, col, word_begin, p - word_begin);
+ state = STATE_SPACE;
+ break;
+
+ default:
+ if (p - word_begin + (* col) >= MAX_VALID_IMF_LINE) {
+ mailimf_string_write_driver(do_write, data, col, word_begin, p - word_begin);
+ mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ word_begin = p;
+ }
+ p ++;
+ length --;
+ break;
+ }
+ break;
+ }
+ }
+
+ if (state == STATE_WORD) {
+ if (p - word_begin + (* col) >= MAX_MAIL_COL)
+ mailimf_string_write_driver(do_write, data, col, HEADER_FOLD,
+ sizeof(HEADER_FOLD) - 1);
+ else {
+ if (!first)
+ mailimf_string_write_driver(do_write, data, col, " ", 1);
+ }
+ first = 0;
+ mailimf_string_write_driver(do_write, data, col, word_begin, p - word_begin);
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+int mailimf_envelope_fields_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_fields * fields)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ int r;
+ struct mailimf_field * field;
+
+ field = clist_content(cur);
+ if (field->fld_type != MAILIMF_FIELD_OPTIONAL_FIELD) {
+ r = mailimf_field_write_driver(do_write, data, col, field);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+int mailimf_fields_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_fields * fields)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ int r;
+
+ r = mailimf_field_write_driver(do_write, data, col, clist_content(cur));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+#if 0
+int mailimf_unparsed_fields_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_unparsed_fields * fields)
+{
+ clistiter * cur;
+
+ for(cur = clist_begin(fields->list) ; cur != NULL ; cur = cur->next) {
+ int r;
+
+ r = mailimf_optional_field_write_driver(do_write, data, col, cur->data);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+#endif
+
+int mailimf_field_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_field * field)
+{
+ int r;
+
+ switch (field->fld_type) {
+ case MAILIMF_FIELD_RETURN_PATH:
+ r = mailimf_return_write_driver(do_write, data, col, field->fld_data.fld_return_path);
+ break;
+ case MAILIMF_FIELD_RESENT_DATE:
+ r = mailimf_resent_date_write_driver(do_write, data, col, field->fld_data.fld_resent_date);
+ break;
+ case MAILIMF_FIELD_RESENT_FROM:
+ r = mailimf_resent_from_write_driver(do_write, data, col, field->fld_data.fld_resent_from);
+ break;
+ case MAILIMF_FIELD_RESENT_SENDER:
+ r = mailimf_resent_sender_write_driver(do_write, data, col, field->fld_data.fld_resent_sender);
+ break;
+ case MAILIMF_FIELD_RESENT_TO:
+ r = mailimf_resent_to_write_driver(do_write, data, col, field->fld_data.fld_resent_to);
+ break;
+ case MAILIMF_FIELD_RESENT_CC:
+ r = mailimf_resent_cc_write_driver(do_write, data, col, field->fld_data.fld_resent_cc);
+ break;
+ case MAILIMF_FIELD_RESENT_BCC:
+ r = mailimf_resent_bcc_write_driver(do_write, data, col, field->fld_data.fld_resent_bcc);
+ break;
+ case MAILIMF_FIELD_RESENT_MSG_ID:
+ r = mailimf_resent_msg_id_write_driver(do_write, data, col, field->fld_data.fld_resent_msg_id);
+ break;
+ case MAILIMF_FIELD_ORIG_DATE:
+ r = mailimf_orig_date_write_driver(do_write, data, col, field->fld_data.fld_orig_date);
+ break;
+ case MAILIMF_FIELD_FROM:
+ r = mailimf_from_write_driver(do_write, data, col, field->fld_data.fld_from);
+ break;
+ case MAILIMF_FIELD_SENDER:
+ r = mailimf_sender_write_driver(do_write, data, col, field->fld_data.fld_sender);
+ break;
+ case MAILIMF_FIELD_REPLY_TO:
+ r = mailimf_reply_to_write_driver(do_write, data, col, field->fld_data.fld_reply_to);
+ break;
+ case MAILIMF_FIELD_TO:
+ r = mailimf_to_write_driver(do_write, data, col, field->fld_data.fld_to);
+ break;
+ case MAILIMF_FIELD_CC:
+ r = mailimf_cc_write_driver(do_write, data, col, field->fld_data.fld_cc);
+ break;
+ case MAILIMF_FIELD_BCC:
+ r = mailimf_bcc_write_driver(do_write, data, col, field->fld_data.fld_bcc);
+ break;
+ case MAILIMF_FIELD_MESSAGE_ID:
+ r = mailimf_message_id_write_driver(do_write, data, col, field->fld_data.fld_message_id);
+ break;
+ case MAILIMF_FIELD_IN_REPLY_TO:
+ r = mailimf_in_reply_to_write_driver(do_write, data, col, field->fld_data.fld_in_reply_to);
+ break;
+ case MAILIMF_FIELD_REFERENCES:
+ r = mailimf_references_write_driver(do_write, data, col, field->fld_data.fld_references);
+ break;
+ case MAILIMF_FIELD_SUBJECT:
+ r = mailimf_subject_write_driver(do_write, data, col, field->fld_data.fld_subject);
+ break;
+ case MAILIMF_FIELD_COMMENTS:
+ r = mailimf_comments_write_driver(do_write, data, col, field->fld_data.fld_comments);
+ break;
+ case MAILIMF_FIELD_KEYWORDS:
+ r = mailimf_keywords_write_driver(do_write, data, col, field->fld_data.fld_keywords);
+ break;
+ case MAILIMF_FIELD_OPTIONAL_FIELD:
+ r = mailimf_optional_field_write_driver(do_write, data, col, field->fld_data.fld_optional_field);
+ break;
+ default:
+ r = MAILIMF_ERROR_INVAL;
+ break;
+ }
+
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_orig_date_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_orig_date * date)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Date: ", 6);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_date_time_write_driver(do_write, data, col, date->dt_date_time);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+#define MAX_DATE_STR 256
+
+/* 0 = Sunday */
+/* y > 1752 */
+
+static int dayofweek(int year, int month, int day)
+{
+ static int offset[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
+
+ year -= month < 3;
+
+ return (year + year/4 - year/100 + year/400 + offset[month-1] + day) % 7;
+}
+
+static const char * week_of_day_str[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
+ "Fri", "Sat"};
+static const char * month_str[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+static int mailimf_date_time_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_date_time * date_time)
+{
+ int r;
+ char date_str[MAX_DATE_STR];
+#if 0
+ struct tm tmval;
+ time_t timeval;
+#endif
+ int wday;
+
+#if 0
+ tmval.tm_sec = date_time->sec;
+ tmval.tm_min = date_time->min;
+ tmval.tm_hour = date_time->hour;
+ tmval.tm_sec = date_time->sec;
+ tmval.tm_mday = date_time->day;
+ tmval.tm_mon = date_time->month - 1;
+ tmval.tm_year = date_time->year - 1900;
+ tmval.tm_isdst = 1;
+
+ timeval = mktime(&tmval);
+
+ localtime_r(&timeval, &tmval);
+#endif
+
+ wday = dayofweek(date_time->dt_year, date_time->dt_month, date_time->dt_day);
+
+ snprintf(date_str, MAX_DATE_STR, "%s, %i %s %i %02i:%02i:%02i %+05i",
+ week_of_day_str[wday], date_time->dt_day,
+ month_str[date_time->dt_month - 1],
+ date_time->dt_year, date_time->dt_hour,
+ date_time->dt_min, date_time->dt_sec,
+ date_time->dt_zone);
+
+ r = mailimf_string_write_driver(do_write, data, col, date_str, strlen(date_str));
+
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_from_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_from * from)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "From: ", 6);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_mailbox_list_write_driver(do_write, data, col, from->frm_mb_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_sender_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_sender * sender)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Sender: ", 8);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_mailbox_write_driver(do_write, data, col, sender->snd_mb);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_reply_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_reply_to * reply_to)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Reply-To: ", 10);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_address_list_write_driver(do_write, data, col, reply_to->rt_addr_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_to * to)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "To: ", 4);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_address_list_write_driver(do_write, data, col, to->to_addr_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_cc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_cc * cc)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Cc: ", 4);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_address_list_write_driver(do_write, data, col, cc->cc_addr_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_bcc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_bcc * bcc)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Bcc: ", 5);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ if (bcc->bcc_addr_list != NULL) {
+ r = mailimf_address_list_write_driver(do_write, data, col, bcc->bcc_addr_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_message_id_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_message_id * message_id)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Message-ID: ", 12);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "<", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col,
+ message_id->mid_value,
+ strlen(message_id->mid_value));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, ">", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_msg_id_list_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, clist * mid_list)
+{
+ clistiter * cur;
+ int r;
+ int first;
+
+ first = TRUE;
+
+ for(cur = clist_begin(mid_list) ; cur != NULL ; cur = clist_next(cur)) {
+ char * msgid;
+ size_t len;
+
+ msgid = clist_content(cur);
+ len = strlen(msgid);
+
+ /*
+ XXX - if this is the first message ID, don't fold.
+ This is a workaround for a bug of old versions of INN.
+ */
+ if (!first) {
+ if (* col > 1) {
+
+ if (* col + len >= MAX_MAIL_COL) {
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 1;
+#endif
+ first = TRUE;
+ }
+ }
+ }
+
+ if (!first) {
+ r = mailimf_string_write_driver(do_write, data, col, " ", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ else {
+ first = FALSE;
+ }
+
+ r = mailimf_string_write_driver(do_write, data, col, "<", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, msgid, len);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, ">", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_in_reply_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_in_reply_to * in_reply_to)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "In-Reply-To: ", 13);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_msg_id_list_write_driver(do_write, data, col, in_reply_to->mid_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_references_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_references * references)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "References: ", 12);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_msg_id_list_write_driver(do_write, data, col, references->mid_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+
+static int mailimf_subject_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_subject * subject)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Subject: ", 9);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_header_string_write_driver(do_write, data, col,
+ subject->sbj_value, strlen(subject->sbj_value));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+int mailimf_address_list_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_address_list * addr_list)
+{
+ clistiter * cur;
+ int r;
+ int first;
+
+ first = TRUE;
+
+ for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimf_address * addr;
+
+ addr = clist_content(cur);
+
+ if (!first) {
+ r = mailimf_string_write_driver(do_write, data, col, ", ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ else {
+ first = FALSE;
+ }
+
+ r = mailimf_address_write_driver(do_write, data, col, addr);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_address_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_address * addr)
+{
+ int r;
+
+ switch(addr->ad_type) {
+ case MAILIMF_ADDRESS_MAILBOX:
+ r = mailimf_mailbox_write_driver(do_write, data, col, addr->ad_data.ad_mailbox);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ break;
+
+ case MAILIMF_ADDRESS_GROUP:
+ r = mailimf_group_write_driver(do_write, data, col, addr->ad_data.ad_group);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ break;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_group_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_group * group)
+{
+ int r;
+
+ r = mailimf_header_string_write_driver(do_write, data, col, group->grp_display_name,
+ strlen(group->grp_display_name));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, ": ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ if (group->grp_mb_list != NULL) {
+ r = mailimf_mailbox_list_write_driver(do_write, data, col, group->grp_mb_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ r = mailimf_string_write_driver(do_write, data, col, ";", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+int mailimf_mailbox_list_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_mailbox_list * mb_list)
+{
+ clistiter * cur;
+ int r;
+ int first;
+
+ first = TRUE;
+
+ for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimf_mailbox * mb;
+
+ mb = clist_content(cur);
+
+ if (!first) {
+ r = mailimf_string_write_driver(do_write, data, col, ", ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ else {
+ first = FALSE;
+ }
+
+ r = mailimf_mailbox_write_driver(do_write, data, col, mb);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+int mailimf_quoted_string_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ const char * string, size_t len)
+{
+ int r;
+ size_t i;
+
+ r = do_write(data, "\"", 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+ for(i = 0 ; i < len ; i ++) {
+ switch (string[i]) {
+ case '\\':
+ case '\"':
+ r = do_write(data, "\\", 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+ r = do_write(data, &string[i], 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+ (* col) += 2;
+ break;
+
+ default:
+ r = do_write(data, &string[i], 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+ (* col) ++;
+ break;
+ }
+ }
+ r = do_write(data, "\"", 1);
+ if (r == 0)
+ return MAILIMF_ERROR_FILE;
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+/*
+static int
+atext = ALPHA / DIGIT / ; Any character except controls,
+ "!" / "#" / ; SP, and specials.
+ "$" / "%" / ; Used for atoms
+ "&" / "'" /
+ "*" / "+" /
+ "-" / "/" /
+ "=" / "?" /
+ "^" / "_" /
+ "`" / "{" /
+ "|" / "}" /
+ "~"
+*/
+
+static int is_atext(const char * s)
+{
+ const char * p;
+
+ for(p = s ; * p != 0 ; p ++) {
+ if (isalpha((unsigned char) * p))
+ continue;
+ if (isdigit((unsigned char) * p))
+ continue;
+ switch (*p) {
+ case ' ':
+ case '\t':
+ case '!':
+ case '#':
+ case '$':
+ case '%':
+ case '&':
+ case '\'':
+ case '*':
+ case '+':
+ case '-':
+ case '/':
+ case '=':
+ case '?':
+ case '^':
+ case '_':
+ case '`':
+ case '{':
+ case '|':
+ case '}':
+ case '~':
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int mailimf_mailbox_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_mailbox * mb)
+{
+ int r;
+ int do_fold;
+
+#if 0
+ if (* col > 1) {
+
+ if (mb->mb_display_name != NULL) {
+ if (* col + strlen(mb->mb_display_name) >= MAX_MAIL_COL) {
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 1;
+#endif
+ }
+ }
+ }
+#endif
+
+ if (mb->mb_display_name) {
+
+ if (is_atext(mb->mb_display_name)) {
+ r = mailimf_header_string_write_driver(do_write, data, col, mb->mb_display_name,
+ strlen(mb->mb_display_name));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ else {
+ if (mb->mb_display_name != NULL) {
+ if (* col + strlen(mb->mb_display_name) >= MAX_MAIL_COL) {
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ }
+
+ if (strlen(mb->mb_display_name) > MAX_VALID_IMF_LINE / 2)
+ return MAILIMF_ERROR_INVAL;
+
+ r = mailimf_quoted_string_write_driver(do_write, data, col, mb->mb_display_name,
+ strlen(mb->mb_display_name));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ do_fold = 0;
+ if (* col > 1) {
+
+ if (* col + strlen(mb->mb_addr_spec) + 3 >= MAX_MAIL_COL) {
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 1;
+#endif
+ do_fold = 1;
+ }
+ }
+
+ if (do_fold)
+ r = mailimf_string_write_driver(do_write, data, col, "<", 1);
+ else
+ r = mailimf_string_write_driver(do_write, data, col, " <", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, mb->mb_addr_spec,
+ strlen(mb->mb_addr_spec));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, ">", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ else {
+ if (* col + strlen(mb->mb_addr_spec) >= MAX_MAIL_COL) {
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ r = mailimf_string_write_driver(do_write, data, col,
+ mb->mb_addr_spec, strlen(mb->mb_addr_spec));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_comments_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_comments * comments)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Comments: ", 10);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_header_string_write_driver(do_write, data, col,
+ comments->cm_value, strlen(comments->cm_value));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_optional_field_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_optional_field * field)
+{
+ int r;
+
+ if (strlen(field->fld_name) + 2 > MAX_VALID_IMF_LINE)
+ return MAILIMF_ERROR_INVAL;
+
+ r = mailimf_string_write_driver(do_write, data, col, field->fld_name, strlen(field->fld_name));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, ": ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_header_string_write_driver(do_write, data, col, field->fld_value,
+ strlen(field->fld_value));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+#if 0
+ /* XXX parsing debug */
+ mailimf_string_write_driver(do_write, data, col, " (X)", 4);
+#endif
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_keywords_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_keywords * keywords)
+{
+ int r;
+ clistiter * cur;
+ int first;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Keywords: ", 10);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ first = TRUE;
+
+ for(cur = clist_begin(keywords->kw_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ char * keyword;
+ size_t len;
+
+ keyword = clist_content(cur);
+ len = strlen(keyword);
+
+ if (!first) {
+ r = mailimf_string_write_driver(do_write, data, col, ", ", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+ else {
+ first = FALSE;
+ }
+
+#if 0
+ if (* col > 1) {
+
+ if (* col + len >= MAX_MAIL_COL) {
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n ", 3);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 1;
+#endif
+ }
+ }
+#endif
+
+ r = mailimf_header_string_write_driver(do_write, data, col, keyword, len);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+#if 0
+static int mailimf_delivering_info_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_delivering_info * info)
+{
+ clistiter * cur;
+ int r;
+
+ for(cur = clist_begin(info->received_fields) ;
+ cur != NULL ; cur = cur->next) {
+ struct mailimf_trace_resent_fields * field;
+
+ field = cur->data;
+
+ r = mailimf_trace_resent_fields_write_driver(do_write, data, col, field);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int
+mailimf_trace_resent_fields_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_trace_resent_fields * field)
+{
+ int r;
+
+ if (field->return_path != NULL) {
+ r = mailimf_return_write_driver(do_write, data, col, field->return_path);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ if (field->resent_fields != NULL) {
+ r = mailimf_resent_fields_write_driver(do_write, data, col, field->resent_fields);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+#endif
+
+static int mailimf_return_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_return * return_path)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Return-Path: ", 13);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_path_write_driver(do_write, data, col, return_path->ret_path);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_path_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_path * path)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "<", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, path->pt_addr_spec,
+ strlen(path->pt_addr_spec));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, ">", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ return MAILIMF_NO_ERROR;
+}
+
+#if 0
+static int mailimf_resent_fields_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_resent_fields_list *
+ resent_fields)
+{
+ clistiter * cur;
+ int r;
+
+ for(cur = clist_begin(resent_fields->list) ; cur != NULL ; cur = cur->next) {
+ struct mailimf_resent_field * field;
+
+ field = cur->data;
+
+ r = mailimf_resent_field_write_driver(do_write, data, col, field);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+
+static int mailimf_resent_field_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_resent_field *
+ resent_field)
+{
+ int r;
+
+ switch (resent_field->type) {
+ case MAILIMF_RESENT_FIELD_DATE:
+ r = mailimf_resent_date_write_driver(do_write, data, col, resent_field->resent_date);
+ break;
+
+ case MAILIMF_RESENT_FIELD_FROM:
+ r = mailimf_resent_from_write_driver(do_write, data, col, resent_field->resent_from);
+ break;
+
+ case MAILIMF_RESENT_FIELD_SENDER:
+ r = mailimf_resent_sender_write_driver(do_write, data, col, resent_field->resent_sender);
+ break;
+
+ case MAILIMF_RESENT_FIELD_TO:
+ r = mailimf_resent_to_write_driver(do_write, data, col, resent_field->resent_to);
+ break;
+
+ case MAILIMF_RESENT_FIELD_CC:
+ r = mailimf_resent_cc_write_driver(do_write, data, col, resent_field->resent_cc);
+ break;
+
+ case MAILIMF_RESENT_FIELD_BCC:
+ r = mailimf_resent_bcc_write_driver(do_write, data, col, resent_field->resent_bcc);
+ break;
+
+ case MAILIMF_RESENT_FIELD_MSG_ID:
+ r = mailimf_resent_msg_id_write_driver(do_write, data, col, resent_field->resent_msg_id);
+ break;
+ default:
+ r = MAILIMF_ERROR_INVAL;
+ break;
+ }
+
+
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ return MAILIMF_NO_ERROR;
+}
+#endif
+
+static int mailimf_resent_date_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_orig_date * date)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Resent-Date: ", 13);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_date_time_write_driver(do_write, data, col, date->dt_date_time);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_resent_from_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_from * from)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Resent-From: ", 13);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_mailbox_list_write_driver(do_write, data, col, from->frm_mb_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_resent_sender_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_sender * sender)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Resent-Sender: ", 15);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_mailbox_write_driver(do_write, data, col, sender->snd_mb);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+static int mailimf_resent_to_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_to * to)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Resent-To: ", 11);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_address_list_write_driver(do_write, data, col, to->to_addr_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_resent_cc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_cc * cc)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Resent-Cc: ", 11);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_address_list_write_driver(do_write, data, col, cc->cc_addr_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int mailimf_resent_bcc_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_bcc * bcc)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Resent-Bcc: ", 12);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ if (bcc->bcc_addr_list != NULL) {
+ r = mailimf_address_list_write_driver(do_write, data, col, bcc->bcc_addr_list);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+ }
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}
+
+
+static int
+mailimf_resent_msg_id_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col,
+ struct mailimf_message_id * message_id)
+{
+ int r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "Resent-Message-ID: ", 19);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "<", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col,
+ message_id->mid_value, strlen(message_id->mid_value));
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, ">", 1);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+
+ r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2);
+ if (r != MAILIMF_NO_ERROR)
+ return r;
+#if 0
+ * col = 0;
+#endif
+
+ return MAILIMF_NO_ERROR;
+}