Mercurial > dovecot > original-hg > dovecot-1.2
changeset 25:55e09f36d23d HEAD
after a few times of trying to access uncached fields, they're cached the
next time mailbox is opened. also some mbox fixes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 25 Aug 2002 23:50:09 +0300 |
parents | e8de6f485c65 |
children | 91e73c5bb8f3 |
files | src/lib-index/Makefile.am src/lib-index/mail-index-update-cache.c src/lib-index/mail-index-update.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/maildir/maildir-update.c src/lib-index/mbox/mbox-append.c src/lib-index/mbox/mbox-from.c src/lib-index/mbox/mbox-index.c src/lib-storage/index/index-fetch.c |
diffstat | 10 files changed, 246 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/Makefile.am Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-index/Makefile.am Sun Aug 25 23:50:09 2002 +0300 @@ -13,6 +13,7 @@ mail-index-fsck.c \ mail-index-data.c \ mail-index-update.c \ + mail-index-update-cache.c \ mail-index-util.c \ mail-lockdir.c \ mail-messageset.c \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-index/mail-index-update-cache.c Sun Aug 25 23:50:09 2002 +0300 @@ -0,0 +1,45 @@ +/* Copyright (C) 2002 Timo Sirainen */ + +#include "lib.h" +#include "mail-index.h" + +static int cache_record(MailIndex *index, MailIndexRecord *rec, + MailField cache_fields) +{ + MailIndexUpdate *update; + IOBuffer *inbuf; + + inbuf = index->open_mail(index, rec); + if (inbuf == NULL) + return FALSE; + + cache_fields &= ~rec->cached_fields; + + update = index->update_begin(index, rec); + mail_index_update_headers(update, inbuf, cache_fields, NULL, NULL); + return index->update_end(update); +} + +int mail_index_update_cache(MailIndex *index) +{ + MailIndexRecord *rec; + MailField cache_fields; + + if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) + return FALSE; + + cache_fields = index->get_header(index)->cache_fields; + + rec = index->lookup(index, 1); + while (rec != NULL) { + if ((rec->cached_fields & cache_fields) != cache_fields) { + if (!cache_record(index, rec, cache_fields)) + return FALSE; + } + + rec = index->next(index, rec); + } + + index->header->flags &= ~MAIL_INDEX_FLAG_CACHE_FIELDS; + return TRUE; +}
--- a/src/lib-index/mail-index-update.c Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-index/mail-index-update.c Sun Aug 25 23:50:09 2002 +0300 @@ -232,8 +232,6 @@ static MailField mail_header_get_field(const char *str, unsigned int len) { - if (len == 10 && strncasecmp(str, "Message-ID", 10) == 0) - return FIELD_TYPE_MESSAGEID; if (len == 7 && strncasecmp(str, "Subject", 7) == 0) return FIELD_TYPE_SUBJECT; if (len == 4 && strncasecmp(str, "From", 4) == 0) @@ -329,10 +327,10 @@ } void mail_index_update_headers(MailIndexUpdate *update, IOBuffer *inbuf, + MailField cache_fields, MessageHeaderFunc header_func, void *context) { HeaderUpdateContext ctx; - MailField cache_fields; MessagePart *part; MessageSize hdr_size, body_size; Pool pool; @@ -344,7 +342,9 @@ ctx.header_func = header_func; ctx.context = context; - cache_fields = update->index->header->cache_fields; + if (cache_fields == 0) + cache_fields = update->index->header->cache_fields; + if ((cache_fields & (FIELD_TYPE_BODY|FIELD_TYPE_BODYSTRUCTURE)) != 0) { /* for body / bodystructure, we need need to fully parse the message */ @@ -360,6 +360,7 @@ if (cache_fields & FIELD_TYPE_BODY) { t_push(); + io_buffer_seek(inbuf, 0); value = imap_part_get_bodystructure(pool, &part, inbuf, FALSE); update->index->update_field(update, FIELD_TYPE_BODY, @@ -369,6 +370,7 @@ if (cache_fields & FIELD_TYPE_BODYSTRUCTURE) { t_push(); + io_buffer_seek(inbuf, 0); value = imap_part_get_bodystructure(pool, &part, inbuf, TRUE); update->index->update_field(update,
--- a/src/lib-index/mail-index.c Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-index/mail-index.c Sun Aug 25 23:50:09 2002 +0300 @@ -506,7 +506,7 @@ if (hdr.flags & MAIL_INDEX_FLAG_REBUILD) { /* index is corrupted, rebuild */ if (!mail_index_rebuild_all(index)) - return FALSE; + break; } if (hdr.flags & MAIL_INDEX_FLAG_FSCK) { @@ -515,6 +515,12 @@ break; } + if (hdr.flags & MAIL_INDEX_FLAG_CACHE_FIELDS) { + /* need to update cached fields */ + if (!mail_index_update_cache(index)) + break; + } + if (!index->sync(index)) break; if (!mail_index_open_init(index, update_recent, &hdr)) @@ -525,8 +531,6 @@ index->updating = FALSE; - /* last_recent_uid update, hash or modifylog creation - may create locks */ if (!index->set_lock(index, MAIL_LOCK_UNLOCK)) failed = TRUE; @@ -894,26 +898,34 @@ /* first check if the field even could be in the file */ if ((rec->cached_fields & field) != field) { - /* no, but make sure the future records will have it. - we don't immediately mark the index to cache this field - for old messages as some clients never ask the info again */ - index->set_cache_fields |= field; + if ((index->header->cache_fields & field) == 0) { + /* no, but make sure the future records will have it. + we don't immediately mark the index to cache this + field for old messages as some clients never ask + the info again */ + index->set_cache_fields |= field; + } else { + /* this is at least the second time it's being asked, + make sure it'll be cached soon. */ + index->set_flags |= MAIL_INDEX_FLAG_CACHE_FIELDS; + } + return NULL; } datarec = mail_index_data_lookup(index->data, rec, field); - if (datarec != NULL) { - if (mail_index_data_record_verify(index->data, datarec)) - return datarec->data; - - /* index is corrupted, it will be rebuilt */ - } else { - /* field doesn't exist, make sure it willl be added later - when there's time */ - index->set_flags |= MAIL_INDEX_FLAG_CACHE_FIELDS; + if (datarec == NULL) { + /* corrupted, the field should have been there */ + index->set_flags |= MAIL_INDEX_FLAG_REBUILD; + return NULL; } - return NULL; + if (!mail_index_data_record_verify(index->data, datarec)) { + /* index is corrupted, it will be rebuilt */ + return NULL; + } + + return datarec->data; } unsigned int mail_index_get_sequence(MailIndex *index, MailIndexRecord *rec)
--- a/src/lib-index/mail-index.h Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-index/mail-index.h Sun Aug 25 23:50:09 2002 +0300 @@ -37,21 +37,20 @@ FIELD_TYPE_ENVELOPE = 0x0002, FIELD_TYPE_BODY = 0x0004, FIELD_TYPE_BODYSTRUCTURE = 0x0008, - FIELD_TYPE_MESSAGEID = 0x0010, - FIELD_TYPE_FROM = 0x0020, - FIELD_TYPE_TO = 0x0040, - FIELD_TYPE_CC = 0x0080, - FIELD_TYPE_BCC = 0x0100, - FIELD_TYPE_SUBJECT = 0x0200, - FIELD_TYPE_MD5 = 0x0400, + FIELD_TYPE_FROM = 0x0010, + FIELD_TYPE_TO = 0x0020, + FIELD_TYPE_CC = 0x0040, + FIELD_TYPE_BCC = 0x0080, + FIELD_TYPE_SUBJECT = 0x0100, + FIELD_TYPE_MD5 = 0x0200, - FIELD_TYPE_LAST = 0x0800, - FIELD_TYPE_MAX_BITS = 11 + FIELD_TYPE_LAST = 0x0400, + FIELD_TYPE_MAX_BITS = 10 } MailField; #define IS_HEADER_FIELD(field) \ - (((field) & (FIELD_TYPE_MESSAGEID | FIELD_TYPE_FROM | FIELD_TYPE_TO | \ - FIELD_TYPE_CC | FIELD_TYPE_BCC | FIELD_TYPE_SUBJECT)) != 0) + (((field) & (FIELD_TYPE_FROM | FIELD_TYPE_TO | FIELD_TYPE_CC | \ + FIELD_TYPE_BCC | FIELD_TYPE_SUBJECT)) != 0) typedef enum { MAIL_LOCK_UNLOCK = 0, @@ -345,7 +344,9 @@ int mail_index_rebuild_all(MailIndex *index); int mail_index_sync_file(MailIndex *index); void mail_index_update_headers(MailIndexUpdate *update, IOBuffer *inbuf, + MailField cache_fields, MessageHeaderFunc header_func, void *context); +int mail_index_update_cache(MailIndex *index); /* Max. mmap()ed size for a message */ #define MAIL_MMAP_BLOCK_SIZE (1024*256)
--- a/src/lib-index/maildir/maildir-update.c Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-index/maildir/maildir-update.c Sun Aug 25 23:50:09 2002 +0300 @@ -12,6 +12,6 @@ inbuf = io_buffer_create_mmap(fd, default_pool, MAIL_MMAP_BLOCK_SIZE, 0); - mail_index_update_headers(update, inbuf, NULL, NULL); + mail_index_update_headers(update, inbuf, 0, NULL, NULL); return TRUE; }
--- a/src/lib-index/mbox/mbox-append.c Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-index/mbox/mbox-append.c Sun Aug 25 23:50:09 2002 +0300 @@ -142,7 +142,7 @@ inbuf->size = stop_offset; io_buffer_seek(inbuf, start_offset); - mail_index_update_headers(update, inbuf, mbox_header_func, &ctx); + mail_index_update_headers(update, inbuf, 0, mbox_header_func, &ctx); inbuf->size = old_size; io_buffer_seek(inbuf, stop_offset);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-index/mbox/mbox-from.c Sun Aug 25 23:50:09 2002 +0300 @@ -0,0 +1,145 @@ +/* Copyright (C) 2002 Timo Sirainen */ + +#include "lib.h" + +#include <time.h> +#include <ctype.h> + +static const char *weekdays[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +static const char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +time_t mbox_from_parse_date(const char *msg, unsigned int size) +{ + const char *msg_end; + struct tm tm; + int i; + + i_assert(size > 5); + + /* From <sender> <date> <moreinfo> */ + if (strncmp(msg, "From ", 5) != 0) + return 0; + + msg_end = msg + size; + + /* skip sender */ + msg += 5; + while (*msg != ' ' && msg < msg_end) msg++; + while (*msg == ' ' && msg < msg_end) msg++; + + /* next 24 chars are the date in asctime() format, + eg. "Thu Nov 29 22:33:52 2001" */ + if (msg+24 > msg_end) + return 0; + + memset(&tm, 0, sizeof(tm)); + + /* skip weekday */ + msg += 4; + + /* month */ + for (i = 0; i < 12; i++) { + if (strncasecmp(months[i], msg, 3) == 0) { + tm.tm_mon = i; + break; + } + } + + if (i == 12 || msg[3] != ' ') + return 0; + msg += 4; + + /* day */ + if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ' ') + return 0; + tm.tm_mday = (msg[0]-'0') * 10 + (msg[1]-'0'); + msg += 3; + + /* hour */ + if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ':') + return 0; + tm.tm_hour = (msg[0]-'0') * 10 + (msg[1]-'0'); + msg += 3; + + /* minute */ + if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ':') + return 0; + tm.tm_min = (msg[0]-'0') * 10 + (msg[1]-'0'); + msg += 3; + + /* second */ + if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ' ') + return 0; + tm.tm_sec = (msg[0]-'0') * 10 + (msg[1]-'0'); + msg += 3; + + /* year */ + if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || + !i_isdigit(msg[2]) || !i_isdigit(msg[3])) + return 0; + tm.tm_year = (msg[0]-'0') * 1000 + (msg[1]-'0') * 100 + + (msg[2]-'0') * 10 + (msg[3]-'0') - 1900; + + tm.tm_isdst = -1; + return mktime(&tm); +} + +const char *mbox_from_create(const char *sender, time_t time) +{ + struct tm *tm; + char *ret, *p; + int len, year; + + len = strlen(sender); + ret = t_malloc(len + 24 + 1); + memcpy(ret, sender, len); + + /* we could use simply asctime(), but i18n etc. may break it. + Example: "Thu Nov 29 22:33:52 2001" */ + tm = localtime(&time); + p = ret + len; + + /* week day */ + strcpy(p, weekdays[tm->tm_wday]); p += 3; + *p++ = ' '; + + /* month */ + strcpy(p, months[tm->tm_mon]); p += 3; + *p++ = ' '; + + /* day */ + *p++ = (tm->tm_mday / 10) + '0'; + *p++ = (tm->tm_mday % 10) + '0'; + *p++ = ' '; + + /* hour */ + *p++ = (tm->tm_hour / 10) + '0'; + *p++ = (tm->tm_hour % 10) + '0'; + *p++ = ':'; + + /* minute */ + *p++ = (tm->tm_min / 10) + '0'; + *p++ = (tm->tm_min % 10) + '0'; + *p++ = ':'; + + /* second */ + *p++ = (tm->tm_sec / 10) + '0'; + *p++ = (tm->tm_sec % 10) + '0'; + *p++ = ' '; + + /* year */ + year = tm->tm_year + 1900; + *p++ = (year / 1000) + '0'; + *p++ = ((year / 100) % 10) + '0'; + *p++ = ((year / 10) % 10) + '0'; + *p++ = (year % 10) + '0'; + + *p++ = '\0'; + return ret; +}
--- a/src/lib-index/mbox/mbox-index.c Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-index/mbox/mbox-index.c Sun Aug 25 23:50:09 2002 +0300 @@ -27,11 +27,14 @@ case 'F': flags |= MAIL_FLAGGED; break; + case 'D': + flags |= MAIL_DELETED; + break; case 'R': flags |= MAIL_SEEN; break; - case 'D': - flags |= MAIL_DELETED; + case 'T': + flags |= MAIL_DRAFT; break; } }
--- a/src/lib-storage/index/index-fetch.c Sun Aug 25 20:51:10 2002 +0300 +++ b/src/lib-storage/index/index-fetch.c Sun Aug 25 23:50:09 2002 +0300 @@ -199,11 +199,8 @@ IOBuffer *inbuf; inbuf = ctx->index->open_mail(ctx->index, rec); - if (inbuf == NULL) { - i_error("Couldn't open message UID %u (index %s)", - rec->uid, ctx->index->filepath); + if (inbuf == NULL) return FALSE; - } if (MSG_HAS_VALID_CRLF_DATA(rec)) { imap_msgcache_message(ctx->cache, rec->uid,