[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-lock.c, 1.6, 1.7 mbox-mail.c, 1.6, 1.7 mbox-save.c, 1.49, 1.50 mbox-storage.h, 1.19, 1.20 mbox-sync-parse.c, 1.12, 1.13 mbox-sync-private.h, 1.16, 1.17 mbox-sync-rewrite.c, 1.19, 1.20 mbox-sync-update.c, 1.15, 1.16 mbox-sync.c, 1.39, 1.40 mbox-transaction.c, 1.2, 1.3

cras at procontrol.fi cras at procontrol.fi
Sun Jun 20 06:25:37 EEST 2004


Update of /home/cvs/dovecot/src/lib-storage/index/mbox
In directory talvi:/tmp/cvs-serv336/src/lib-storage/index/mbox

Modified Files:
	mbox-lock.c mbox-mail.c mbox-save.c mbox-storage.h 
	mbox-sync-parse.c mbox-sync-private.h mbox-sync-rewrite.c 
	mbox-sync-update.c mbox-sync.c mbox-transaction.c 
Log Message:
mailbox_save() and mailbox_copy() functions can now return the saved mail so
it can be immediately queried. Implemented UIDPLUS extension using it.
Maildir implementation missing, so it crashes with it for now.. APPEND with
mbox now doesn't require resyncing the mailbox since it updates indexes
directly.



Index: mbox-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-lock.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mbox-lock.c	15 Jun 2004 02:05:55 -0000	1.6
+++ mbox-lock.c	20 Jun 2004 03:25:34 -0000	1.7
@@ -331,6 +331,7 @@
 
 	if (ibox->mbox_lock_type == lock_type) {
 		ibox->mbox_locks++;
+		*lock_id_r = ibox->mbox_lock_id;
 		return 1;
 	}
 

Index: mbox-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-mail.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mbox-mail.c	16 Jun 2004 05:38:23 -0000	1.6
+++ mbox-mail.c	20 Jun 2004 03:25:34 -0000	1.7
@@ -19,7 +19,7 @@
 	uint64_t offset;
 
 	if (ibox->mbox_lock_type == F_UNLCK) {
-		if (mbox_sync(ibox, FALSE, TRUE) < 0)
+		if (mbox_sync(ibox, FALSE, FALSE, TRUE) < 0)
 			return -1;
 
 		i_assert(ibox->mbox_lock_type != F_UNLCK);
@@ -74,12 +74,15 @@
 		return (time_t)-1;
 	data->received_date =
 		istream_raw_mbox_get_received_time(mail->ibox->mbox_stream);
-
-	if (data->received_date != (time_t)-1) {
-		index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
-				     &data->received_date,
-				     sizeof(data->received_date));
+	if (data->received_date == (time_t)-1) {
+		/* it's broken and conflicts with our "not found"
+		   return value. change it. */
+		data->received_date = 0;
 	}
+
+	index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
+			     &data->received_date,
+			     sizeof(data->received_date));
 	return data->received_date;
 }
 

Index: mbox-save.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-save.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -d -r1.49 -r1.50
--- mbox-save.c	15 Jun 2004 02:05:55 -0000	1.49
+++ mbox-save.c	20 Jun 2004 03:25:34 -0000	1.50
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "hostpid.h"
 #include "ostream.h"
 #include "str.h"
@@ -9,8 +10,10 @@
 #include "mbox-file.h"
 #include "mbox-from.h"
 #include "mbox-lock.h"
+#include "mbox-sync-private.h"
 #include "mail-save.h"
 
+#include <stddef.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -19,12 +22,20 @@
 
 struct mbox_save_context {
 	struct index_mailbox *ibox;
+	struct mail_index_transaction *trans;
 	uoff_t append_offset;
 
+	string_t *headers;
+	size_t space_end_idx;
+	uint32_t next_uid;
+
 	struct ostream *output;
-	uoff_t sync_offset, content_length_offset, eoh_offset;
+	uoff_t extra_hdr_offset, eoh_offset;
+
+	struct index_mail mail;
 
 	const struct mail_full_flags *flags;
+	unsigned int synced:1;
 };
 
 static char my_hostdomain[256] = "";
@@ -111,89 +122,50 @@
 	return 0;
 }
 
-static const char *get_system_flags(enum mail_flags flags)
+static int mbox_write_content_length(struct mbox_save_context *ctx)
 {
-	string_t *str;
-
-	if (flags == 0)
-		return "";
+	uoff_t end_offset;
+	const char *str;
+	size_t len;
+	int ret = 0;
 
-	str = t_str_new(32);
-	if (flags & MAIL_SEEN)
-		str_append(str, "Status: R\n");
+	end_offset = ctx->output->offset;
 
-	if (flags & (MAIL_ANSWERED|MAIL_DRAFT|MAIL_FLAGGED|MAIL_DELETED)) {
-		str_append(str, "X-Status: ");
+	/* write Content-Length headers */
+	t_push();
+	str = t_strdup_printf("\nContent-Length: %s",
+			      dec2str(end_offset - (ctx->eoh_offset + 1)));
+	len = strlen(str);
 
-		if ((flags & MAIL_ANSWERED) != 0)
-			str_append_c(str, 'A');
-		if ((flags & MAIL_DELETED) != 0)
-			str_append_c(str, 'D');
-		if ((flags & MAIL_FLAGGED) != 0)
-			str_append_c(str, 'F');
-		if ((flags & MAIL_DRAFT) != 0)
-			str_append_c(str, 'T');
-		str_append_c(str, '\n');
+	if (o_stream_seek(ctx->output, ctx->extra_hdr_offset +
+			  ctx->space_end_idx - len) < 0) {
+		mbox_set_syscall_error(ctx->ibox, "o_stream_seek()");
+		ret = -1;
+	} else if (o_stream_send(ctx->output, str, len) < 0) {
+		write_error(ctx);
+		ret = -1;
+	} else {
+		if (o_stream_seek(ctx->output, end_offset) < 0) {
+			mbox_set_syscall_error(ctx->ibox, "o_stream_seek()");
+			ret = -1;
+		}
 	}
 
-	return str_c(str);
-}
-
-static const char *get_keywords(const struct mail_full_flags *flags)
-{
-	string_t *str;
-	unsigned int i;
-
-	if (flags->keywords_count == 0)
-		return "";
-
-	str = t_str_new(256);
-	for (i = 0; i < flags->keywords_count; i++) {
-		if (str_len(str) > 0)
-			str_append_c(str, ' ');
-		str_append(str, flags->keywords[i]);
-	}
-	return str_c(str);
+	t_pop();
+	return ret;
 }
 
 static int save_header_callback(const char *name, write_func_t *write_func,
 				void *context)
 {
-	static const char *content_length = "Content-Length: ";
 	struct mbox_save_context *ctx = context;
-	const char *str;
-	char *buf;
-	size_t space;
 
 	if (name == NULL) {
-		/* write system flags */
-		str = get_system_flags(ctx->flags->flags);
-		if (write_func(ctx->output, str, strlen(str)) < 0)
-			return -1;
-
-		/* write beginning of content-length header */
-		if (write_func(ctx->output, content_length,
-			       strlen(content_length)) < 0) {
-			write_error(ctx);
-			return -1;
-		}
-		ctx->content_length_offset = ctx->output->offset;
-
-		/* calculate how much space keywords and content-length
-		   value needs, then write that amount of spaces. */
-		space = strlen(get_keywords(ctx->flags));
-		space += sizeof("X-Keywords: ");
-		space += MBOX_HEADER_EXTRA_SPACE + MAX_INT_STRLEN + 1;
-
-		/* @UNSAFE */
-		buf = t_malloc(space);
-		memset(buf, ' ', space-1);
-		buf[space-1] = '\n';
-
-		if (write_func(ctx->output, buf, space) < 0) {
-			write_error(ctx);
+		/* write our extra headers */
+		ctx->extra_hdr_offset = ctx->output->offset;
+		if (write_func(ctx->output, str_data(ctx->headers),
+			       str_len(ctx->headers)) < 0)
 			return -1;
-		}
 		ctx->eoh_offset = ctx->output->offset;
 		return 1;
 	}
@@ -217,6 +189,8 @@
 			return 0;
 		if (strcasecmp(name, "X-Keywords") == 0)
 			return 0;
+		if (strcasecmp(name, "X-IMAP") == 0)
+			return 0;
 		if (strcasecmp(name, "X-IMAPbase") == 0)
 			return 0;
 		break;
@@ -225,51 +199,95 @@
 	return 1;
 }
 
-static int mbox_fix_header(struct mbox_save_context *ctx)
+static int mbox_save_init_sync(struct mbox_transaction_context *t)
 {
-	uoff_t old_offset;
-	const char *str;
-	int crlf = getenv("MAIL_SAVE_CRLF") != NULL;
+	struct mbox_save_context *ctx = t->save_ctx;
+	const struct mail_index_header *hdr;
 
-	old_offset = ctx->output->offset;
-	if (o_stream_seek(ctx->output, ctx->content_length_offset) < 0)
-                return mbox_set_syscall_error(ctx->ibox, "o_stream_seek()");
+	if (mail_index_get_header(ctx->ibox->view, &hdr) < 0) {
+		mail_storage_set_index_error(ctx->ibox);
+		return -1;
+	}
+	ctx->next_uid = hdr->next_uid;
+	ctx->synced = TRUE;
+        t->mbox_modified = TRUE;
 
-	/* write value for Content-Length */
-	str = dec2str(old_offset - (ctx->eoh_offset + 1 + crlf));
-	if (o_stream_send_str(ctx->output, str) < 0)
-		return write_error(ctx);
+	index_mail_init(&t->ictx, &ctx->mail, 0, NULL);
+	return 0;
+}
 
-	/* [CR]LF X-Keywords: */
-	str = crlf ? "\r\nX-Keywords:" : "\nX-Keywords:";
-	if (o_stream_send_str(ctx->output, str) < 0)
-		return write_error(ctx);
+static void status_flags_append(string_t *str, enum mail_flags flags,
+				const struct mbox_flag_type *flags_list)
+{
+	int i;
 
-	/* write keywords into X-Keywords */
-	str = get_keywords(ctx->flags);
-	if (o_stream_send_str(ctx->output, str) < 0)
-		return write_error(ctx);
+	for (i = 0; flags_list[i].chr != 0; i++) {
+		if ((flags & flags_list[i].flag) != 0)
+			str_append_c(str, flags_list[i].chr);
+	}
+}
 
-	if (o_stream_seek(ctx->output, old_offset) < 0)
-		return mbox_set_syscall_error(ctx->ibox, "o_stream_seek()");
-	return 0;
+static void mbox_save_append_flag_headers(string_t *str, enum mail_flags flags)
+{
+	if ((flags & STATUS_FLAGS_MASK) != 0) {
+		str_append(str, "Status: ");
+		status_flags_append(str, flags, mbox_status_flags);
+		str_append_c(str, '\n');
+	}
+
+	if ((flags & XSTATUS_FLAGS_MASK) != 0) {
+		str_append(str, "X-Status: ");
+		status_flags_append(str, flags, mbox_xstatus_flags);
+		str_append_c(str, '\n');
+	}
+}
+
+static void mbox_save_append_keyword_headers(struct mbox_save_context *ctx,
+					     const char *const *keywords,
+					     unsigned int count)
+{
+	unsigned char space[MBOX_HEADER_EXTRA_SPACE+1 +
+			    sizeof("Content-Length: \n")-1 + MAX_INT_STRLEN];
+	unsigned int i;
+
+	str_append(ctx->headers, "X-Keywords:");
+	for (i = 0; i < count; i++) {
+		str_append_c(ctx->headers, ' ');
+		str_append(ctx->headers, keywords[i]);
+	}
+
+	memset(space, ' ', sizeof(space));
+	str_append_n(ctx->headers, space, sizeof(space));
+	ctx->space_end_idx = str_len(ctx->headers);
+	str_append_c(ctx->headers, '\n');
 }
 
 int mbox_save(struct mailbox_transaction_context *_t,
 	      const struct mail_full_flags *flags,
 	      time_t received_date, int timezone_offset __attr_unused__,
-	      const char *from_envelope, struct istream *data)
+	      const char *from_envelope, struct istream *data,
+	      struct mail **mail_r)
 {
 	struct mbox_transaction_context *t =
 		(struct mbox_transaction_context *)_t;
 	struct index_mailbox *ibox = t->ictx.ibox;
 	struct mbox_save_context *ctx = t->save_ctx;
+	enum mail_flags save_flags;
+	keywords_mask_t keywords;
+	uint64_t offset;
+	uint32_t seq = 0;
 	int ret;
 
+	/* FIXME: we could write timezone_offset to From-line.. */
+	if (received_date == (time_t)-1)
+		received_date = ioloop_time;
+
 	if (ctx == NULL) {
 		ctx = t->save_ctx = i_new(struct mbox_save_context, 1);
 		ctx->ibox = ibox;
+		ctx->trans = t->ictx.trans;
 		ctx->append_offset = (uoff_t)-1;
+		ctx->headers = str_new(default_pool, 512);
 	}
 	ctx->flags = flags;
 
@@ -284,6 +302,17 @@
 				return -1;
 		}
 
+		if (mail_r == NULL) {
+			/* assign UIDs only if mbox doesn't require syncing */
+			ret = mbox_sync_has_changed(ibox);
+			if (ret < 0)
+				return -1;
+			if (ret == 0) {
+				if (mbox_save_init_sync(t) < 0)
+					return -1;
+			}
+		}
+
 		if (mbox_seek_to_end(ctx, &ctx->append_offset) < 0)
 			return -1;
 
@@ -292,27 +321,72 @@
 		o_stream_set_blocking(ctx->output, 60000, NULL, NULL);
 	}
 
+	if (!ctx->synced && mail_r != NULL) {
+		/* we'll need to assign UID for the mail immediately. */
+		if (mbox_sync(ibox, FALSE, FALSE, FALSE) < 0)
+			return -1;
+		if (mbox_save_init_sync(t) < 0)
+			return -1;
+	}
+
+	save_flags = (flags->flags & ~MAIL_RECENT) | MAIL_RECENT;
+	str_truncate(ctx->headers, 0);
+	if (ctx->synced) {
+		str_printfa(ctx->headers, "X-UID: %u\n", ctx->next_uid);
+		if (!ibox->keep_recent)
+			save_flags &= ~MAIL_RECENT;
+
+		memset(keywords, 0, INDEX_KEYWORDS_BYTE_COUNT);
+		// FIXME: set keywords
+		mail_index_append(ctx->trans, ctx->next_uid, &seq);
+		mail_index_update_flags(ctx->trans, seq, MODIFY_REPLACE,
+					save_flags, keywords);
+
+		offset = ctx->output->offset - 1;
+		mail_index_update_extra_rec(ctx->trans, seq,
+					    ibox->mbox_extra_idx, &offset);
+		ctx->next_uid++;
+	}
+	mbox_save_append_flag_headers(ctx->headers,
+				      save_flags ^ MBOX_NONRECENT);
+	mbox_save_append_keyword_headers(ctx, flags->keywords,
+					 flags->keywords_count);
+
 	i_assert(ibox->mbox_lock_type == F_WRLCK);
 
 	t_push();
 	if (write_from_line(ctx, received_date, from_envelope) < 0 ||
 	    mail_storage_save(ibox->box.storage, ibox->path, data, ctx->output,
-			      getenv("MAIL_SAVE_CRLF") != NULL,
+			      FALSE, getenv("MAIL_SAVE_CRLF") != NULL,
 			      save_header_callback, ctx) < 0 ||
-	    mbox_fix_header(ctx) < 0 ||
+	    mbox_write_content_length(ctx) < 0 ||
 	    mbox_append_lf(ctx) < 0) {
 		ret = -1;
 	} else {
 		ret = 0;
 	}
 	t_pop();
+
+	if (mail_r != NULL) {
+		const struct mail_index_record *rec;
+
+		rec = mail_index_lookup_append(ctx->trans, seq);
+		if (index_mail_next(&ctx->mail, rec, seq, FALSE) <= 0)
+			return -1;
+		*mail_r = &ctx->mail.mail;
+	}
+
 	return ret;
 }
 
 static void mbox_save_deinit(struct mbox_save_context *ctx)
 {
+	if (ctx->mail.pool != NULL)
+		index_mail_deinit(&ctx->mail);
+
 	if (ctx->output != NULL)
 		o_stream_unref(ctx->output);
+	str_free(ctx->headers);
 	i_free(ctx);
 }
 
@@ -320,7 +394,13 @@
 {
 	int ret = 0;
 
-	if (ctx->ibox->mbox_fd != -1) {
+	if (ctx->synced) {
+		mail_index_update_header(ctx->trans,
+			offsetof(struct mail_index_header, next_uid),
+			&ctx->next_uid, sizeof(ctx->next_uid));
+	}
+
+	if (!ctx->synced && ctx->ibox->mbox_fd != -1) {
 		if (fdatasync(ctx->ibox->mbox_fd) < 0) {
 			mbox_set_syscall_error(ctx->ibox, "fsync()");
 			ret = -1;

Index: mbox-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-storage.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- mbox-storage.h	6 May 2004 01:22:25 -0000	1.19
+++ mbox-storage.h	20 Jun 2004 03:25:34 -0000	1.20
@@ -14,6 +14,7 @@
 
 	struct mbox_save_context *save_ctx;
 	unsigned int mbox_lock_id;
+	unsigned int mbox_modified:1;
 };
 
 extern struct mail mbox_mail;
@@ -36,7 +37,8 @@
 int mbox_save(struct mailbox_transaction_context *t,
 	      const struct mail_full_flags *flags,
 	      time_t received_date, int timezone_offset,
-	      const char *from_envelope, struct istream *data);
+	      const char *from_envelope, struct istream *data,
+	      struct mail **mail_r);
 int mbox_save_commit(struct mbox_save_context *ctx);
 void mbox_save_rollback(struct mbox_save_context *ctx);
 

Index: mbox-sync-parse.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-parse.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- mbox-sync-parse.c	17 Jun 2004 21:29:20 -0000	1.12
+++ mbox-sync-parse.c	20 Jun 2004 03:25:34 -0000	1.13
@@ -131,10 +131,16 @@
 	if (ctx->sync_ctx->base_uid_validity == 0) {
 		ctx->sync_ctx->base_uid_validity = uid_validity;
 		ctx->sync_ctx->base_uid_last = uid_last;
-		ctx->sync_ctx->next_uid = uid_last+1;
+		if (ctx->sync_ctx->next_uid-1 <= uid_last)
+			ctx->sync_ctx->next_uid = uid_last+1;
+		else {
+			ctx->sync_ctx->update_base_uid_last =
+				ctx->sync_ctx->next_uid - 1;
+			ctx->need_rewrite = TRUE;
+		}
 	}
 
-	if (ctx->sync_ctx->prev_msg_uid >= ctx->sync_ctx->next_uid) {
+	if (ctx->sync_ctx->next_uid <= ctx->sync_ctx->prev_msg_uid) {
 		/* broken, update */
                 ctx->sync_ctx->next_uid = ctx->sync_ctx->prev_msg_uid+1;
 	}

Index: mbox-sync-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-private.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- mbox-sync-private.h	19 Jun 2004 00:19:48 -0000	1.16
+++ mbox-sync-private.h	20 Jun 2004 03:25:34 -0000	1.17
@@ -97,7 +97,10 @@
 	unsigned int seen_first_mail:1;
 };
 
-int mbox_sync(struct index_mailbox *ibox, int last_commit, int lock);
+int mbox_sync(struct index_mailbox *ibox, int last_commit,
+	      int sync_header, int lock);
+int mbox_sync_has_changed(struct index_mailbox *ibox);
+
 void mbox_sync_parse_next_mail(struct istream *input,
 			       struct mbox_sync_mail_context *ctx,
 			       int rewriting);

Index: mbox-sync-rewrite.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-rewrite.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- mbox-sync-rewrite.c	19 Jun 2004 19:52:25 -0000	1.19
+++ mbox-sync-rewrite.c	20 Jun 2004 03:25:34 -0000	1.20
@@ -262,6 +262,13 @@
 		mbox_set_syscall_error(ctx->sync_ctx->ibox, "pwrite_full()");
 		return -1;
 	}
+
+	if (ctx->sync_ctx->dest_first_mail) {
+		ctx->sync_ctx->base_uid_last =
+			ctx->sync_ctx->update_base_uid_last;
+                ctx->sync_ctx->update_base_uid_last = 0;
+	}
+
 	istream_raw_mbox_flush(ctx->sync_ctx->input);
 	return 1;
 }
@@ -292,7 +299,7 @@
 	   so we have to fool it. */
 	old_prev_msg_uid = sync_ctx->prev_msg_uid;
 	sync_ctx->prev_msg_uid = mails[idx].uid-1;
-	sync_ctx->dest_first_mail = seq == 1;
+	sync_ctx->dest_first_mail = mails[idx].from_offset == 0;
 
 	mbox_sync_parse_next_mail(sync_ctx->input, &mail_ctx, TRUE);
 	if (mails[idx].space != 0)
@@ -337,6 +344,12 @@
 		return -1;
 	}
 
+	if (mails[idx].from_offset == 0) {
+		sync_ctx->base_uid_last =
+			sync_ctx->update_base_uid_last;
+                sync_ctx->update_base_uid_last = 0;
+	}
+
 	return 0;
 }
 

Index: mbox-sync-update.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-update.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- mbox-sync-update.c	19 Jun 2004 00:19:48 -0000	1.15
+++ mbox-sync-update.c	20 Jun 2004 03:25:34 -0000	1.16
@@ -3,6 +3,7 @@
 #include "buffer.h"
 #include "str.h"
 #include "message-parser.h"
+#include "index-storage.h"
 #include "mbox-sync-private.h"
 
 static void status_flags_append(struct mbox_sync_mail_context *ctx,
@@ -140,7 +141,8 @@
 
 	if (ctx->hdr_pos[MBOX_HDR_STATUS] == (size_t)-1 &&
 	    (ctx->mail.flags & STATUS_FLAGS_MASK) != 0) {
-		ctx->mail.flags |= MBOX_NONRECENT;
+		if (!ctx->sync_ctx->ibox->keep_recent)
+                        ctx->mail.flags |= MBOX_NONRECENT;
 		ctx->hdr_pos[MBOX_HDR_STATUS] = str_len(ctx->header);
 		str_append(ctx->header, "Status: ");
 		status_flags_append(ctx, mbox_status_flags);
@@ -278,7 +280,8 @@
 			   INDEX_KEYWORDS_BYTE_COUNT) != 0)
 			mbox_sync_update_xkeywords(ctx);
 	} else {
-		if ((ctx->mail.flags & MBOX_NONRECENT) == 0) {
+		if ((ctx->mail.flags & MBOX_NONRECENT) == 0 &&
+		    !ctx->sync_ctx->ibox->keep_recent) {
 			ctx->mail.flags |= MBOX_NONRECENT;
 			mbox_sync_update_status(ctx);
 		}
@@ -296,7 +299,9 @@
 	    (mail->flags & STATUS_FLAGS_MASK) ||
 	    (ctx->mail.flags & MBOX_NONRECENT) == 0) {
 		ctx->mail.flags = (ctx->mail.flags & ~STATUS_FLAGS_MASK) |
-			(mail->flags & STATUS_FLAGS_MASK) | MBOX_NONRECENT;
+			(mail->flags & STATUS_FLAGS_MASK);
+		if (!ctx->sync_ctx->ibox->keep_recent)
+                        ctx->mail.flags |= MBOX_NONRECENT;
 		mbox_sync_update_status(ctx);
 	}
 	if ((ctx->mail.flags & XSTATUS_FLAGS_MASK) !=

Index: mbox-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- mbox-sync.c	19 Jun 2004 19:16:57 -0000	1.39
+++ mbox-sync.c	20 Jun 2004 03:25:34 -0000	1.40
@@ -258,7 +258,8 @@
 
 	mbox_sync_buffer_delete_old(sync_ctx->syncs, uid);
 	while (uid >= sync_rec->uid1) {
-		if (sync_rec->uid1 != 0) {
+		if (sync_rec->uid1 != 0 &&
+		    sync_rec->type != MAIL_INDEX_SYNC_TYPE_APPEND) {
 			i_assert(uid <= sync_rec->uid2);
 			buffer_append(sync_ctx->syncs, sync_rec,
 				      sizeof(*sync_rec));
@@ -277,6 +278,14 @@
 			memset(sync_rec, 0, sizeof(*sync_rec));
 			break;
 		}
+
+		if (sync_rec->type == MAIL_INDEX_SYNC_TYPE_APPEND) {
+			if (sync_rec->uid2 >= sync_ctx->next_uid) {
+				sync_ctx->next_uid = sync_rec->uid2 + 1;
+                                sync_ctx->update_base_uid_last = sync_rec->uid2;
+			}
+			memset(sync_rec, 0, sizeof(*sync_rec));
+		}
 	}
 
 	if (!*sync_expunge_r)
@@ -555,7 +564,9 @@
 				return -1;
 		}
 	} else if (mail_ctx->need_rewrite ||
-		   buffer_get_used_size(sync_ctx->syncs) != 0) {
+		   buffer_get_used_size(sync_ctx->syncs) != 0 ||
+		   (mail_ctx->seq == 1 &&
+		    sync_ctx->update_base_uid_last != 0)) {
 		if ((ret = mbox_sync_check_excl_lock(sync_ctx)) < 0)
 			return ret;
 
@@ -923,22 +934,26 @@
         sync_ctx->seen_first_mail = FALSE;
 }
 
-static int mbox_sync_do(struct mbox_sync_context *sync_ctx)
+static int mbox_sync_do(struct mbox_sync_context *sync_ctx, int sync_header)
 {
 	struct mbox_sync_mail_context mail_ctx;
 	struct stat st;
 	uint32_t min_msg_count;
 	int ret;
 
-	if (fstat(sync_ctx->fd, &st) < 0) {
-		mbox_set_syscall_error(sync_ctx->ibox, "stat()");
-		return -1;
-	}
+	if (sync_header)
+		min_msg_count = 1;
+	else {
+		if (fstat(sync_ctx->fd, &st) < 0) {
+			mbox_set_syscall_error(sync_ctx->ibox, "stat()");
+			return -1;
+		}
 
-	min_msg_count =
-		(uint32_t)st.st_mtime == sync_ctx->hdr->sync_stamp &&
-		(uint64_t)st.st_size == sync_ctx->hdr->sync_size ?
-		0 : (uint32_t)-1;
+		min_msg_count =
+			(uint32_t)st.st_mtime == sync_ctx->hdr->sync_stamp &&
+			(uint64_t)st.st_size == sync_ctx->hdr->sync_size ?
+			0 : (uint32_t)-1;
+	}
 
 	mbox_sync_restart(sync_ctx);
 	if ((ret = mbox_sync_loop(sync_ctx, &mail_ctx, min_msg_count)) == -1)
@@ -975,7 +990,7 @@
 	return 0;
 }
 
-static int mbox_sync_has_changed(struct index_mailbox *ibox)
+int mbox_sync_has_changed(struct index_mailbox *ibox)
 {
 	const struct mail_index_header *hdr;
 	struct stat st;
@@ -1020,7 +1035,8 @@
 	return 0;
 }
 
-int mbox_sync(struct index_mailbox *ibox, int last_commit, int lock)
+int mbox_sync(struct index_mailbox *ibox, int last_commit,
+	      int sync_header, int lock)
 {
 	struct mail_index_sync_ctx *index_sync_ctx;
 	struct mail_index_view *sync_view;
@@ -1035,11 +1051,16 @@
 			return -1;
 	}
 
-	if ((ret = mbox_sync_has_changed(ibox)) < 0) {
-		if (lock)
-			(void)mbox_unlock(ibox, lock_id);
-		return -1;
+	if (sync_header)
+		ret = 0;
+	else {
+		if ((ret = mbox_sync_has_changed(ibox)) < 0) {
+			if (lock)
+				(void)mbox_unlock(ibox, lock_id);
+			return -1;
+		}
 	}
+
 	if (ret == 0 && !last_commit)
 		return 0;
 
@@ -1084,7 +1105,7 @@
 
 	if (mbox_sync_lock(&sync_ctx, lock_type) < 0)
 		ret = -1;
-	else if (mbox_sync_do(&sync_ctx) < 0)
+	else if (mbox_sync_do(&sync_ctx, sync_header) < 0)
 		ret = -1;
 
 	if (ret < 0)
@@ -1103,8 +1124,9 @@
 		ret = -1;
 	}
 
-	if (sync_ctx.base_uid_last != sync_ctx.next_uid-1 && ret == 0 &&
-	    !ibox->mbox_readonly) {
+	if (sync_ctx.seen_first_mail &&
+	    sync_ctx.base_uid_last != sync_ctx.next_uid-1 &&
+	    ret == 0 && !ibox->mbox_readonly) {
 		/* rewrite X-IMAPbase header. do it after mail_index_sync_end()
 		   so previous transactions have been committed. */
 		/* FIXME: ugly .. */
@@ -1155,7 +1177,7 @@
 	    ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) {
 		ibox->sync_last_check = ioloop_time;
 
-		if (mbox_sync(ibox, FALSE, FALSE) < 0)
+		if (mbox_sync(ibox, FALSE, FALSE, FALSE) < 0)
 			return -1;
 	}
 

Index: mbox-transaction.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-transaction.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mbox-transaction.c	15 Jun 2004 01:15:44 -0000	1.2
+++ mbox-transaction.c	20 Jun 2004 03:25:34 -0000	1.3
@@ -37,7 +37,7 @@
 	}
 
 	if (ret == 0) {
-		if (mbox_sync(ibox, TRUE, FALSE) < 0)
+		if (mbox_sync(ibox, TRUE, t->mbox_modified, FALSE) < 0)
 			ret = -1;
 	}
 



More information about the dovecot-cvs mailing list