virtual-sync.c revision 3e1d94509fd76c56f2eb54f98ea02ade9ac2d44a
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2008-2014 Dovecot authors, see the included COPYING file */
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen const char *const *kw_all;
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainen /* messages expunged within this sync */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstatic void virtual_sync_set_uidvalidity(struct virtual_sync_context *ctx)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen offsetof(struct mail_index_header, uid_validity),
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstatic void virtual_sync_external_flags(struct virtual_sync_context *ctx,
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainen const char *const *kw_names;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (!mail_set_uid(bbox->sync_mail, real_uid)) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen /* copy flags */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen mail_index_update_flags(ctx->trans, vseq, MODIFY_REPLACE, flags);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* copy keywords */
7d87a87b360ecac47fe10e7ca5c7e1433dd63004Timo Sirainen kw_names = mail_get_keywords(bbox->sync_mail);
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainen keywords = mail_index_keywords_create(ctx->index, kw_names);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen mail_index_update_keywords(ctx->trans, vseq, MODIFY_REPLACE, keywords);
7d87a87b360ecac47fe10e7ca5c7e1433dd63004Timo Sirainenstatic int virtual_sync_mail_cmp(const void *p1, const void *p2)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const struct virtual_sync_mail *m1 = p1, *m2 = p2;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (m1->vrec.mailbox_id < m2->vrec.mailbox_id)
ef2b2ef2e6a6eb5e4667f2e63faae8a3b646e8baTimo Sirainen if (m1->vrec.mailbox_id > m2->vrec.mailbox_id)
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainenvirtual_backend_box_sync_mail_set(struct virtual_backend_box *bbox)
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen trans = mailbox_transaction_begin(bbox->box, 0);
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainenvirtual_backend_box_sync_mail_unset(struct virtual_backend_box *bbox)
d337f4291d9ea9cd1adee0f468bc0c3baeabb4feTimo Sirainenstatic int bbox_mailbox_id_cmp(struct virtual_backend_box *const *b1,
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainenvirtual_sync_get_backend_box(struct virtual_sync_context *ctx, const char *name,
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen *bbox_r = virtual_backend_box_lookup_name(ctx->mbox, name);
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen if (*bbox_r != NULL || !ctx->mbox->sync_initialized)
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen /* another process just added a new mailbox.
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen we can't handle this currently. */
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen mail_storage_set_error(ctx->mbox->box.storage, MAIL_ERROR_TEMP,
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen "Backend mailbox added by another session. "
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen "Reopen the virtual mailbox.");
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainenstatic int virtual_sync_ext_header_read(struct virtual_sync_context *ctx)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen const char *box_path = mailbox_get_path(&ctx->mbox->box);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen const struct virtual_mail_index_header *ext_hdr;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen const struct virtual_mail_index_mailbox_record *mailboxes;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen unsigned int i, count, ext_name_offset, ext_mailbox_count;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen mail_index_get_header_ext(ctx->sync_view, ctx->mbox->virtual_ext_id,
5a37e34b1b5acf453372cd112c70bb4e46b4bee2Timo Sirainen ctx->mbox->prev_uid_validity == hdr->uid_validity &&
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen ctx->mbox->prev_change_counter == ext_hdr->change_counter) {
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen /* fully refreshed */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen ctx->mbox->prev_uid_validity = hdr->uid_validity;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen ctx->mbox->search_args_crc32 != ext_hdr->search_args_crc32) {
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ctx->mbox->prev_change_counter = ext_hdr->change_counter;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen ext_hdr->mailbox_count > INT_MAX/sizeof(*mailboxes)) {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen i_error("virtual index %s: Broken mailbox_count header",
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen /* update mailbox backends */
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen for (i = 0; i < ext_mailbox_count; i++) {
e5dca7edde333c2759b0e6b1d0d00b94ea303322Timo Sirainen if (mailboxes[i].id > ext_hdr->highest_mailbox_id ||
2521fd0986302cdabc8b0711eef63ac188f32cd6Timo Sirainen i_error("virtual index %s: Broken mailbox id",
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen i_error("virtual index %s: Broken mailbox name_len",
bf9ea5404a0094a8fb8199b677d81f803512c44eTimo Sirainen if (ext_name_offset + mailboxes[i].name_len > ext_size) {
bf9ea5404a0094a8fb8199b677d81f803512c44eTimo Sirainen i_error("virtual index %s: Broken mailbox list",
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen const unsigned char *nameptr;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen nameptr = CONST_PTR_OFFSET(ext_data, ext_name_offset);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen name = t_strndup(nameptr, mailboxes[i].name_len);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (virtual_sync_get_backend_box(ctx, name, &bbox) < 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* mailbox no longer exists. */
66a872b4569c048e804f0731680d89c6042d8890Timo Sirainen bbox->sync_uid_validity = mailboxes[i].uid_validity;
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen ctx->mbox->highest_mailbox_id = ext_hdr == NULL ? 0 :
8552b0cad8ffe9ccb8270577ba28b8010c89af11Timo Sirainen /* assign new mailbox IDs if any are missing */
for (i = 0; i < count; i++) {
ret = 0;
return ret;
const void *ext_data;
for (i = 0; i < count; i++) {
i_assert(i == 0 ||
sizeof(struct virtual_mail_index_record),
sizeof(uint32_t));
const void *data;
if (flags != 0) {
if (flags != 0) {
kw_names);
int ret;
0, NULL);
return ret;
if (uid_count == 0)
i_unreached();
for (i = 0; i < uid_count; i++) {
&vseq))
if (uid_count == 0)
if (rec_count == 0 ||
&dest))
i_unreached();
for (i = 0; i < uid_count; i++) {
unsigned int i, count;
for (i = 0; i < count; i++) {
const void *data;
old_msg_count = 0;
&removed_uids);
unsigned int i, n = 0, count;
if (i == count)
for (; i < count; ) {
unsigned int i, n = 0, count;
for (; i < count; ) {
if (!iter_done) {
&added_uids);
&temp_uids);
&removed_uids);
&removed_uids);
unsigned int *idx1_r,
unsigned int *idx2_r)
&idx);
return FALSE;
return TRUE;
&idx1);
case MAILBOX_SYNC_TYPE_FLAGS:
case MAILBOX_SYNC_TYPE_MODSEQ:
const unsigned int uidval_pos =
unsigned int mailbox_offset;
int ret;
if (bbox_index_opened) {
&status) < 0)
if (!bbox_index_opened) {
} T_END;
return ret;
const void *data;
unsigned int j = 0, uidmap_count = 0;
if (messages == 0)
for (i = 0; i < messages; i++) {
for (; j < uidmap_count; j++) {
&uidmap_count);
for (; j < uidmap_count; j++) {
for (; j < uidmap_count; j++) {
for (i = 0; i < count; i++) {
for (j = 0; j < uidmap_count; j++) {
unsigned int i, count;
i_unreached();
if (count == 0) {
&idx))
i_unreached();
const void *data;
const void *data;
unsigned int i, count;
for (i = 0; i < count; i++) {
unsigned int i, count;
for (i = 0; i < count; i++)
if (success) {
return ret;
int ret;
if (ret <= 0) {
if (ret < 0)
return ret;
if (ret < 0)
if (ret == 0)
struct mailbox_sync_context *
int ret = 0;
return sync_ctx;