[dovecot-cvs] dovecot/src/lib-storage/index/dbox dbox-sync-expunge.c, 1.1, 1.2 dbox-sync.c, 1.1, 1.2 dbox-sync.h, 1.1, 1.2

cras at dovecot.org cras at dovecot.org
Wed Dec 21 16:15:39 EET 2005


Update of /var/lib/cvs/dovecot/src/lib-storage/index/dbox
In directory talvi:/tmp/cvs-serv25340

Modified Files:
	dbox-sync-expunge.c dbox-sync.c dbox-sync.h 
Log Message:
Write flag changes to dbox files.



Index: dbox-sync-expunge.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-sync-expunge.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbox-sync-expunge.c	27 Nov 2005 23:05:29 -0000	1.1
+++ dbox-sync-expunge.c	21 Dec 2005 14:15:37 -0000	1.2
@@ -4,7 +4,6 @@
 #include "array.h"
 #include "istream.h"
 #include "ostream.h"
-#include "write-full.h"
 #include "seq-range-array.h"
 #include "dbox-storage.h"
 #include "dbox-uidlist.h"
@@ -322,52 +321,11 @@
 	return 0;
 }
 
-static int
-dbox_sync_expunge_mark_flags(struct dbox_sync_context *ctx,
-			     const struct dbox_sync_file_entry *entry,
-			     unsigned int sync_idx)
-{
-	struct dbox_mailbox *mbox = ctx->mbox;
-	const struct dbox_sync_rec *sync_rec;
-	unsigned char expunged_flag = '1';
-	uint32_t file_seq, uid2;
-	uoff_t offset;
-	int ret;
-
-	sync_rec = array_idx(&entry->sync_recs, sync_idx);
-	if (dbox_sync_get_file_offset(ctx, sync_rec->seq1,
-				      &file_seq, &offset) < 0)
-		return -1;
-
-	if (mail_index_lookup_uid(ctx->sync_view, sync_rec->seq2, &uid2) < 0) {
-		mail_storage_set_index_error(&ctx->mbox->ibox);
-		return -1;
-	}
-
-	while (mbox->file->seeked_uid <= uid2) {
-		ret = pwrite_full(ctx->mbox->file->fd, &expunged_flag, 1,
-				  offset + offsetof(struct dbox_mail_header,
-						    expunged));
-		if (ret < 0) {
-			mail_storage_set_critical(STORAGE(mbox->storage),
-				"pwrite(%s) failed: %m", mbox->path);
-			return -1;
-		}
-
-		ret = dbox_file_seek_next_nonexpunged(mbox);
-		if (ret <= 0) {
-			if (ret == 0)
-				break;
-			return -1;
-		}
-	}
-	return 0;
-}
-
 int dbox_sync_expunge(struct dbox_sync_context *ctx,
 		      const struct dbox_sync_file_entry *entry,
 		      unsigned int sync_idx)
 {
+	const struct dbox_sync_rec *sync_rec;
 	struct dotlock *dotlock;
 	const char *path;
 	int ret;
@@ -400,5 +358,6 @@
 	   choice but to just mark the mail expunged. otherwise we'd
 	   deadlock (appending process waits for uidlist lock which
 	   we have, we wait for file lock which append process has) */
-	return dbox_sync_expunge_mark_flags(ctx, entry, sync_idx);
+	sync_rec = array_idx(&entry->sync_recs, sync_idx);
+	return dbox_sync_update_flags(ctx, sync_rec);
 }

Index: dbox-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-sync.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbox-sync.c	27 Nov 2005 23:05:29 -0000	1.1
+++ dbox-sync.c	21 Dec 2005 14:15:37 -0000	1.2
@@ -4,6 +4,7 @@
 #include "ioloop.h"
 #include "array.h"
 #include "hash.h"
+#include "write-full.h"
 #include "dbox-file.h"
 #include "dbox-sync.h"
 #include "dbox-uidlist.h"
@@ -117,6 +118,90 @@
 	return 0;
 }
 
+int dbox_sync_update_flags(struct dbox_sync_context *ctx,
+			   const struct dbox_sync_rec *sync_rec)
+{
+	static enum mail_flags dbox_flag_list[] = {
+		MAIL_ANSWERED,
+		MAIL_FLAGGED,
+		MAIL_DELETED,
+		MAIL_SEEN,
+		MAIL_DRAFT,
+		0 /* expunged */
+	};
+#define DBOX_FLAG_COUNT (sizeof(dbox_flag_list)/sizeof(dbox_flag_list[0]))
+	struct dbox_mailbox *mbox = ctx->mbox;
+	unsigned char dbox_flag_array[DBOX_FLAG_COUNT];
+	unsigned char dbox_flag_mask[DBOX_FLAG_COUNT];
+	uint32_t file_seq, uid2;
+	uoff_t offset;
+	unsigned int i, start, first_flag_offset;
+	int ret;
+
+	/* first build flag array and mask */
+	if (sync_rec->type == MAIL_INDEX_SYNC_TYPE_EXPUNGE) {
+		memset(dbox_flag_array, '0', sizeof(dbox_flag_array));
+		memset(dbox_flag_mask, 0, sizeof(dbox_flag_mask));
+		dbox_flag_mask[5] = 1;
+		dbox_flag_array[5] = '1';
+	} else {
+		i_assert(sync_rec->type == MAIL_INDEX_SYNC_TYPE_FLAGS);
+		for (i = 0; i < DBOX_FLAG_COUNT; i++) {
+			dbox_flag_array[i] =
+				(sync_rec->value.flags.add &
+				 dbox_flag_list[i]) != 0 ? '1' : '0';
+			dbox_flag_mask[i] = dbox_flag_array[i] ||
+				(sync_rec->value.flags.remove &
+				 dbox_flag_list[i]) != 0;
+		}
+	}
+	first_flag_offset = offsetof(struct dbox_mail_header, answered);
+
+	if (dbox_sync_get_file_offset(ctx, sync_rec->seq1,
+				      &file_seq, &offset) < 0)
+		return -1;
+
+	if (mail_index_lookup_uid(ctx->sync_view, sync_rec->seq2, &uid2) < 0) {
+		mail_storage_set_index_error(&ctx->mbox->ibox);
+		return -1;
+	}
+
+	if ((ret = dbox_file_seek(mbox, file_seq, offset)) <= 0)
+		return ret;
+
+	while (mbox->file->seeked_uid <= uid2) {
+		for (i = 0; i < DBOX_FLAG_COUNT; ) {
+			if (!dbox_flag_mask[i])
+				continue;
+
+			start = i;
+			while (i < DBOX_FLAG_COUNT) {
+				if (!dbox_flag_mask[i])
+					break;
+				i++;
+			}
+			ret = pwrite_full(ctx->mbox->file->fd,
+					  dbox_flag_array+start, i - start,
+					  offset + first_flag_offset + start);
+			if (ret < 0) {
+				mail_storage_set_critical(
+					STORAGE(mbox->storage),
+					"pwrite(%s) failed: %m", mbox->path);
+				return -1;
+			}
+		}
+
+		ret = dbox_file_seek_next_nonexpunged(mbox);
+		if (ret <= 0) {
+			if (ret == 0)
+				break;
+			return -1;
+		}
+		offset = mbox->file->seeked_offset;
+	}
+	return 0;
+}
+
 static int dbox_sync_file(struct dbox_sync_context *ctx,
                           const struct dbox_sync_file_entry *entry)
 {
@@ -140,6 +225,9 @@
 			/* handled expunging by writing expunge flags */
 			break;
 		case MAIL_INDEX_SYNC_TYPE_FLAGS:
+			if (dbox_sync_update_flags(ctx, &sync_recs[i]) < 0)
+				return -1;
+			break;
 		case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
 		case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
 		case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:

Index: dbox-sync.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-sync.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbox-sync.h	27 Nov 2005 23:05:29 -0000	1.1
+++ dbox-sync.h	21 Dec 2005 14:15:37 -0000	1.2
@@ -2,10 +2,10 @@
 #define __DBOX_SYNC_H
 
 #include "mail-index.h"
+#include "mail-storage.h"
 
 struct mailbox;
 struct dbox_mailbox;
-enum mailbox_sync_flags;
 
 struct dbox_sync_rec {
 	uint32_t seq1, seq2;
@@ -52,6 +52,8 @@
 int dbox_sync_get_file_offset(struct dbox_sync_context *ctx, uint32_t seq,
 			      uint32_t *file_seq_r, uoff_t *offset_r);
 
+int dbox_sync_update_flags(struct dbox_sync_context *ctx,
+			   const struct dbox_sync_rec *sync_rec);
 int dbox_sync_expunge(struct dbox_sync_context *ctx,
 		      const struct dbox_sync_file_entry *entry,
                       unsigned int sync_idx);



More information about the dovecot-cvs mailing list