Mercurial > dovecot > original-hg > dovecot-1.2
changeset 437:20d5136a0c6a HEAD
Fixed several problems with FETCH BODY[..]<limits>, especially related to
handling missing CRs.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 16 Oct 2002 02:46:42 +0300 |
parents | 8a252e6567d7 |
children | 8fd9842b64d9 |
files | src/lib-imap/imap-message-cache.c src/lib-imap/imap-message-cache.h src/lib-mail/message-send.c src/lib-mail/message-send.h src/lib-storage/index/index-fetch-section.c |
diffstat | 5 files changed, 46 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-imap/imap-message-cache.c Wed Oct 16 00:35:27 2002 +0300 +++ b/src/lib-imap/imap-message-cache.c Wed Oct 16 02:46:42 2002 +0300 @@ -424,12 +424,9 @@ static void get_partial_size(IBuffer *inbuf, uoff_t virtual_skip, uoff_t max_virtual_size, - MessageSize *partial, MessageSize *dest) + MessageSize *partial, MessageSize *dest, + int *cr_skipped) { - const unsigned char *msg; - size_t size; - int cr_skipped; - /* see if we can use the existing partial */ if (partial->virtual_size > virtual_skip) memset(partial, 0, sizeof(MessageSize)); @@ -438,32 +435,30 @@ virtual_skip -= partial->virtual_size; } - message_skip_virtual(inbuf, virtual_skip, partial, &cr_skipped); + message_skip_virtual(inbuf, virtual_skip, partial, cr_skipped); + message_get_body_size(inbuf, dest, max_virtual_size); - if (!cr_skipped) { - /* see if we need to add virtual CR */ - if (i_buffer_read_data(inbuf, &msg, &size, 0) > 0) { - if (msg[0] == '\n') - dest->virtual_size++; - } + if (*cr_skipped) { + dest->virtual_size--; + partial->virtual_size--; } - - message_get_body_size(inbuf, dest, max_virtual_size); } int imap_msgcache_get_rfc822_partial(ImapMessageCache *cache, uoff_t virtual_skip, uoff_t max_virtual_size, int get_header, MessageSize *size, - IBuffer **inbuf) + IBuffer **inbuf, int *cr_skipped) { CachedMessage *msg; - uoff_t physical_skip; + uoff_t physical_skip, full_size; int size_got; i_assert(cache->open_msg != NULL); + memset(size, 0, sizeof(MessageSize)); *inbuf = NULL; + *cr_skipped = FALSE; msg = cache->open_msg; if (msg->hdr_size == NULL) { @@ -472,8 +467,6 @@ return FALSE; } - physical_skip = get_header ? 0 : msg->hdr_size->physical_size; - /* see if we can do this easily */ size_got = FALSE; if (virtual_skip == 0) { @@ -483,27 +476,35 @@ return FALSE; } - if (max_virtual_size >= msg->body_size->virtual_size) { - *size = *msg->body_size; + full_size = msg->body_size->virtual_size; + if (get_header) + full_size += msg->hdr_size->virtual_size; + + if (max_virtual_size >= full_size) { + memcpy(size, msg->body_size, sizeof(MessageSize)); + if (get_header) + message_size_add(size, msg->hdr_size); size_got = TRUE; } } - if (!size_got) { - if (!imap_msgcache_get_inbuf(cache, - msg->hdr_size->physical_size)) + if (size_got) { + physical_skip = get_header ? 0 : msg->hdr_size->physical_size; + } else { + if (!imap_msgcache_get_inbuf(cache, 0)) return FALSE; if (msg->partial_size == NULL) msg->partial_size = p_new(msg->pool, MessageSize, 1); - get_partial_size(cache->open_inbuf, virtual_skip, - max_virtual_size, msg->partial_size, size); + if (!get_header) + virtual_skip += msg->hdr_size->virtual_size; - physical_skip += msg->partial_size->physical_size; - } + get_partial_size(cache->open_inbuf, virtual_skip, + max_virtual_size, msg->partial_size, size, + cr_skipped); - if (get_header) - message_size_add(size, msg->hdr_size); + physical_skip = msg->partial_size->physical_size; + } /* seek to wanted position */ if (!imap_msgcache_get_inbuf(cache, physical_skip))
--- a/src/lib-imap/imap-message-cache.h Wed Oct 16 00:35:27 2002 +0300 +++ b/src/lib-imap/imap-message-cache.h Wed Oct 16 02:46:42 2002 +0300 @@ -63,12 +63,14 @@ MessageSize *hdr_size, MessageSize *body_size); /* Returns TRUE if successful. *inbuf is set to point to the first non-skipped - character. size is set to specify the full size of message. */ + character. size is set to specify the actual message size in + virtual_skip..max_virtual_size range. cr_skipped is set to TRUE if first + character in inbuf is LF, and we should NOT treat it as CR+LF. */ int imap_msgcache_get_rfc822_partial(ImapMessageCache *cache, uoff_t virtual_skip, uoff_t max_virtual_size, int get_header, MessageSize *size, - IBuffer **inbuf); + IBuffer **inbuf, int *cr_skipped); /* Returns TRUE if successful. *inbuf is set to point to beginning of message. */
--- a/src/lib-mail/message-send.c Wed Oct 16 00:35:27 2002 +0300 +++ b/src/lib-mail/message-send.c Wed Oct 16 02:46:42 2002 +0300 @@ -10,7 +10,7 @@ uoff_t virtual_skip, uoff_t max_virtual_size) { const unsigned char *msg; - uoff_t old_limit; + uoff_t old_limit, limit; size_t i, size; int cr_skipped, add_cr, ret; @@ -26,8 +26,8 @@ i_buffer_skip(inbuf, virtual_skip); old_limit = inbuf->v_limit; - i_buffer_set_read_limit(inbuf, - I_MIN(max_virtual_size, old_limit)); + limit = inbuf->v_offset + max_virtual_size; + i_buffer_set_read_limit(inbuf, I_MIN(limit, old_limit)); ret = o_buffer_send_ibuffer(outbuf, inbuf) > 0; i_buffer_set_read_limit(inbuf, old_limit);
--- a/src/lib-mail/message-send.h Wed Oct 16 00:35:27 2002 +0300 +++ b/src/lib-mail/message-send.h Wed Oct 16 02:46:42 2002 +0300 @@ -5,7 +5,8 @@ /* 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. Returns TRUE if successful. */ + use (uoff_t)-1. Remember that if inbuf begins with LF, CR is inserted + before it unless virtual_skip = 1. Returns TRUE if successful. */ int message_send(OBuffer *outbuf, IBuffer *inbuf, MessageSize *msg_size, uoff_t virtual_skip, uoff_t max_virtual_size);
--- a/src/lib-storage/index/index-fetch-section.c Wed Oct 16 00:35:27 2002 +0300 +++ b/src/lib-storage/index/index-fetch-section.c Wed Oct 16 02:46:42 2002 +0300 @@ -45,10 +45,11 @@ MessageSize size; IBuffer *inbuf; const char *str; + int cr_skipped; if (!imap_msgcache_get_rfc822_partial(ctx->cache, sect->skip, sect->max_size, fetch_header, - &size, &inbuf)) { + &size, &inbuf, &cr_skipped)) { i_error("Couldn't get BODY[] for UID %u (index %s)", rec->uid, ctx->index->filepath); return FALSE; @@ -59,7 +60,11 @@ if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) return FALSE; - return message_send(ctx->outbuf, inbuf, &size, 0, sect->max_size); + if (cr_skipped) + size.virtual_size++; + + return message_send(ctx->outbuf, inbuf, &size, + cr_skipped ? 1 : 0, sect->max_size); } static char *const *get_fields_array(const char *fields)