dovecot-2.0: sdbox: When deleting a mailbox, make sure all of it...

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 2 14:34:03 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/75e4f4a86cb3
changeset: 12257:75e4f4a86cb3
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Aug 26 18:16:04 2010 +0100
description:
sdbox: When deleting a mailbox, make sure all of its attachments get deleted.

diffstat:

 src/lib-storage/index/dbox-single/sdbox-file.c    |  55 +++++++++++++++++++++++++++
 src/lib-storage/index/dbox-single/sdbox-file.h    |   2 +
 src/lib-storage/index/dbox-single/sdbox-storage.c |  43 +++++++++++++++++++++-
 src/lib-storage/index/dbox-single/sdbox-sync.c    |  56 +---------------------------
 4 files changed, 100 insertions(+), 56 deletions(-)

diffs (220 lines):

diff -r 968a4dd6240a -r 75e4f4a86cb3 src/lib-storage/index/dbox-single/sdbox-file.c
--- a/src/lib-storage/index/dbox-single/sdbox-file.c	Tue Aug 24 17:03:40 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-file.c	Thu Aug 26 18:16:04 2010 +0100
@@ -6,6 +6,7 @@
 #include "mkdir-parents.h"
 #include "istream.h"
 #include "ostream.h"
+#include "dbox-attachment.h"
 #include "sdbox-storage.h"
 #include "sdbox-file.h"
 
@@ -238,3 +239,57 @@
 	}
 	return 0;
 }
+
+int sdbox_file_unlink_with_attachments(struct dbox_file *file)
+{
+	struct dbox_storage *storage = file->storage;
+	ARRAY_TYPE(mail_attachment_extref) extrefs;
+	const struct mail_attachment_extref *extref;
+	const char *line;
+	pool_t pool;
+	bool deleted;
+	int ret;
+
+	/* read the metadata */
+	ret = dbox_file_open(file, &deleted);
+	if (ret > 0) {
+		if (deleted)
+			return 0;
+		if ((ret = dbox_file_seek(file, 0)) > 0)
+			ret = dbox_file_metadata_read(file);
+	}
+	if (ret <= 0) {
+		if (ret < 0)
+			return -1;
+		/* corrupted file. we're deleting it anyway. */
+		line = NULL;
+	} else {
+		line = dbox_file_metadata_get(file, DBOX_METADATA_EXT_REF);
+	}
+	if (line == NULL) {
+		/* no attachments */
+		return dbox_file_unlink(file);
+	}
+
+	pool = pool_alloconly_create("sdbox attachment delete", 1024);
+	p_array_init(&extrefs, pool, 16);
+	if (!dbox_attachment_parse_extref(line, pool, &extrefs))
+		array_clear(&extrefs);
+
+	/* try to delete the file first, so if it fails we don't have
+	   missing attachments */
+	if (dbox_file_unlink(file) < 0)
+		ret = -1;
+	else {
+		/* if deleting any attachment fails, we can't do anything else
+		   but ignore it, since the main main mail file is already
+		   deleted */
+		array_foreach(&extrefs, extref) {
+			(void)index_attachment_delete(&storage->storage,
+						      storage->attachment_fs,
+						      extref->path);
+		}
+	}
+	pool_unref(&pool);
+	return 0;
+}
diff -r 968a4dd6240a -r 75e4f4a86cb3 src/lib-storage/index/dbox-single/sdbox-file.h
--- a/src/lib-storage/index/dbox-single/sdbox-file.h	Tue Aug 24 17:03:40 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-file.h	Thu Aug 26 18:16:04 2010 +0100
@@ -21,5 +21,7 @@
 			 bool parents);
 /* Move the file to alt path or back. */
 int sdbox_file_move(struct dbox_file *file, bool alt_path);
+/* Unlink file and all of its referenced attachments. */
+int sdbox_file_unlink_with_attachments(struct dbox_file *file);
 
 #endif
diff -r 968a4dd6240a -r 75e4f4a86cb3 src/lib-storage/index/dbox-single/sdbox-storage.c
--- a/src/lib-storage/index/dbox-single/sdbox-storage.c	Tue Aug 24 17:03:40 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.c	Thu Aug 26 18:16:04 2010 +0100
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "master-service.h"
 #include "mail-index-modseq.h"
+#include "mail-search-build.h"
 #include "mailbox-list-private.h"
 #include "dbox-mail.h"
 #include "dbox-save.h"
@@ -217,6 +218,46 @@
 	index_storage_mailbox_close(box);
 }
 
+static int sdbox_mailbox_delete(struct mailbox *box)
+{
+	struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
+	struct mail_search_context *ctx;
+        struct mailbox_transaction_context *t;
+	struct mail *mail;
+	struct mail_search_args *search_args;
+	struct dbox_file *file;
+
+	if (!box->opened || mbox->storage->storage.attachment_dir == NULL)
+		return index_storage_mailbox_delete(box);
+
+	/* mark the mailbox deleted to avoid race conditions */
+	if (mailbox_mark_index_deleted(box, TRUE) < 0)
+		return -1;
+
+	/* ulink all dbox mails and their attachements in the mailbox. */
+	t = mailbox_transaction_begin(box, 0);
+
+	search_args = mail_search_build_init();
+	mail_search_build_add_all(search_args);
+	ctx = mailbox_search_init(t, search_args, NULL);
+	mail_search_args_unref(&search_args);
+
+	mail = mail_alloc(t, 0, NULL);
+	while (mailbox_search_next(ctx, mail)) {
+		file = sdbox_file_init(mbox, mail->uid);
+		(void)sdbox_file_unlink_with_attachments(file);
+		dbox_file_unref(&file);
+	}
+	mail_free(&mail);
+
+	if (mailbox_search_deinit(&ctx) < 0) {
+		/* maybe we missed some mails. oh well, can't help it. */
+	}
+	mailbox_transaction_rollback(&t);
+
+	return index_storage_mailbox_delete(box);
+}
+
 static int
 sdbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
 {
@@ -292,7 +333,7 @@
 		index_storage_mailbox_free,
 		dbox_mailbox_create,
 		dbox_mailbox_update,
-		index_storage_mailbox_delete,
+		sdbox_mailbox_delete,
 		index_storage_mailbox_rename,
 		index_storage_get_status,
 		sdbox_mailbox_get_guid,
diff -r 968a4dd6240a -r 75e4f4a86cb3 src/lib-storage/index/dbox-single/sdbox-sync.c
--- a/src/lib-storage/index/dbox-single/sdbox-sync.c	Tue Aug 24 17:03:40 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-sync.c	Thu Aug 26 18:16:04 2010 +0100
@@ -23,60 +23,6 @@
 	}
 }
 
-static int dbox_sync_file_expunge_with_attachments(struct dbox_file *file)
-{
-	struct dbox_storage *storage = file->storage;
-	ARRAY_TYPE(mail_attachment_extref) extrefs;
-	const struct mail_attachment_extref *extref;
-	const char *line;
-	pool_t pool;
-	bool deleted;
-	int ret;
-
-	/* read the metadata */
-	ret = dbox_file_open(file, &deleted);
-	if (ret > 0) {
-		if (deleted)
-			return 0;
-		if ((ret = dbox_file_seek(file, 0)) > 0)
-			ret = dbox_file_metadata_read(file);
-	}
-	if (ret <= 0) {
-		if (ret < 0)
-			return -1;
-		/* corrupted file. we're deleting it anyway. */
-		line = NULL;
-	} else {
-		line = dbox_file_metadata_get(file, DBOX_METADATA_EXT_REF);
-	}
-	if (line == NULL) {
-		/* no attachments */
-		return dbox_file_unlink(file);
-	}
-
-	pool = pool_alloconly_create("sdbox attachment delete", 1024);
-	p_array_init(&extrefs, pool, 16);
-	if (!dbox_attachment_parse_extref(line, pool, &extrefs))
-		array_clear(&extrefs);
-
-	/* try to delete the file first, so if it fails we don't have
-	   missing attachments */
-	if (dbox_file_unlink(file) < 0)
-		ret = -1;
-	else {
-		/* if deleting any attachment fails, we can't do anything else
-		   but ignore it, since the main main mail file is already
-		   deleted */
-		array_foreach(&extrefs, extref) {
-			(void)index_attachment_delete(&storage->storage,
-						      storage->attachment_fs,
-						      extref->path);
-		}
-	}
-	pool_unref(&pool);
-	return 0;
-}
-
 static void dbox_sync_file_expunge(struct sdbox_sync_context *ctx,
 				   struct dbox_file *file, uint32_t seq)
 {
@@ -90,7 +36,7 @@
 	}
 
 	if (file->storage->attachment_dir != NULL)
-		ret = dbox_sync_file_expunge_with_attachments(file);
+		ret = sdbox_file_unlink_with_attachments(file);
 	else
 		ret = dbox_file_unlink(file);
 	if (ret < 0) {


More information about the dovecot-cvs mailing list