# HG changeset patch # User Timo Sirainen # Date 1030018355 -10800 # Node ID 21c8e080150d67bf48a05e599568c14e2293d35a # Parent 2d8711a043a06c128ec38286cb1d2850e36c662a fixes, seems to be somewhat working now. diff -r 2d8711a043a0 -r 21c8e080150d src/lib-imap/imap-message-cache.h --- a/src/lib-imap/imap-message-cache.h Thu Aug 22 01:45:34 2002 +0300 +++ b/src/lib-imap/imap-message-cache.h Thu Aug 22 15:12:35 2002 +0300 @@ -1,10 +1,9 @@ #ifndef __IMAP_MESSAGE_CACHE_H #define __IMAP_MESSAGE_CACHE_H -// FIXME: update comments - /* IMAP message cache. Caches are mailbox-specific and must be cleared - if UID validity changes. + if UID validity changes. Also if message data may have changed, + imap_msgcache_close() must be called. Caching is mostly done to avoid parsing the same message multiple times when client fetches the message in parts. @@ -59,22 +58,22 @@ /* Returns the root MessagePart for message, or NULL if it's not cached. */ MessagePart *imap_msgcache_get_parts(ImapMessageCache *cache, unsigned int uid); -/* Returns FALSE if message isn't in cache. If data is not NULL, it's set to - point to beginning of message data. If fd is not NULL, it's set to contain - the message file descriptor seeked to same position as *data. If hdr_size - is NULL, *data contains only the message body. */ +/* Returns FALSE if message isn't in cache. If inbuf is not NULL, it's set + to point to beginning of message, or to beginning of message body if + hdr_size is NULL. */ int imap_msgcache_get_rfc822(ImapMessageCache *cache, unsigned int uid, MessageSize *hdr_size, MessageSize *body_size, IOBuffer **inbuf); /* Returns FALSE if message isn't in cache. *inbuf is set to point to the first - non-skipped character. size is set to specify the full size for message. */ + non-skipped character. size is set to specify the full size of message. */ int imap_msgcache_get_rfc822_partial(ImapMessageCache *cache, unsigned int uid, off_t virtual_skip, off_t max_virtual_size, int get_header, MessageSize *size, IOBuffer **inbuf); -/* Like imap_msgcache_get_rfc822() without calculating virtual sizes. */ +/* Returns FALSE if message isn't in cache. *inbuf is set to point to + beginning of message. */ int imap_msgcache_get_data(ImapMessageCache *cache, unsigned int uid, IOBuffer **inbuf); diff -r 2d8711a043a0 -r 21c8e080150d src/lib-mail/message-parser.c --- a/src/lib-mail/message-parser.c Thu Aug 22 01:45:34 2002 +0300 +++ b/src/lib-mail/message-parser.c Thu Aug 22 15:12:35 2002 +0300 @@ -5,6 +5,7 @@ #include "rfc822-tokenize.h" #include "message-content-parser.h" #include "message-parser.h" +#include "message-size.h" typedef struct _MessageBoundary { struct _MessageBoundary *next; @@ -266,7 +267,7 @@ while (io_buffer_read_data(inbuf, &msg, &size, startpos) >= 0) { for (i = startpos; i < size; i++) { if (msg[i] == '\n') { - if (i > 0 && msg[i-1] != '\r') + if (i == 0 || msg[i-1] != '\r') msg_size->virtual_size++; if (msg_size != NULL) msg_size->lines++; @@ -275,7 +276,7 @@ } if (i < size) { - startpos = i; + startpos = i+1; break; } @@ -337,7 +338,7 @@ the \n ending the header. */ size--; for (i = startpos; i < size; i++) { - if (msg[i] == ':' && colon_pos != UINT_MAX) { + if (msg[i] == ':' && colon_pos == UINT_MAX) { colon_pos = i; continue; } @@ -355,14 +356,12 @@ if (i == 0 || (i == 1 && msg[i-1] == '\r')) { /* no headers at all */ - i++; break; } if ((i > 0 && msg[i-1] == '\n') || (i > 1 && msg[i-2] == '\n' && msg[i-1] == '\r')) { /* \n\n or \n\r\n - end of headers */ - i++; break; } @@ -401,7 +400,7 @@ if (i < size) { /* end of header */ - startpos = i; + startpos = i+1; break; } @@ -450,13 +449,10 @@ message_find_boundary(IOBuffer *inbuf, MessageBoundary *boundaries, MessageSize *msg_size, int skip_over) { - // FIXME: probably lots of bugs in this function MessageBoundary *boundary; unsigned char *msg; unsigned int i, size, startpos, line_start, missing_cr_count; - memset(msg_size, 0, sizeof(MessageSize)); - boundary = NULL; missing_cr_count = startpos = line_start = 0; @@ -475,7 +471,7 @@ break; } - if (i > 0 && msg[i-1] != '\r') { + if (i == 0 || msg[i-1] != '\r') { /* missing CR */ missing_cr_count++; } @@ -515,38 +511,33 @@ io_buffer_skip(inbuf, i); msg_size->physical_size += i; + msg_size->virtual_size += i; startpos = size - i; } } if (boundary != NULL) { - msg_size->physical_size += line_start - startpos; - if (skip_over) { /* leave the pointer right after the boundary */ line_start += 2 + boundary->len; } else if (line_start > 0 && msg[line_start-1] == '\n') { /* leave the \r\n before the boundary */ line_start--; - msg_size->physical_size--; msg_size->lines--; - if (line_start > 0 && msg[line_start-1] == '\r') { + if (line_start > 0 && msg[line_start-1] == '\r') line_start--; - msg_size->physical_size--; - } else { + else missing_cr_count--; - } } startpos = line_start; } io_buffer_skip(inbuf, startpos); msg_size->physical_size += startpos; + msg_size->virtual_size += startpos + missing_cr_count; - msg_size->virtual_size += - msg_size->physical_size + missing_cr_count; i_assert(msg_size->virtual_size >= msg_size->physical_size); return boundary; @@ -558,8 +549,14 @@ { MessageBoundary *boundary; - boundary = message_find_boundary(inbuf, boundaries, body_size, FALSE); - return boundary == NULL ? NULL : boundary->part; + if (boundaries == NULL) { + message_get_body_size(inbuf, body_size, -1); + return NULL; + } else { + boundary = message_find_boundary(inbuf, boundaries, + body_size, FALSE); + return boundary == NULL ? NULL : boundary->part; + } } /* skip data until next boundary is found. if it's end boundary, diff -r 2d8711a043a0 -r 21c8e080150d src/lib-mail/message-parser.h --- a/src/lib-mail/message-parser.h Thu Aug 22 01:45:34 2002 +0300 +++ b/src/lib-mail/message-parser.h Thu Aug 22 15:12:35 2002 +0300 @@ -21,7 +21,7 @@ MessagePart *next; MessagePart *children; - MessagePosition pos; + MessagePosition pos; /* absolute position from beginning of message */ MessageSize header_size; MessageSize body_size; diff -r 2d8711a043a0 -r 21c8e080150d src/lib-mail/message-size.c --- a/src/lib-mail/message-size.c Thu Aug 22 01:45:34 2002 +0300 +++ b/src/lib-mail/message-size.c Thu Aug 22 15:12:35 2002 +0300 @@ -38,7 +38,7 @@ if (i < size) { /* end of header */ - startpos = i + 1; + startpos = i+1; break; } diff -r 2d8711a043a0 -r 21c8e080150d src/lib/iobuffer.c --- a/src/lib/iobuffer.c Thu Aug 22 01:45:34 2002 +0300 +++ b/src/lib/iobuffer.c Thu Aug 22 15:12:35 2002 +0300 @@ -198,7 +198,7 @@ i_assert(size <= INT_MAX); if (size == 0) - return 1; + return 0; ret = write(fd, buf, size); if (ret < 0 && (errno == EINTR || errno == EAGAIN)) @@ -413,6 +413,9 @@ if (buf->closed) return -1; + if (size == 0) + return 1; + if (buf->pos == 0) { /* buffer is empty, try to send the data immediately */ ret = buf->file ? my_write(buf->fd, data, size) : @@ -428,9 +431,6 @@ size -= ret; } - if (size == 0) - return 1; - if (io_buffer_get_space(buf, size) == NULL) { if (buf->blocking) { /* if we don't have space, we block */ @@ -607,7 +607,7 @@ if (buf->pos != 0) { aligned_skip = buf->skip & ~mmap_pagemask; - if (buf->buffer != NULL) { + if (aligned_skip == 0 && buf->buffer != NULL) { /* didn't skip enough bytes */ return -2; } @@ -686,7 +686,6 @@ return -1; } - buf->offset += ret; buf->pos += ret; return ret; } @@ -700,9 +699,10 @@ { int ret; + buf->offset += size; + if (size <= buf->pos - buf->skip) { buf->skip += size; - buf->offset += size; return; } @@ -769,13 +769,14 @@ if (buf->skip == buf->cr_lookup_pos) buf->cr_lookup_pos++; buf->skip++; + buf->offset++; } buf->last_cr = FALSE; } char *io_buffer_next_line(IOBuffer *buf) { - // FIXME: update buf->offset + /* FIXME: buf->offset isn't updated right.. (skip_lf thing?) */ unsigned char *ret_buf; unsigned int i; @@ -794,6 +795,7 @@ ret_buf = buf->buffer + buf->skip; i++; + buf->offset += i - buf->skip; buf->skip = i; break; }