# HG changeset patch # User Timo Sirainen # Date 1068324427 -7200 # Node ID d9d05fc3c90574ec3bfd12da1409d6b299aaafa1 # Parent c6d327242fa61241ffd7214f3a845bed68f44e48 message_send()'s skip parameter was buggy with messages having CRLF. diff -r c6d327242fa6 -r d9d05fc3c905 src/imap/imap-fetch-body-section.c --- a/src/imap/imap-fetch-body-section.c Sat Nov 08 20:17:15 2003 +0200 +++ b/src/imap/imap-fetch-body-section.c Sat Nov 08 22:47:07 2003 +0200 @@ -305,7 +305,7 @@ const void *data; size_t data_size; uoff_t start_offset, send_size; - int failed; + int failed, skip_cr; /* HEADER, MIME, HEADER.FIELDS (list), HEADER.FIELDS.NOT (list) */ @@ -316,8 +316,12 @@ ctx->prefix, send_size); if (o_stream_send_str(ctx->output, str) < 0) return FALSE; + + skip_cr = seek_partial(ctx->select_counter, mail->uid, + &partial, input, 0, body->skip); + return message_send(ctx->output, input, size, - body->skip, send_size, NULL, + skip_cr, send_size, NULL, !mail->has_no_nuls) >= 0; } diff -r c6d327242fa6 -r d9d05fc3c905 src/lib-mail/message-send.c --- a/src/lib-mail/message-send.c Sat Nov 08 20:17:15 2003 +0200 +++ b/src/lib-mail/message-send.c Sat Nov 08 22:47:07 2003 +0200 @@ -9,41 +9,30 @@ off_t message_send(struct ostream *output, struct istream *input, const struct message_size *msg_size, - uoff_t virtual_skip, uoff_t max_virtual_size, int *last_cr, + int cr_skipped, uoff_t max_virtual_size, int *last_cr, int fix_nuls) { const unsigned char *msg; - uoff_t old_limit, limit; size_t i, size; off_t ret; - int cr_skipped; unsigned char add; if (last_cr != NULL) *last_cr = -1; - if (msg_size->physical_size == 0 || - virtual_skip >= msg_size->virtual_size) + if (msg_size->physical_size == 0) return 0; - if (max_virtual_size > msg_size->virtual_size - virtual_skip) - max_virtual_size = msg_size->virtual_size - virtual_skip; - if (msg_size->physical_size == msg_size->virtual_size && !fix_nuls) { /* no need to kludge with CRs, we can use sendfile() */ - i_stream_skip(input, virtual_skip); - - old_limit = input->v_limit; - limit = input->v_offset + max_virtual_size; - i_stream_set_read_limit(input, I_MIN(limit, old_limit)); + input = i_stream_create_limit(default_pool, input, + input->v_offset, + max_virtual_size); ret = o_stream_send_istream(output, input); - i_stream_set_read_limit(input, old_limit); - + i_stream_unref(input); return ret; } - message_skip_virtual(input, virtual_skip, NULL, 0, &cr_skipped); - /* go through the message data and insert CRs where needed. */ ret = 0; while (max_virtual_size > 0 && @@ -53,8 +42,8 @@ max_virtual_size--; if (msg[i] == '\n') { - if ((i == 0 && !cr_skipped) || - (i > 0 && msg[i-1] != '\r')) { + if ((i > 0 && msg[i-1] != '\r') || + (i == 0 && !cr_skipped)) { /* missing CR */ add = '\r'; break; diff -r c6d327242fa6 -r d9d05fc3c905 src/lib-mail/message-send.h --- a/src/lib-mail/message-send.h Sat Nov 08 20:17:15 2003 +0200 +++ b/src/lib-mail/message-send.h Sat Nov 08 22:47:07 2003 +0200 @@ -4,13 +4,12 @@ struct message_size; /* Send message to client inserting CRs if needed. Only max_virtual_size - bytes if sent (relative to virtual_skip), if you want it unlimited, - use (uoff_t)-1. Remember that if input begins with LF, CR is inserted - before it unless virtual_skip = 1. last_cr is set to 1, 0 or -1 if not - known. Returns number of bytes sent, or -1 if error. */ + bytes are sent. If cr_skipped is FALSE and input begins with LF, it's + treated as CRLF. last_cr is set to 1, 0 or -1 if not known. Returns number + of bytes sent, or -1 if error. */ off_t message_send(struct ostream *output, struct istream *input, const struct message_size *msg_size, - uoff_t virtual_skip, uoff_t max_virtual_size, int *last_cr, + int cr_skipped, uoff_t max_virtual_size, int *last_cr, int fix_nuls); /* Skip number of virtual bytes from putfer. msg_size is updated if it's not