]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixes for expunging first message
authorTimo Sirainen <tss@iki.fi>
Sun, 13 Jun 2004 20:39:17 +0000 (23:39 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 13 Jun 2004 20:39:17 +0000 (23:39 +0300)
--HG--
branch : HEAD

src/lib-storage/index/mbox/mbox-sync-rewrite.c
src/lib-storage/index/mbox/mbox-sync.c

index 67de7a2c10261de5671b643897dc891e7aa000bc..261e7a9ceaa99c98cca09fda23fd4e51dbf1aaac 100644 (file)
@@ -242,8 +242,7 @@ static int mbox_sync_read_and_move(struct mbox_sync_context *sync_ctx,
                        str_append_c(mail_ctx.header, '\n');
        }
 
-       /* breaks with leftover space:
-          i_assert(mail_ctx.mail.space == mails[idx].space);*/
+       i_assert(mail_ctx.mail.space == mails[idx].space);
         sync_ctx->prev_msg_uid = old_prev_msg_uid;
 
        /* we're moving next message - update it's from_offset */
@@ -282,11 +281,49 @@ static int mbox_sync_read_and_move(struct mbox_sync_context *sync_ctx,
        return 0;
 }
 
+static int mbox_sync_fill_leftover(struct mbox_sync_context *sync_ctx,
+                                  struct mbox_sync_mail *mails,
+                                  uint32_t seq, uint32_t idx,
+                                  uoff_t start_offset, uoff_t end_offset)
+{
+       struct mbox_sync_mail_context mail_ctx;
+       uint32_t old_prev_msg_uid;
+
+       i_stream_seek(sync_ctx->file_input, mails[idx].offset);
+
+       memset(&mail_ctx, 0, sizeof(mail_ctx));
+       mail_ctx.sync_ctx = sync_ctx;
+       mail_ctx.seq = seq;
+       mail_ctx.header = sync_ctx->header;
+
+       mail_ctx.mail.offset = mails[idx].offset;
+       mail_ctx.mail.body_size = mails[idx].body_size;
+
+       /* mbox_sync_parse_next_mail() checks that UIDs are growing,
+          so we have to fool it. */
+        old_prev_msg_uid = sync_ctx->prev_msg_uid;
+        sync_ctx->prev_msg_uid = mails[idx].uid-1;
+
+       mbox_sync_parse_next_mail(sync_ctx->file_input, &mail_ctx, TRUE);
+       mbox_sync_update_header_from(&mail_ctx, &mails[idx]);
+
+        sync_ctx->prev_msg_uid = old_prev_msg_uid;
+
+       mbox_sync_headers_add_space(&mail_ctx, end_offset - start_offset);
+
+       if (pwrite_full(sync_ctx->fd, str_data(mail_ctx.header),
+                       str_len(mail_ctx.header), start_offset) < 0) {
+               // FIXME: error handling
+               return -1;
+       }
+
+       mails[idx].offset = start_offset;
+       return 0;
+}
+
 int mbox_sync_rewrite(struct mbox_sync_context *sync_ctx, buffer_t *mails_buf,
                      uint32_t first_seq, uint32_t last_seq, off_t extra_space)
 {
-       /* FIXME: with mails[0] = expunged and first_seq=1, we leave the
-          \n header! */
        struct mbox_sync_mail *mails;
        size_t size;
        uoff_t offset, start_offset, end_offset, dest_offset;
@@ -374,6 +411,9 @@ int mbox_sync_rewrite(struct mbox_sync_context *sync_ctx, buffer_t *mails_buf,
                        mbox_sync_fix_from_offset(sync_ctx, 1,
                                                  (off_t)end_offset - offset);
                        idx++;
+
+                       start_offset += offset - end_offset;
+                       end_offset = offset;
                } else {
                        /* "\nFrom ..\n" start_offset .. end_offset "hdr.." */
                }
@@ -381,11 +421,9 @@ int mbox_sync_rewrite(struct mbox_sync_context *sync_ctx, buffer_t *mails_buf,
                /* now parse it again and give it more space */
                mails[idx].space = extra_per_mail;
                mails[idx+1].space = 0; /* from_offset doesn't move.. */
-               if (mbox_sync_read_and_move(sync_ctx, mails,
+               if (mbox_sync_fill_leftover(sync_ctx, mails,
                                            first_seq + idx, idx,
-                                           end_offset - start_offset +
-                                           mails[idx].space,
-                                           &end_offset) < 0)
+                                           start_offset, end_offset) < 0)
                        ret = -1;
        }
 
index 8d12133b17df05c312a8939a6d2cf38abf844e7f..98a2853bb9c2b957f3720a1fbd548a6c65dbeb8e 100644 (file)
@@ -118,6 +118,12 @@ mbox_sync_next_mail(struct mbox_sync_context *sync_ctx,
        mail_ctx->mail.offset =
                istream_raw_mbox_get_header_offset(sync_ctx->input);
 
+       if (seq > 1 && sync_ctx->first_uid == mail_ctx->mail.uid) {
+               /* First message was expunged and this is the next one.
+                  Skip \n header */
+               mail_ctx->from_offset++;
+       }
+
        mbox_sync_parse_next_mail(sync_ctx->input, mail_ctx, FALSE);
        i_assert(sync_ctx->input->v_offset != mail_ctx->from_offset);
 
@@ -186,14 +192,6 @@ mbox_write_from_line(struct mbox_sync_mail_context *ctx, off_t move_diff)
        if (move_diff == 0)
                return 0;
 
-       if (ctx->from_offset + move_diff == 0) {
-               /* FIXME: kludge: we're writing the first header,
-                  change the \n prefix into space suffix */
-               buffer_copy(str, 0, str, 1, (size_t)-1);
-               str_truncate(str, str_len(str)-2);
-               str_append(str, " \n");
-       }
-
        if (pwrite_full(ctx->sync_ctx->fd, str_data(str), str_len(str),
                        ctx->from_offset + move_diff) < 0) {
                // FIXME: error handling
@@ -308,6 +306,9 @@ static int mbox_sync_do(struct index_mailbox *ibox,
                                        mail_ctx.mail.body_size;
                                mail_ctx.mail.body_size = 0;
 
+                               if (seq == 1)
+                                       mail_ctx.mail.space++;
+
                                sync_ctx.expunged_space += mail_ctx.mail.space;
                        } else {
                                move_diff = need_space_seq != 0 ? 0 :