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;
}
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;
(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 =
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;
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);
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)) {
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
dbox_mailbox_create(struct mail_storage *storage, struct mailbox_list *list,
const char *name, bool directory)
index_storage_mailbox_enable,
dbox_mailbox_open,
dbox_mailbox_close,
- index_storage_get_status,
+ dbox_storage_get_status,
NULL,
NULL,
dbox_storage_sync_init,
/* 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 {
uint32_t dbox_ext_id, dbox_hdr_ext_id, guid_ext_id;
const char *alt_path;
+
+ unsigned int creating:1;
};
struct dbox_transaction_context {
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);
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)
+ memset(&hdr, 0, sizeof(hdr));
+ dbox_set_mailbox_guid(&hdr);
+ if (hdr.highest_maildir_uid < ctx->mbox->highest_maildir_uid)
+ hdr.highest_maildir_uid = ctx->mbox->highest_maildir_uid;
+ hdr.map_uid_validity = !ctx->storage_rebuild ? 0 :
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));
+ &hdr, sizeof(hdr));
}
struct dbox_sync_rebuild_context *
static int dbox_refresh_header(struct dbox_mailbox *mbox, bool retry)
{
struct mail_index_view *view;
- const struct dbox_index_header *hdr;
- const void *data;
- size_t data_size;
+ struct dbox_index_header hdr;
int ret;
view = mail_index_view_open(mbox->ibox.index);
- mail_index_get_header_ext(view, mbox->dbox_hdr_ext_id,
- &data, &data_size);
- if (data_size != sizeof(*hdr)) {
- if (retry) {
- mail_index_view_close(&view);
- (void)mail_index_refresh(mbox->ibox.index);
- return dbox_refresh_header(mbox, FALSE);
- }
-
- /* data_size=0 means it's never been synced as dbox.
- data_size=4 is for backwards compatibility */
- if (data_size != 0 && data_size != 4) {
- i_warning("dbox %s: Invalid dbox header size",
- mbox->ibox.box.path);
- }
- ret = -1;
- } else {
- hdr = data;
+ ret = dbox_read_header(mbox, &hdr);
+ mail_index_view_close(&view);
- mbox->highest_maildir_uid = hdr->highest_maildir_uid;
+ if (ret == 0) {
+ mbox->highest_maildir_uid = hdr.highest_maildir_uid;
ret = mbox->storage->sync_rebuild ? -1 : 0;
+ } else if (retry) {
+ (void)mail_index_refresh(mbox->ibox.index);
+ return dbox_refresh_header(mbox, FALSE);
}
- mail_index_view_close(&view);
return ret;
}
} else {
match->refcount++;
}
+ i_assert(match->index != NULL);
return match->index;
}
return 0;
}
+static void
+maildir_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
+ struct mailbox_status *status_r)
+{
+ struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
+
+ index_storage_get_status(box, items, status_r);
+ if ((items & STATUS_GUID) != 0) {
+ (void)maildir_uidlist_get_mailbox_guid(mbox->uidlist,
+ status_r->mailbox_guid);
+ }
+}
+
static const char *
maildir_get_unlink_dest(struct mailbox_list *list, const char *name)
{
index_storage_mailbox_enable,
maildir_mailbox_open,
maildir_mailbox_close,
- index_storage_get_status,
+ maildir_storage_get_status,
maildir_list_index_has_changed,
maildir_list_index_update_sync,
maildir_storage_sync_init,
#include "istream.h"
#include "ostream.h"
#include "str.h"
+#include "hex-binary.h"
#include "file-dotlock.h"
#include "close-keep-errno.h"
#include "nfs-workarounds.h"
uoff_t last_read_offset;
string_t *hdr_extensions;
+ uint8_t mailbox_guid[MAILBOX_GUID_SIZE];
+
unsigned int recreate:1;
unsigned int initial_read:1;
unsigned int initial_hdr_read:1;
unsigned int retry_rewind:1;
unsigned int locked_refresh:1;
unsigned int unsorted:1;
+ unsigned int have_mailbox_guid:1;
};
struct maildir_uidlist_sync_ctx {
return TRUE;
}
+static int
+maildir_uidlist_read_v3_header(struct maildir_uidlist *uidlist,
+ const char *line,
+ unsigned int *uid_validity_r,
+ unsigned int *next_uid_r)
+{
+ buffer_t *buf;
+ char key;
+
+ str_truncate(uidlist->hdr_extensions, 0);
+ while (*line != '\0') {
+ const char *value;
+
+ key = *line;
+ value = ++line;
+ while (*line != '\0' && *line != ' ') line++;
+ value = t_strdup_until(value, line);
+
+ switch (key) {
+ case MAILDIR_UIDLIST_HDR_EXT_UID_VALIDITY:
+ *uid_validity_r = strtoul(value, NULL, 10);
+ break;
+ case MAILDIR_UIDLIST_HDR_EXT_NEXT_UID:
+ *next_uid_r = strtoul(value, NULL, 10);
+ break;
+ case MAILDIR_UIDLIST_HDR_EXT_GUID:
+ buf = buffer_create_dynamic(pool_datastack_create(),
+ MAILBOX_GUID_SIZE);
+ if (hex_to_binary(value, buf) < 0 ||
+ buf->used != MAILBOX_GUID_SIZE) {
+ maildir_uidlist_set_corrupted(uidlist,
+ "Invalid mailbox GUID: %s", value);
+ return -1;
+ }
+ memcpy(uidlist->mailbox_guid, buf->data,
+ sizeof(uidlist->mailbox_guid));
+ uidlist->have_mailbox_guid = TRUE;
+ break;
+ default:
+ if (str_len(uidlist->hdr_extensions) > 0)
+ str_append_c(uidlist->hdr_extensions, ' ');
+ str_printfa(uidlist->hdr_extensions,
+ "%c%s", key, value);
+ break;
+ }
+
+ while (*line == ' ') line++;
+ }
+ return 0;
+}
+
static int maildir_uidlist_read_header(struct maildir_uidlist *uidlist,
struct istream *input)
{
unsigned int uid_validity, next_uid;
- string_t *ext_hdr;
const char *line;
- char key;
+ int ret;
line = i_stream_read_next_line(input);
if (line == NULL) {
}
break;
case UIDLIST_VERSION:
- ext_hdr = uidlist->hdr_extensions;
- str_truncate(ext_hdr, 0);
- while (*line != '\0') T_BEGIN {
- const char *value;
-
- key = *line;
- value = ++line;
- while (*line != '\0' && *line != ' ') line++;
- value = t_strdup_until(value, line);
-
- switch (key) {
- case MAILDIR_UIDLIST_HDR_EXT_UID_VALIDITY:
- uid_validity = strtoul(value, NULL, 10);
- break;
- case MAILDIR_UIDLIST_HDR_EXT_NEXT_UID:
- next_uid = strtoul(value, NULL, 10);
- break;
- default:
- if (str_len(ext_hdr) > 0)
- str_append_c(ext_hdr, ' ');
- str_printfa(ext_hdr, "%c%s", key, value);
- break;
- }
-
- while (*line == ' ') line++;
+ T_BEGIN {
+ ret = maildir_uidlist_read_v3_header(uidlist, line,
+ &uid_validity,
+ &next_uid);
} T_END;
+ if (ret < 0)
+ return 0;
break;
default:
maildir_uidlist_set_corrupted(uidlist, "Unsupported version %u",
uidlist->initial_hdr_read = TRUE;
if (UIDLIST_IS_LOCKED(uidlist))
uidlist->locked_refresh = TRUE;
+ if (!uidlist->have_mailbox_guid) {
+ uidlist->recreate = TRUE;
+ (void)maildir_uidlist_update(uidlist);
+ }
}
return ret;
}
return !uidlist->initial_hdr_read ? 0 : uidlist->next_uid;
}
+int maildir_uidlist_get_mailbox_guid(struct maildir_uidlist *uidlist,
+ uint8_t mailbox_guid[MAILBOX_GUID_SIZE])
+{
+ if (!uidlist->have_mailbox_guid) {
+ uidlist->recreate = TRUE;
+ if (maildir_uidlist_update(uidlist) < 0)
+ return -1;
+ }
+ memcpy(mailbox_guid, uidlist->mailbox_guid, MAILBOX_GUID_SIZE);
+ return 0;
+}
+
void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist,
uint32_t uid_validity)
{
i_assert(first_idx == 0);
uidlist->version = UIDLIST_VERSION;
+ if (!uidlist->have_mailbox_guid)
+ mail_generate_guid_128(uidlist->mailbox_guid);
+
i_assert(uidlist->uid_validity != 0);
i_assert(uidlist->next_uid > 0);
- str_printfa(str, "%u V%u N%u", uidlist->version,
- uidlist->uid_validity, uidlist->next_uid);
+ str_printfa(str, "%u V%u N%u G%s", uidlist->version,
+ uidlist->uid_validity, uidlist->next_uid,
+ binary_to_hex(uidlist->mailbox_guid,
+ sizeof(uidlist->mailbox_guid)));
if (str_len(uidlist->hdr_extensions) > 0) {
str_append_c(str, ' ');
str_append_str(str, uidlist->hdr_extensions);
uidlist->fd_size = st.st_size;
uidlist->last_read_offset = st.st_size;
uidlist->recreate = FALSE;
+ uidlist->have_mailbox_guid = TRUE;
maildir_uidlist_update_hdr(uidlist, &st);
}
if (ret < 0)
if (ctx->finish_change_counter != uidlist->change_counter)
return TRUE;
- if (uidlist->fd == -1 || uidlist->version != UIDLIST_VERSION)
+ if (uidlist->fd == -1 || uidlist->version != UIDLIST_VERSION ||
+ !uidlist->have_mailbox_guid)
return TRUE;
return maildir_uidlist_want_compress(ctx);
}
#ifndef MAILDIR_UIDLIST_H
#define MAILDIR_UIDLIST_H
+#include "mail-storage.h"
+
#define MAILDIR_UIDLIST_NAME "dovecot-uidlist"
/* how many seconds to wait before overriding uidlist.lock */
#define MAILDIR_UIDLIST_LOCK_STALE_TIMEOUT (60*2)
enum maildir_uidlist_hdr_ext_key {
MAILDIR_UIDLIST_HDR_EXT_UID_VALIDITY = 'V',
MAILDIR_UIDLIST_HDR_EXT_NEXT_UID = 'N',
+ MAILDIR_UIDLIST_HDR_EXT_GUID = 'G',
/* POP3 UIDL format unless overridden by records */
MAILDIR_UIDLIST_HDR_EXT_POP3_UIDL_FORMAT = 'P'
};
uint32_t maildir_uidlist_get_uid_validity(struct maildir_uidlist *uidlist);
uint32_t maildir_uidlist_get_next_uid(struct maildir_uidlist *uidlist);
+int maildir_uidlist_get_mailbox_guid(struct maildir_uidlist *uidlist,
+ uint8_t mailbox_guid[MAILBOX_GUID_SIZE]);
void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist,
uint32_t uid_validity);
index_storage_mailbox_close(box);
}
+static void
+mbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
+ struct mailbox_status *status_r)
+{
+ struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
+
+ index_storage_get_status(box, items, status_r);
+ if ((items & STATUS_GUID) != 0) {
+ memcpy(status_r->mailbox_guid, mbox->mbox_hdr.mailbox_guid,
+ sizeof(status_r->mailbox_guid));
+ }
+}
+
static void mbox_notify_changes(struct mailbox *box)
{
struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
index_storage_mailbox_enable,
mbox_mailbox_open,
mbox_mailbox_close,
- index_storage_get_status,
+ mbox_storage_get_status,
NULL,
NULL,
mbox_storage_sync_init,
uint32_t sync_mtime;
uint8_t dirty_flag;
uint8_t unused[3];
+ uint8_t mailbox_guid[MAILBOX_GUID_SIZE];
};
struct mbox_storage {
struct mail_storage storage;
return 0;
}
+static bool mbox_has_mailbox_guid(struct mbox_mailbox *mbox)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(mbox->mbox_hdr.mailbox_guid); i++) {
+ if (mbox->mbox_hdr.mailbox_guid[i] != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
static void
mbox_sync_index_update_ext_header(struct mbox_sync_context *sync_ctx)
{
const void *data;
size_t data_size;
+ if (!mbox_has_mailbox_guid(mbox))
+ mail_generate_guid_128(mbox->mbox_hdr.mailbox_guid);
+
mail_index_get_header_ext(mbox->ibox.view, mbox->mbox_ext_idx,
&data, &data_size);
if (data_size != sizeof(mbox->mbox_hdr) ||
if (mbox_sync_header_refresh(mbox) < 0)
return -1;
+ if (!mbox_has_mailbox_guid(mbox)) {
+ /* need to assign mailbox GUID */
+ return 1;
+ }
+
if ((uint32_t)st->st_mtime == mbox->mbox_hdr.sync_mtime &&
(uint64_t)st->st_size == mbox->mbox_hdr.sync_size) {
/* fully synced */
STATUS_UNSEEN = 0x10,
STATUS_FIRST_UNSEEN_SEQ = 0x20,
STATUS_KEYWORDS = 0x40,
- STATUS_HIGHESTMODSEQ = 0x80
+ STATUS_HIGHESTMODSEQ = 0x80,
+ STATUS_GUID = 0x100
};
enum mailbox_search_result_flags {
struct mailbox;
struct mailbox_transaction_context;
+#define MAILBOX_GUID_SIZE 16
struct mailbox_status {
uint32_t messages;
uint32_t recent;
uint32_t first_unseen_seq;
uint64_t highest_modseq;
+ uint8_t mailbox_guid[MAILBOX_GUID_SIZE];
const ARRAY_TYPE(keywords) *keywords;
uint32_t sync_mtime;
uint8_t dirty_flag;
uint8_t unused[3];
+ uint8_t mailbox_guid[16];
};
struct dbox_index_header {
uint32_t map_uid_validity;
uint32_t highest_maildir_uid;
+ uint8_t mailbox_guid[16];
};
struct dbox_mail_index_record {
uint32_t map_uid;
const struct mbox_index_header *hdr = data;
printf("header\n");
- printf(" - sync_mtime = %s\n", unixdate2str(hdr->sync_mtime));
- printf(" - sync_size = %llu\n",
+ printf(" - sync_mtime . = %s\n", unixdate2str(hdr->sync_mtime));
+ printf(" - sync_size .. = %llu\n",
(unsigned long long)hdr->sync_size);
- printf(" - dirty_flag = %d\n", hdr->dirty_flag);
+ printf(" - dirty_flag . = %d\n", hdr->dirty_flag);
+ printf(" - mailbox_guid = %s\n",
+ binary_to_hex(hdr->mailbox_guid,
+ sizeof(hdr->mailbox_guid)));
} else if (strcmp(ext->name, "dbox-hdr") == 0) {
const struct dbox_index_header *hdr = data;
printf("header\n");
- printf(" - map_uid_validity = %u\n", hdr->map_uid_validity);
+ printf(" - map_uid_validity .. = %u\n", hdr->map_uid_validity);
printf(" - highest_maildir_uid = %u\n", hdr->highest_maildir_uid);
+ printf(" - mailbox_guid ...... = %s\n",
+ binary_to_hex(hdr->mailbox_guid,
+ sizeof(hdr->mailbox_guid)));
} else if (strcmp(ext->name, "modseq") == 0) {
const struct mail_index_modseq_header *hdr = data;