/* 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"
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 },
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) {
}
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 */
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)
{
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,
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. */