dovecot-2.0: Added support for mailbox GUIDs.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jun 16 00:37:49 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/f98ec5dffd04
changeset: 9471:f98ec5dffd04
user: Timo Sirainen <tss at iki.fi>
date: Mon Jun 15 17:37:15 2009 -0400
description:
Added support for mailbox GUIDs.
diffstat:
15 files changed, 287 insertions(+), 125 deletions(-)
src/lib-storage/index/dbox/dbox-mail.c | 14 --
src/lib-storage/index/dbox/dbox-save.c | 26 -----
src/lib-storage/index/dbox/dbox-storage.c | 108 +++++++++++++++++++--
src/lib-storage/index/dbox/dbox-storage.h | 8 +
src/lib-storage/index/dbox/dbox-sync-rebuild.c | 26 +----
src/lib-storage/index/dbox/dbox-sync.c | 35 +-----
src/lib-storage/index/index-storage.c | 1
src/lib-storage/index/maildir/maildir-storage.c | 15 ++
src/lib-storage/index/maildir/maildir-uidlist.c | 118 +++++++++++++++++------
src/lib-storage/index/maildir/maildir-uidlist.h | 5
src/lib-storage/index/mbox/mbox-storage.c | 15 ++
src/lib-storage/index/mbox/mbox-storage.h | 1
src/lib-storage/index/mbox/mbox-sync.c | 19 +++
src/lib-storage/mail-storage.h | 5
src/util/idxview.c | 16 ++-
diffs (truncated from 787 to 300 lines):
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-mail.c
--- a/src/lib-storage/index/dbox/dbox-mail.c Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-mail.c Mon Jun 15 17:37:15 2009 -0400
@@ -49,9 +49,8 @@ int dbox_mail_lookup(struct dbox_mailbox
uint32_t seq, uint32_t *map_uid_r)
{
const struct dbox_mail_index_record *dbox_rec;
- const struct dbox_index_header *hdr;
+ struct dbox_index_header hdr;
const void *data;
- size_t data_size;
uint32_t cur_map_uid_validity;
bool expunged;
@@ -63,18 +62,11 @@ int dbox_mail_lookup(struct dbox_mailbox
}
if (mbox->map_uid_validity == 0) {
- mail_index_get_header_ext(mbox->ibox.view,
- mbox->dbox_hdr_ext_id,
- &data, &data_size);
- if (data_size != sizeof(*hdr)) {
- mail_storage_set_critical(&mbox->storage->storage,
- "dbox %s: Invalid dbox header size",
- mbox->ibox.box.path);
+ if (dbox_read_header(mbox, &hdr) < 0) {
mbox->storage->sync_rebuild = TRUE;
return -1;
}
- hdr = data;
- mbox->map_uid_validity = hdr->map_uid_validity;
+ mbox->map_uid_validity = hdr.map_uid_validity;
}
if (dbox_map_open(mbox->storage->map, TRUE) < 0)
return -1;
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-save.c
--- a/src/lib-storage/index/dbox/dbox-save.c Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-save.c Mon Jun 15 17:37:15 2009 -0400
@@ -319,30 +319,6 @@ void dbox_save_cancel(struct mail_save_c
(void)dbox_save_finish(_ctx);
}
-static void dbox_add_missing_map_uidvalidity(struct dbox_save_context *ctx)
-{
- const struct dbox_index_header *hdr;
- struct dbox_index_header new_hdr;
- const void *data;
- size_t data_size;
-
- mail_index_get_header_ext(ctx->mbox->ibox.view,
- ctx->mbox->dbox_hdr_ext_id,
- &data, &data_size);
- if (data_size == sizeof(*hdr)) {
- hdr = data;
- if (hdr->map_uid_validity != 0)
- return;
- new_hdr = *hdr;
- } else {
- memset(&new_hdr, 0, sizeof(new_hdr));
- }
- new_hdr.map_uid_validity =
- dbox_map_get_uid_validity(ctx->mbox->storage->map);
- mail_index_update_header_ext(ctx->trans, ctx->mbox->dbox_hdr_ext_id, 0,
- &new_hdr, sizeof(new_hdr));
-}
-
int dbox_transaction_save_commit_pre(struct dbox_save_context *ctx)
{
struct dbox_transaction_context *t =
@@ -392,7 +368,7 @@ int dbox_transaction_save_commit_pre(str
unsigned int i, count;
uint32_t next_map_uid = first_map_uid;
- dbox_add_missing_map_uidvalidity(ctx);
+ dbox_update_header(ctx->mbox, ctx->trans);
memset(&rec, 0, sizeof(rec));
rec.save_date = ioloop_time;
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-storage.c Mon Jun 15 17:37:15 2009 -0400
@@ -191,23 +191,72 @@ uint32_t dbox_get_uidvalidity_next(struc
return mailbox_uidvalidity_next(path);
}
+static bool
+dbox_index_header_has_mailbox_guid(const struct dbox_index_header *hdr)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(hdr->mailbox_guid); i++) {
+ if (hdr->mailbox_guid[i] != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void dbox_set_mailbox_guid(struct dbox_index_header *hdr)
+{
+ if (!dbox_index_header_has_mailbox_guid(hdr))
+ mail_generate_guid_128(hdr->mailbox_guid);
+}
+
+int dbox_read_header(struct dbox_mailbox *mbox, struct dbox_index_header *hdr)
+{
+ const void *data;
+ size_t data_size;
+
+ mail_index_get_header_ext(mbox->ibox.view, mbox->dbox_hdr_ext_id,
+ &data, &data_size);
+ if (data_size < DBOX_INDEX_HEADER_MIN_SIZE &&
+ (!mbox->creating || data_size != 0)) {
+ mail_storage_set_critical(&mbox->storage->storage,
+ "dbox %s: Invalid dbox header size",
+ mbox->ibox.box.path);
+ return -1;
+ }
+ memset(hdr, 0, sizeof(*hdr));
+ memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
+ return 0;
+}
+
+void dbox_update_header(struct dbox_mailbox *mbox,
+ struct mail_index_transaction *trans)
+{
+ struct dbox_index_header hdr, new_hdr;
+
+ if (dbox_read_header(mbox, &hdr) < 0)
+ memset(&hdr, 0, sizeof(hdr));
+
+ new_hdr = hdr;
+ dbox_set_mailbox_guid(&new_hdr);
+ new_hdr.map_uid_validity =
+ dbox_map_get_uid_validity(mbox->storage->map);
+ if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
+ mail_index_update_header_ext(trans, mbox->dbox_hdr_ext_id, 0,
+ &new_hdr, sizeof(new_hdr));
+ }
+}
+
static int dbox_write_index_header(struct mailbox *box)
{
struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
struct mail_index_transaction *trans;
- struct dbox_index_header hdr;
uint32_t uid_validity;
if (dbox_map_open(mbox->storage->map, TRUE) < 0)
return -1;
trans = mail_index_transaction_begin(mbox->ibox.view, 0);
-
- /* set dbox header */
- memset(&hdr, 0, sizeof(hdr));
- hdr.map_uid_validity = dbox_map_get_uid_validity(mbox->storage->map);
- mail_index_update_header_ext(trans, mbox->dbox_hdr_ext_id, 0,
- &hdr, sizeof(hdr));
+ dbox_update_header(mbox, trans);
/* set uidvalidity */
uid_validity = dbox_get_uidvalidity_next(box->list);
@@ -215,20 +264,30 @@ static int dbox_write_index_header(struc
offsetof(struct mail_index_header, uid_validity),
&uid_validity, sizeof(uid_validity), TRUE);
- return mail_index_transaction_commit(&trans);
+ if (mail_index_transaction_commit(&trans) < 0) {
+ mail_storage_set_internal_error(box->storage);
+ mail_index_reset_error(mbox->ibox.index);
+ return -1;
+ }
+ return 0;
}
static int create_dbox(struct mailbox *box)
{
+ struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
mode_t mode;
gid_t gid;
+ int ret;
mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid);
if (mkdir_parents_chown(box->path, mode, (uid_t)-1, gid) == 0) {
/* create indexes immediately with the dbox header */
if (index_storage_mailbox_open(box) < 0)
return -1;
- if (dbox_write_index_header(box) < 0)
+ mbox->creating = TRUE;
+ ret = dbox_write_index_header(box);
+ mbox->creating = FALSE;
+ if (ret < 0)
return -1;
} else if (errno != EEXIST) {
if (!mail_storage_set_error_from_errno(box->storage)) {
@@ -303,6 +362,35 @@ static void dbox_mailbox_close(struct ma
maildir_uidlist_deinit(&mbox->maildir_uidlist);
index_storage_mailbox_close(box);
+}
+
+static void dbox_storage_get_status_guid(struct mailbox *box,
+ struct mailbox_status *status_r)
+{
+ struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
+ struct dbox_index_header hdr;
+
+ if (dbox_read_header(mbox, &hdr) < 0)
+ memset(&hdr, 0, sizeof(hdr));
+
+ if (!dbox_index_header_has_mailbox_guid(&hdr)) {
+ /* regenerate it */
+ if (dbox_write_index_header(box) < 0 ||
+ dbox_read_header(mbox, &hdr) < 0)
+ return;
+ }
+ memcpy(status_r->mailbox_guid, hdr.mailbox_guid,
+ sizeof(status_r->mailbox_guid));
+}
+
+static void
+dbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
+ struct mailbox_status *status_r)
+{
+ index_storage_get_status(box, items, status_r);
+
+ if ((items & STATUS_GUID) != 0)
+ dbox_storage_get_status_guid(box, status_r);
}
static int
@@ -776,7 +864,7 @@ struct mailbox dbox_mailbox = {
index_storage_mailbox_enable,
dbox_mailbox_open,
dbox_mailbox_close,
- index_storage_get_status,
+ dbox_storage_get_status,
NULL,
NULL,
dbox_storage_sync_init,
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-storage.h
--- a/src/lib-storage/index/dbox/dbox-storage.h Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-storage.h Mon Jun 15 17:37:15 2009 -0400
@@ -30,9 +30,11 @@
/* Flag specifies if the message should be in primary or alternative storage */
#define DBOX_INDEX_FLAG_ALT MAIL_INDEX_MAIL_FLAG_BACKEND
+#define DBOX_INDEX_HEADER_MIN_SIZE (sizeof(uint32_t))
struct dbox_index_header {
uint32_t map_uid_validity;
uint32_t highest_maildir_uid;
+ uint8_t mailbox_guid[MAILBOX_GUID_SIZE];
};
struct dbox_storage {
@@ -74,6 +76,8 @@ struct dbox_mailbox {
uint32_t dbox_ext_id, dbox_hdr_ext_id, guid_ext_id;
const char *alt_path;
+
+ unsigned int creating:1;
};
struct dbox_transaction_context {
@@ -104,6 +108,10 @@ int dbox_mail_lookup(struct dbox_mailbox
int dbox_mail_lookup(struct dbox_mailbox *mbox, struct mail_index_view *view,
uint32_t seq, uint32_t *map_uid_r);
uint32_t dbox_get_uidvalidity_next(struct mailbox_list *list);
+void dbox_set_mailbox_guid(struct dbox_index_header *hdr);
+int dbox_read_header(struct dbox_mailbox *mbox, struct dbox_index_header *hdr);
+void dbox_update_header(struct dbox_mailbox *mbox,
+ struct mail_index_transaction *trans);
struct mail_save_context *
dbox_save_alloc(struct mailbox_transaction_context *_t);
diff -r c0dd791aaaaa -r f98ec5dffd04 src/lib-storage/index/dbox/dbox-sync-rebuild.c
--- a/src/lib-storage/index/dbox/dbox-sync-rebuild.c Mon Jun 15 17:35:28 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-sync-rebuild.c Mon Jun 15 17:37:15 2009 -0400
@@ -348,25 +348,17 @@ static int dbox_sync_maildir_finish(stru
static void dbox_sync_update_header(struct dbox_sync_rebuild_context *ctx)
{
- const struct dbox_index_header *hdr;
- struct dbox_index_header new_hdr;
- const void *data;
- size_t data_size;
-
- mail_index_get_header_ext(ctx->mbox->ibox.view,
- ctx->mbox->dbox_hdr_ext_id,
- &data, &data_size);
- hdr = data;
- if (data_size == sizeof(*hdr))
- new_hdr = *hdr;
- else
- memset(&new_hdr, 0, sizeof(new_hdr));
- if (new_hdr.highest_maildir_uid < ctx->mbox->highest_maildir_uid)
- new_hdr.highest_maildir_uid = ctx->mbox->highest_maildir_uid;
- new_hdr.map_uid_validity = !ctx->storage_rebuild ? 0 :
+ struct dbox_index_header hdr;
+
+ if (dbox_read_header(ctx->mbox, &hdr) < 0)
More information about the dovecot-cvs
mailing list