changeset 5950:49aebb3028f7 HEAD

Added support for updating uidlist record extensions.
author Timo Sirainen <tss@iki.fi>
date Thu, 12 Jul 2007 02:42:32 +0300
parents 1a80f37a4a12
children e9b5d3d33b95
files src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/index/maildir/maildir-uidlist.h
diffstat 3 files changed, 74 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-sync.c	Thu Jul 12 02:40:14 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Thu Jul 12 02:42:32 2007 +0300
@@ -762,14 +762,18 @@
 int maildir_sync_last_commit(struct maildir_mailbox *mbox)
 {
         struct maildir_sync_context *ctx;
-	int ret;
+	int ret = 0;
 
-	if (mbox->ibox.commit_log_file_seq == 0)
-		return 0;
+	if (mbox->ibox.commit_log_file_seq != 0) {
+		ctx = maildir_sync_context_new(mbox);
+		ret = maildir_sync_context(ctx, FALSE, TRUE);
+		maildir_sync_deinit(ctx);
+	}
 
-	ctx = maildir_sync_context_new(mbox);
-	ret = maildir_sync_context(ctx, FALSE, TRUE);
-	maildir_sync_deinit(ctx);
+	if (ret == 0) {
+		if (maildir_uidlist_update(mbox->uidlist) < 0)
+			ret = -1;
+	}
 	return ret < 0 ? -1 : 0;
 }
 
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Thu Jul 12 02:40:14 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Thu Jul 12 02:42:32 2007 +0300
@@ -612,7 +612,7 @@
         return ret;
 }
 
-static const struct maildir_uidlist_rec *
+static struct maildir_uidlist_rec *
 maildir_uidlist_lookup_rec(struct maildir_uidlist *uidlist, uint32_t uid,
 			   unsigned int *idx_r)
 {
@@ -761,6 +761,44 @@
 		uidlist->next_uid = next_uid;
 }
 
+void maildir_uidlist_set_ext(struct maildir_uidlist *uidlist, uint32_t uid,
+			     enum maildir_uidlist_rec_ext_key key,
+			     const char *value)
+{
+	struct maildir_uidlist_rec *rec;
+	unsigned int idx;
+	const char *p;
+	buffer_t *buf;
+	unsigned int len;
+
+	rec = maildir_uidlist_lookup_rec(uidlist, uid, &idx);
+	i_assert(rec != NULL);
+
+	t_push();
+	buf = buffer_create_dynamic(pool_datastack_create(), 128);
+
+	/* copy existing extensions, except for the one we're updating */
+	if (rec->extensions != NULL) {
+		p = rec->extensions;
+		while (*p != '\0') {
+			/* <key><value>\0 */
+			len = strlen(p) + 1;
+			if (*p != (char)key)
+				buffer_append(buf, p, len);
+			p += len;
+		}
+	}
+	buffer_append_c(buf, key);
+	buffer_append(buf, value, strlen(value) + 1);
+	buffer_append_c(buf, '\0');
+
+	rec->extensions = p_malloc(uidlist->record_pool, buf->used);
+	memcpy(rec->extensions, buf->data, buf->used);
+
+	uidlist->recreate = TRUE;
+	t_pop();
+}
+
 static int maildir_uidlist_write_fd(struct maildir_uidlist *uidlist, int fd,
 				    const char *path, unsigned int first_idx,
 				    uoff_t *file_size_r)
@@ -895,7 +933,21 @@
 	return ret;
 }
 
-static int maildir_uidlist_update(struct maildir_uidlist_sync_ctx *ctx)
+int maildir_uidlist_update(struct maildir_uidlist *uidlist)
+{
+	int ret;
+
+	if (!uidlist->recreate)
+		return 0;
+
+	if (maildir_uidlist_lock(uidlist) <= 0)
+		return -1;
+	ret = maildir_uidlist_recreate(uidlist);
+	maildir_uidlist_unlock(uidlist);
+	return ret;
+}
+
+static int maildir_uidlist_sync_update(struct maildir_uidlist_sync_ctx *ctx)
 {
 	struct maildir_uidlist *uidlist = ctx->uidlist;
 	uoff_t file_size;
@@ -1231,9 +1283,9 @@
 	if (ctx->partial)
 		maildir_uidlist_mark_all(ctx->uidlist, FALSE);
 
-	if (ctx->changed && !ctx->failed) {
+	if ((ctx->changed || ctx->uidlist->recreate) && !ctx->failed) {
 		t_push();
-		ret = maildir_uidlist_update(ctx);
+		ret = maildir_uidlist_sync_update(ctx);
 		t_pop();
 	}
 
--- a/src/lib-storage/index/maildir/maildir-uidlist.h	Thu Jul 12 02:40:14 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h	Thu Jul 12 02:42:32 2007 +0300
@@ -65,6 +65,14 @@
 void maildir_uidlist_set_next_uid(struct maildir_uidlist *uidlist,
 				  uint32_t next_uid, bool force);
 
+void maildir_uidlist_set_ext(struct maildir_uidlist *uidlist, uint32_t uid,
+			     enum maildir_uidlist_rec_ext_key key,
+			     const char *value);
+
+/* If uidlist has changed, update it. This is mostly meant to be used with
+   maildir_uidlist_set_ext() */
+int maildir_uidlist_update(struct maildir_uidlist *uidlist);
+
 /* Sync uidlist with what's actually on maildir. Returns same as
    maildir_uidlist_lock(). */
 int maildir_uidlist_sync_init(struct maildir_uidlist *uidlist,