[dovecot-cvs] dovecot/src/lib-storage/index index-expunge.c,1.17,1.18 index-mail.c,1.12,1.13 index-mail.h,1.4,1.5 index-storage.c,1.36,1.37 index-storage.h,1.44,1.45 index-update-flags.c,1.23,1.24

cras at procontrol.fi cras at procontrol.fi
Sat Jul 26 20:33:24 EEST 2003


Update of /home/cvs/dovecot/src/lib-storage/index
In directory danu:/tmp/cvs-serv28560/lib-storage/index

Modified Files:
	index-expunge.c index-mail.c index-mail.h index-storage.c 
	index-storage.h index-update-flags.c 
Log Message:
API change for expunging messages. Not exactly what I wanted, but good
enough.



Index: index-expunge.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-expunge.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- index-expunge.c	21 Jul 2003 14:35:39 -0000	1.17
+++ index-expunge.c	26 Jul 2003 16:33:22 -0000	1.18
@@ -1,10 +1,12 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
 
 #include "lib.h"
 #include "index-storage.h"
+#include "index-expunge.h"
 
-int index_expunge_seek_first(struct index_mailbox *ibox, unsigned int *seq,
-			     struct mail_index_record **rec)
+static int index_expunge_seek_first(struct index_mailbox *ibox,
+				    unsigned int *seq,
+				    struct mail_index_record **rec)
 {
 	struct mail_index_header *hdr;
 
@@ -43,70 +45,156 @@
 	return TRUE;
 }
 
-int index_expunge_mails(struct index_mailbox *ibox,
-			struct mail_index_record *first_rec,
-			struct mail_index_record *last_rec,
-			unsigned int first_seq, unsigned int last_seq,
-			int notify)
+struct mail_expunge_context *
+index_storage_expunge_init(struct mailbox *box,
+			   enum mail_fetch_field wanted_fields,
+			   int expunge_all)
 {
-	unsigned int max;
+	struct index_mailbox *ibox = (struct index_mailbox *) box;
+	struct mail_expunge_context *ctx;
 
-	if (!ibox->index->expunge(ibox->index, first_rec, last_rec,
-				  first_seq, last_seq, FALSE))
-		return FALSE;
+	if (box->readonly) {
+		box->storage->callbacks->
+			notify_no(box, "Mailbox is read-only, ignoring expunge",
+				  box->storage->callback_context);
+		return i_new(struct mail_expunge_context, 1);
+	}
 
-	if (first_seq > ibox->synced_messages_count)
-		return TRUE;
+	if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
+		return NULL;
 
-	max = last_seq > ibox->synced_messages_count ?
-		ibox->synced_messages_count : last_seq;
+	ctx = i_new(struct mail_expunge_context, 1);
+	ctx->ibox = ibox;
+	ctx->expunge_all = expunge_all;
+	index_mail_init(ibox, &ctx->mail, wanted_fields, NULL);
 
-	ibox->synced_messages_count -= max - first_seq + 1;
-	if (notify) {
-		struct mail_storage_callbacks *cb;
-		void *cb_ctx;
+	do {
+		if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
+						 MAIL_LOCK_EXCLUSIVE))
+			break;
 
-		cb = ibox->box.storage->callbacks;
-		cb_ctx = ibox->box.storage->callback_context;
+		/* modifylog must be marked synced before expunging
+		   anything new */
+		if (!index_storage_sync_modifylog(ibox, TRUE))
+			break;
 
-		while (max >= first_seq) {
-			cb->expunge(&ibox->box, first_seq, cb_ctx);
-			max--;
+		if (expunge_all) {
+			ctx->seq = 1;
+			ctx->rec = ibox->index->lookup(ibox->index, 1);
+		} else {
+			if (!index_expunge_seek_first(ibox, &ctx->seq,
+						      &ctx->rec))
+				break;
+
+			ctx->fetch_next = ctx->rec != NULL &&
+				(ctx->rec->msg_flags & MAIL_DELETED) == 0;
 		}
+
+		return ctx;
+	} while (0);
+
+	(void)index_storage_lock(ctx->ibox, MAIL_LOCK_UNLOCK);
+	i_free(ctx);
+	return NULL;
+}
+
+int index_storage_expunge_deinit(struct mail_expunge_context *ctx)
+{
+	int ret = !ctx->failed;
+
+	if (ctx->first_seq != 0) {
+		if (!ctx->ibox->index->expunge(ctx->ibox->index,
+					       ctx->first_rec, ctx->last_rec,
+					       ctx->first_seq, ctx->last_seq,
+					       FALSE))
+			ret = FALSE;
 	}
 
-	return TRUE;
+	if (ctx->ibox != NULL) {
+		ctx->ibox->fetch_mail.data.rec = NULL;
+
+		if (!index_storage_lock(ctx->ibox, MAIL_LOCK_UNLOCK))
+			ret = FALSE;
+	}
+
+	i_free(ctx);
+	return ret;
 }
 
-int index_storage_expunge(struct mailbox *box, int notify)
+struct mail *index_storage_expunge_fetch_next(struct mail_expunge_context *ctx)
 {
-	struct index_mailbox *ibox = (struct index_mailbox *) box;
-	int failed;
+	struct mail_index *index = ctx->ibox->index;
 
-	if (box->readonly) {
-		box->storage->callbacks->
-			notify_no(&ibox->box,
-				  "Mailbox is read-only, ignoring expunge",
-				  box->storage->callback_context);
-		return TRUE;
+	if (ctx->rec == NULL)
+		return NULL;
+
+	if (ctx->fetch_next) {
+		do {
+			ctx->seq++;
+			ctx->rec = index->next(index, ctx->rec);
+			if (ctx->rec == NULL)
+				return NULL;
+		} while ((ctx->rec->msg_flags & MAIL_DELETED) == 0 &&
+			 !ctx->expunge_all);
+	} else {
+		ctx->fetch_next = TRUE;
 	}
 
-	if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
-		return FALSE;
+	ctx->mail.expunge_counter = index->expunge_counter;
+	ctx->mail.mail.seq = ctx->seq;
+	ctx->mail.mail.uid = ctx->rec->uid;
 
-	if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
-					 MAIL_LOCK_EXCLUSIVE))
-		return FALSE;
+	if (!index_mail_next(&ctx->mail, ctx->rec, ctx->seq)) {
+		ctx->failed = TRUE;
+		return NULL;
+	}
 
-	/* modifylog must be marked synced before expunging
-	   anything new */
-	if (!index_storage_sync_modifylog(ibox, TRUE))
-		failed = TRUE;
-	else
-		failed = !ibox->expunge_locked(ibox, notify);
+	return &ctx->mail.mail;
+}
 
-	if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK))
-		return FALSE;
+int index_storage_expunge(struct mail *mail, struct mail_expunge_context *ctx,
+			  unsigned int *seq_r, int notify)
+{
+	struct index_mail *imail = (struct index_mail *) mail;
+	struct index_mailbox *ibox = imail->ibox;
+	unsigned int seq;
 
-	return !failed;
+	/* currently we allow expunges only from beginning to end so we can
+	   easily update sequence numbers */
+	i_assert(ctx->last_seq < ctx->seq);
+
+	seq = mail->seq;
+	if (ctx->first_seq != 0)
+		seq -= (ctx->last_seq - ctx->first_seq) + 1;
+	if (seq_r != NULL) *seq_r = seq;
+
+	if (ctx->first_seq != 0 && ctx->seq != ctx->last_seq+1) {
+		if (!ibox->index->expunge(ibox->index,
+					  ctx->first_rec, ctx->last_rec,
+					  ctx->first_seq, ctx->last_seq, FALSE))
+			return FALSE;
+
+		ctx->seq -= (ctx->last_seq - ctx->first_seq) + 1;
+		ctx->rec = ibox->index->lookup(ibox->index, ctx->seq);
+
+		ctx->first_seq = 0;
+	}
+
+	if (ctx->first_seq == 0) {
+		ctx->first_seq = ctx->seq;
+		ctx->first_rec = ctx->rec;
+	}
+	ctx->last_seq = ctx->seq;
+	ctx->last_rec = ctx->rec;
+
+	ibox->fetch_mail.data.rec = NULL;
+
+	ibox->synced_messages_count--;
+	if (notify && seq <= ibox->synced_messages_count+1) {
+		ibox->box.storage->callbacks->
+			expunge(&ibox->box, seq,
+				ibox->box.storage->callback_context);
+	}
+
+	return TRUE;
 }

Index: index-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- index-mail.c	23 Jul 2003 01:44:16 -0000	1.12
+++ index-mail.c	26 Jul 2003 16:33:22 -0000	1.13
@@ -12,6 +12,7 @@
 #include "mail-index-util.h"
 #include "mail-custom-flags.h"
 #include "index-storage.h"
+#include "index-expunge.h"
 #include "index-mail.h"
 
 #include <ctype.h>
@@ -650,7 +651,8 @@
 	get_stream,
 	get_special,
 	index_storage_update_flags,
-	index_storage_copy
+	index_storage_copy,
+	index_storage_expunge
 };
 
 void index_mail_init(struct index_mailbox *ibox, struct index_mail *mail,
@@ -664,6 +666,7 @@
 	mail->ibox = ibox;
 	mail->wanted_fields = wanted_fields;
 	mail->wanted_headers = wanted_headers;
+	mail->expunge_counter = ibox->index->expunge_counter;
 
 	if (ibox->mail_init != NULL)
 		ibox->mail_init(mail);
@@ -674,6 +677,8 @@
 {
 	struct index_mail_data *data = &mail->data;
 	int ret, open_mail, parse_header, envelope_headers;
+
+	i_assert(mail->expunge_counter == mail->ibox->index->expunge_counter);
 
 	t_push();
 

Index: index-mail.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- index-mail.h	23 Jul 2003 01:44:16 -0000	1.4
+++ index-mail.h	26 Jul 2003 16:33:22 -0000	1.5
@@ -1,6 +1,10 @@
 #ifndef __INDEX_MAIL_H
 #define __INDEX_MAIL_H
 
+#include "message-size.h"
+
+struct message_header_line;
+
 struct cached_header {
 	struct cached_header *next;
 
@@ -40,6 +44,7 @@
 
 	pool_t pool;
 	struct index_mailbox *ibox;
+	unsigned int expunge_counter;
 	buffer_t *header_buf;
 
 	enum mail_fetch_field wanted_fields;

Index: index-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- index-storage.c	23 Jul 2003 02:55:12 -0000	1.36
+++ index-storage.c	26 Jul 2003 16:33:22 -0000	1.37
@@ -288,7 +288,7 @@
 		if (ibox->lock_type != MAILBOX_LOCK_UNLOCK)
 			return TRUE;
 	} else {
-		if (ibox->index->lock_type == MAIL_LOCK_EXCLUSIVE)
+		if (ibox->lock_type == MAIL_LOCK_EXCLUSIVE)
 			return TRUE;
 	}
 

Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- index-storage.h	23 Jul 2003 02:55:12 -0000	1.44
+++ index-storage.h	26 Jul 2003 16:33:22 -0000	1.45
@@ -17,7 +17,6 @@
 
 	/* expunge messages marked as deleted, requires index to be
 	   exclusively locked */
-	int (*expunge_locked)(struct index_mailbox *ibox, int notify);
 	void (*mail_init)(struct index_mail *mail);
 
 	struct mail_index *index;
@@ -36,6 +35,7 @@
 	enum mail_lock_notify_type last_notify_type;
 
 	unsigned int sent_diskspace_warning:1;
+	unsigned int sent_readonly_flags_warning:1;
 };
 
 int mail_storage_set_index_error(struct index_mailbox *ibox);
@@ -69,14 +69,6 @@
 
 unsigned int index_storage_get_recent_count(struct mail_index *index);
 
-int index_expunge_seek_first(struct index_mailbox *ibox, unsigned int *seq,
-			     struct mail_index_record **rec);
-int index_expunge_mails(struct index_mailbox *ibox,
-			struct mail_index_record *first_rec,
-			struct mail_index_record *last_rec,
-			unsigned int first_seq, unsigned int last_seq,
-			int notify);
-
 void index_mailbox_check_add(struct index_mailbox *ibox, const char *path);
 void index_mailbox_check_remove_all(struct index_mailbox *ibox);
 
@@ -84,7 +76,6 @@
 void index_storage_set_callbacks(struct mail_storage *storage,
 				 struct mail_storage_callbacks *callbacks,
 				 void *context);
-int index_storage_expunge(struct mailbox *box, int notify);
 int index_storage_get_status(struct mailbox *box,
 			     enum mailbox_status_items items,
 			     struct mailbox_status *status);

Index: index-update-flags.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-update-flags.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- index-update-flags.c	23 Jul 2003 01:44:16 -0000	1.23
+++ index-update-flags.c	26 Jul 2003 16:33:22 -0000	1.24
@@ -15,6 +15,10 @@
 	enum mail_flags modify_flags, new_flags;
 
 	if (mail->box->readonly) {
+		if (ibox->sent_readonly_flags_warning)
+			return TRUE;
+                ibox->sent_readonly_flags_warning = TRUE;
+
 		storage->callbacks->
 			notify_no(&ibox->box,
 				  "Mailbox is read-only, ignoring flag changes",



More information about the dovecot-cvs mailing list