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