Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2242:5e2518377c0a HEAD
Save MD5 sums of some headers for readonly mboxes and use them for syncing
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 24 Jun 2004 16:47:35 +0300 |
parents | c9a27c0875e2 |
children | 6850ff275fa5 |
files | src/lib-storage/index/index-storage.h src/lib-storage/index/mbox/mbox-sync-parse.c src/lib-storage/index/mbox/mbox-sync-private.h src/lib-storage/index/mbox/mbox-sync.c |
diffstat | 4 files changed, 136 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/index-storage.h Thu Jun 24 16:43:56 2004 +0300 +++ b/src/lib-storage/index/index-storage.h Thu Jun 24 16:47:35 2004 +0300 @@ -88,7 +88,7 @@ unsigned int mbox_lock_id, mbox_mail_lock_id; int mbox_readonly; - uint32_t mbox_extra_idx; + uint32_t mbox_extra_idx, md5hdr_extra_idx; /* maildir sync: */ struct maildir_uidlist *uidlist;
--- a/src/lib-storage/index/mbox/mbox-sync-parse.c Thu Jun 24 16:43:56 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync-parse.c Thu Jun 24 16:47:35 2004 +0300 @@ -1,5 +1,8 @@ /* Copyright (C) 2004 Timo Sirainen */ +/* MD5 header summing logic was pretty much copy&pasted from popa3d by + Solar Designer */ + #include "lib.h" #include "buffer.h" #include "istream.h" @@ -266,9 +269,64 @@ return TRUE; } +static int parse_date(struct mbox_sync_mail_context *ctx, + struct message_header_line *hdr) +{ + if (!ctx->seen_received_hdr) { + /* Received-header contains date too, and more trusted one */ + md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len); + } + return TRUE; +} + +static int parse_delivered_to(struct mbox_sync_mail_context *ctx, + struct message_header_line *hdr) +{ + md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len); + return TRUE; +} + +static int parse_message_id(struct mbox_sync_mail_context *ctx, + struct message_header_line *hdr) +{ + if (!ctx->seen_received_hdr) { + /* Received-header contains unique ID too, + and more trusted one */ + md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len); + } + return TRUE; +} + +static int parse_received(struct mbox_sync_mail_context *ctx, + struct message_header_line *hdr) +{ + if (!ctx->seen_received_hdr) { + /* get only the first received-header */ + md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len); + if (!hdr->continues) + ctx->seen_received_hdr = TRUE; + } + return TRUE; +} + +static int parse_x_delivery_id(struct mbox_sync_mail_context *ctx, + struct message_header_line *hdr) +{ + /* Let the local delivery agent help generate unique ID's but don't + blindly trust this header alone as it could just as easily come from + the remote. */ + md5_update(&ctx->hdr_md5_ctx, hdr->value, hdr->value_len); + return TRUE; +} + static struct header_func header_funcs[] = { { "Content-Length", parse_content_length }, + { "Date", parse_date }, + { "Delivered-To", parse_delivered_to }, + { "Message-ID", parse_message_id }, + { "Received", parse_received }, { "Status", parse_status }, + { "X-Delivery-ID", parse_x_delivery_id }, { "X-IMAP", parse_x_imap }, { "X-IMAPbase", parse_x_imap_base }, { "X-Keywords", parse_x_keywords }, @@ -310,6 +368,8 @@ ctx->content_length = (uoff_t)-1; str_truncate(ctx->header, 0); + md5_init(&ctx->hdr_md5_ctx); + line_start_pos = 0; hdr_ctx = message_parse_header_init(input, NULL, FALSE); while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { @@ -361,6 +421,8 @@ } message_parse_header_deinit(hdr_ctx); + md5_final(&ctx->hdr_md5_ctx, ctx->hdr_md5_sum); + if ((ctx->seq == 1 && sync_ctx->base_uid_validity == 0) || (ctx->seq > 1 && sync_ctx->dest_first_mail)) { /* missing X-IMAPbase */
--- a/src/lib-storage/index/mbox/mbox-sync-private.h Thu Jun 24 16:43:56 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync-private.h Thu Jun 24 16:47:35 2004 +0300 @@ -1,6 +1,7 @@ #ifndef __MBOX_SYNC_PRIVATE_H #define __MBOX_SYNC_PRIVATE_H +#include "md5.h" #include "mail-index.h" struct mbox_flag_type { @@ -56,6 +57,9 @@ size_t header_first_change, header_last_change; string_t *header, *uidl; + struct md5_context hdr_md5_ctx; + unsigned char hdr_md5_sum[16]; + uoff_t content_length; size_t hdr_pos[MBOX_HDR_COUNT]; @@ -67,6 +71,7 @@ unsigned int seen_imapbase:1; unsigned int pseudo:1; unsigned int updated:1; + unsigned int seen_received_hdr:1; }; struct mbox_sync_context {
--- a/src/lib-storage/index/mbox/mbox-sync.c Thu Jun 24 16:43:56 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync.c Thu Jun 24 16:47:35 2004 +0300 @@ -365,6 +365,45 @@ return ret; } +static int mbox_sync_find_index_md5(struct mbox_sync_context *sync_ctx, + unsigned char hdr_md5_sum[], + const struct mail_index_record **rec_r) +{ + const struct mail_index_record *rec = NULL; + uint32_t messages_count; + const void *data; + int ret; + + messages_count = mail_index_view_get_message_count(sync_ctx->sync_view); + while (sync_ctx->idx_seq <= messages_count) { + ret = mail_index_lookup(sync_ctx->sync_view, + sync_ctx->idx_seq, &rec); + if (ret < 0) { + mail_storage_set_index_error(sync_ctx->ibox); + return -1; + } + + if (mail_index_lookup_extra(sync_ctx->sync_view, + sync_ctx->idx_seq, + sync_ctx->ibox->md5hdr_extra_idx, + &data) < 0) { + mail_storage_set_index_error(sync_ctx->ibox); + return -1; + } + + if (memcmp(data, hdr_md5_sum, 16) == 0) + break; + + /* externally expunged message, remove from index */ + mail_index_expunge(sync_ctx->t, sync_ctx->idx_seq); + sync_ctx->idx_seq++; + rec = NULL; + } + + *rec_r = rec; + return 0; +} + static int mbox_sync_get_from_offset(struct mbox_sync_context *sync_ctx, uint32_t seq, uint64_t *offset_r) { @@ -419,6 +458,14 @@ mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq, MODIFY_REPLACE, mbox_flags, mail->keywords); + + if (sync_ctx->ibox->md5hdr_extra_idx != 0) { + mail_index_update_extra_rec(sync_ctx->t, + sync_ctx->idx_seq, + sync_ctx->ibox->md5hdr_extra_idx, + mail_ctx->hdr_md5_sum); + } + if (str_len(mail_ctx->uidl) > 0) { /*FIXME:mail_cache_add(sync_ctx->cache_trans, MAIL_CACHE_UID_STRING, @@ -762,13 +809,33 @@ return -1; rec = NULL; - if (uid != 0 && !mail_ctx->pseudo) { + if (uid != 0 && !mail_ctx->pseudo && + sync_ctx->ibox->md5hdr_extra_idx == 0) { ret = mbox_sync_read_index_rec(sync_ctx, uid, &rec); if (ret < 0) return -1; if (ret == 0) uid = 0; } + + if (uid == 0 && sync_ctx->ibox->mbox_readonly) { + /* Use MD5 sums */ + if (sync_ctx->ibox->md5hdr_extra_idx == 0) { + sync_ctx->ibox->md5hdr_extra_idx = + mail_index_register_record_extra( + sync_ctx->ibox->index, + "header-md5", 16); + } + + if (mbox_sync_find_index_md5(sync_ctx, + mail_ctx->hdr_md5_sum, + &rec) < 0) + return -1; + + if (rec != NULL) + uid = rec->uid; + } + if (uid == 0) { /* missing/broken X-UID. all the rest of the mails need new UIDs. */