]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Don't die horribly when message with previously expunged UID is inserted
authorTimo Sirainen <tss@iki.fi>
Sun, 20 Jun 2004 13:03:02 +0000 (16:03 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 20 Jun 2004 13:03:02 +0000 (16:03 +0300)
into mbox.

--HG--
branch : HEAD

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-update.c
src/lib-storage/index/mbox/mbox-sync.c

index 779ec2b17d3c25ab1ccb570472a52afb2c39df2c..396e5c41e0d1a41a8212cb30d6869ded968a1e2b 100644 (file)
@@ -218,6 +218,7 @@ static int parse_x_uid(struct mbox_sync_mail_context *ctx,
        }
 
        ctx->hdr_pos[MBOX_HDR_X_UID] = str_len(ctx->header);
+       ctx->parsed_uid = value;
        parse_trailing_whitespace(ctx, hdr);
        return TRUE;
 }
@@ -355,12 +356,6 @@ void mbox_sync_parse_next_mail(struct istream *input,
                /* update uid-last field in X-IMAPbase */
                ctx->need_rewrite = TRUE;
        }
-       if (ctx->mail.uid == 0 && !rewriting) {
-               /* missing X-UID */
-               ctx->need_rewrite = TRUE;
-               ctx->mail.uid = sync_ctx->next_uid++;
-               sync_ctx->prev_msg_uid = ctx->mail.uid;
-       }
 
        ctx->body_offset = input->v_offset;
 }
index 1728efb1f5d673fe9f087bd29312b1ccfa129a3b..cbfdc14008d05a4092d665b7f300fadd43cf8f06 100644 (file)
@@ -59,6 +59,7 @@ struct mbox_sync_mail_context {
        uoff_t content_length;
 
        size_t hdr_pos[MBOX_HDR_COUNT];
+       uint32_t parsed_uid;
 
        unsigned int have_eoh:1;
        unsigned int need_rewrite:1;
index 89a569a204435349f78dccdb40e6798988e37f8d..519f534385649c2580e56d5376a3350f0665098d 100644 (file)
@@ -207,11 +207,31 @@ static void mbox_sync_update_xkeywords(struct mbox_sync_mail_context *ctx)
 {
 }
 
+static void mbox_sync_update_line(struct mbox_sync_mail_context *ctx,
+                                 size_t pos, string_t *new_line)
+{
+       const char *hdr, *p;
+
+       if (ctx->header_first_change > pos)
+               ctx->header_first_change = pos;
+
+       hdr = str_c(ctx->header) + pos;
+       p = strchr(hdr, '\n');
+
+       if (p == NULL) {
+               /* shouldn't really happen, but allow anyway.. */
+               ctx->header_last_change = (size_t)-1;
+               str_truncate(ctx->header, pos);
+               str_append_str(ctx->header, new_line);
+       } else {
+               mbox_sync_move_buffer(ctx, pos, str_len(new_line), p - hdr + 1);
+               buffer_copy(ctx->header, pos, new_line, 0, (size_t)-1);
+       }
+}
+
 static void mbox_sync_update_x_imap_base(struct mbox_sync_mail_context *ctx)
 {
        string_t *str;
-       const char *p, *hdr;
-       size_t pos;
 
        if (!ctx->sync_ctx->dest_first_mail ||
            ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1 ||
@@ -219,31 +239,31 @@ static void mbox_sync_update_x_imap_base(struct mbox_sync_mail_context *ctx)
            ctx->sync_ctx->update_base_uid_last < ctx->sync_ctx->base_uid_last)
                return;
 
-       pos = ctx->hdr_pos[MBOX_HDR_X_IMAPBASE];
-       if (ctx->header_first_change > pos)
-               ctx->header_first_change = pos;
-
        /* update uid-last field in X-IMAPbase */
        t_push();
+
        str = t_str_new(200);
        str_printfa(str, "%u %010u", ctx->sync_ctx->base_uid_validity,
                    ctx->sync_ctx->update_base_uid_last);
        //FIXME:keywords_append(ctx, all_keywords);
        str_append_c(str, '\n');
 
-       hdr = str_c(ctx->header) + pos;
-       p = strchr(hdr, '\n');
+        mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_IMAPBASE], str);
+       t_pop();
+}
 
-       if (p == NULL) {
-               /* shouldn't really happen, but allow anyway.. */
-               ctx->header_last_change = (size_t)-1;
-               str_truncate(ctx->header, pos);
-               str_append_str(ctx->header, str);
-       } else {
-               mbox_sync_move_buffer(ctx, pos, str_len(str), p - hdr + 1);
-               buffer_copy(ctx->header, pos, str, 0, (size_t)-1);
-       }
+static void mbox_sync_update_x_uid(struct mbox_sync_mail_context *ctx)
+{
+       string_t *str;
+
+       if (ctx->hdr_pos[MBOX_HDR_X_UID] == (size_t)-1 ||
+           ctx->mail.uid == ctx->parsed_uid)
+               return;
 
+       t_push();
+       str = t_str_new(64);
+       str_printfa(str, "%u", ctx->mail.uid);
+       mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_UID], str);
        t_pop();
 }
 
@@ -288,6 +308,7 @@ void mbox_sync_update_header(struct mbox_sync_mail_context *ctx,
        }
 
        mbox_sync_update_x_imap_base(ctx);
+       mbox_sync_update_x_uid(ctx);
        mbox_sync_add_missing_headers(ctx);
        ctx->updated = TRUE;
 }
@@ -321,5 +342,6 @@ void mbox_sync_update_header_from(struct mbox_sync_mail_context *ctx,
        ctx->mail.uid = mail->uid;
 
        mbox_sync_update_x_imap_base(ctx);
+       mbox_sync_update_x_uid(ctx);
        mbox_sync_add_missing_headers(ctx);
 }
index 7aa692bced5d7c6b56798e0ef1cf95d9f8afae59..47d499ad7b530fa4c383f04ebc81347cbba9f117 100644 (file)
@@ -256,6 +256,11 @@ static int mbox_sync_read_index_syncs(struct mbox_sync_context *sync_ctx,
        if (sync_ctx->ibox->mbox_readonly || sync_ctx->index_sync_ctx == NULL)
                return 0;
 
+       if (uid == 0) {
+               /* nothing for this or the future ones */
+               uid = (uint32_t)-1;
+       }
+
        mbox_sync_buffer_delete_old(sync_ctx->syncs, uid);
        while (uid >= sync_rec->uid1) {
                if (uid <= sync_rec->uid2 &&
@@ -315,11 +320,13 @@ mbox_sync_read_index_rec(struct mbox_sync_context *sync_ctx,
 {
         const struct mail_index_record *rec = NULL;
        uint32_t messages_count;
+       int ret = 0;
 
        messages_count = mail_index_view_get_message_count(sync_ctx->sync_view);
        while (sync_ctx->idx_seq < messages_count) {
-               if (mail_index_lookup(sync_ctx->sync_view,
-                                     ++sync_ctx->idx_seq, &rec) < 0) {
+               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;
                }
@@ -342,7 +349,7 @@ mbox_sync_read_index_rec(struct mbox_sync_context *sync_ctx,
        }
 
        *rec_r = rec;
-       return 0;
+       return ret;
 }
 
 static int mbox_sync_get_from_offset(struct mbox_sync_context *sync_ctx,
@@ -726,6 +733,24 @@ static int mbox_sync_loop(struct mbox_sync_context *sync_ctx,
                if (mbox_sync_read_index_syncs(sync_ctx, uid, &expunged) < 0)
                        return -1;
 
+               if (uid != 0) {
+                       ret = mbox_sync_read_index_rec(sync_ctx, uid, &rec);
+                       if (ret < 0)
+                               return -1;
+                       if (ret == 0 && uid < sync_ctx->hdr->next_uid) {
+                               /* this UID was already in index and it was
+                                  expunged */
+                               uid = 0;
+                       }
+               }
+               if (uid == 0) {
+                       /* missing/broken X-UID */
+                       mail_ctx->need_rewrite = TRUE;
+                       mail_ctx->mail.uid = sync_ctx->next_uid++;
+                       sync_ctx->prev_msg_uid = mail_ctx->mail.uid;
+                       rec = NULL;
+               }
+
                if (!expunged) {
                        ret = mbox_sync_handle_header(mail_ctx);
                        sync_ctx->dest_first_mail = FALSE;
@@ -738,9 +763,6 @@ static int mbox_sync_loop(struct mbox_sync_context *sync_ctx,
                        return ret;
                }
 
-               if (mbox_sync_read_index_rec(sync_ctx, uid, &rec) < 0)
-                       return -1;
-
                if (!expunged) {
                        if (mbox_sync_update_index(sync_ctx, &mail_ctx->mail,
                                                   rec) < 0)