static bool dsync_brain_master_sync_recv_mailbox(struct dsync_brain *brain) { const struct dsync_mailbox *dsync_box; enum dsync_ibc_recv_ret ret; bool resync; i_assert(brain->master_brain); if ((ret = dsync_ibc_recv_mailbox(brain->ibc, &dsync_box)) == 0) return FALSE; if (ret == DSYNC_IBC_RECV_RET_FINISHED) { i_error("Remote sent end-of-list instead of a mailbox"); brain->failed = TRUE; return TRUE; } if (memcmp(dsync_box->mailbox_guid, brain->local_dsync_box.mailbox_guid, sizeof(dsync_box->mailbox_guid)) != 0) { i_error("Remote sent mailbox with a wrong GUID"); brain->failed = TRUE; return TRUE; } if (dsync_box->mailbox_lost) { /* remote lost the mailbox. it's probably already deleted, but verify it on next sync just to be sure */ brain->changes_during_sync = TRUE; brain->require_full_resync = TRUE; dsync_brain_sync_mailbox_deinit(brain); return TRUE; } resync = !dsync_brain_mailbox_update_pre(brain, brain->box, &brain->local_dsync_box, dsync_box); if (!dsync_boxes_need_sync(brain, &brain->local_dsync_box, dsync_box)) { /* no fields appear to have changed, skip this mailbox */ dsync_brain_sync_mailbox_deinit(brain); return TRUE; } if ((ret = dsync_brain_sync_mailbox_open(brain, dsync_box)) < 0) return TRUE; if (ret == 0 || resync) { brain->changes_during_sync = TRUE; brain->require_full_resync = TRUE; brain->failed = TRUE; dsync_brain_sync_mailbox_deinit(brain); return TRUE; } dsync_brain_sync_init_box_states(brain); return TRUE; }
bool dsync_brain_slave_recv_mailbox(struct dsync_brain *brain) { const struct dsync_mailbox *dsync_box; struct dsync_mailbox local_dsync_box; struct mailbox *box; int ret; i_assert(!brain->master_brain); i_assert(brain->box == NULL); if ((ret = dsync_ibc_recv_mailbox(brain->ibc, &dsync_box)) == 0) return FALSE; if (ret < 0) { brain->state = DSYNC_STATE_DONE; return TRUE; } if (dsync_brain_mailbox_alloc(brain, dsync_box->mailbox_guid, &box) < 0) { i_assert(brain->failed); return TRUE; } if (box == NULL) { /* mailbox was probably deleted/renamed during sync */ //FIXME: verify this from log, and if not log an error. brain->changes_during_sync = TRUE; dsync_brain_slave_send_mailbox_lost(brain, dsync_box); return TRUE; } if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { i_error("Can't sync mailbox %s: %s", mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); mailbox_free(&box); brain->failed = TRUE; return TRUE; } if ((ret = dsync_box_get(box, &local_dsync_box)) <= 0) { mailbox_free(&box); if (ret < 0) { brain->failed = TRUE; return TRUE; } /* another process just deleted this mailbox? */ dsync_brain_slave_send_mailbox_lost(brain, dsync_box); return TRUE; } i_assert(local_dsync_box.uid_validity != 0); i_assert(memcmp(dsync_box->mailbox_guid, local_dsync_box.mailbox_guid, sizeof(dsync_box->mailbox_guid)) == 0); dsync_ibc_send_mailbox(brain->ibc, &local_dsync_box); dsync_brain_mailbox_update_pre(brain, box, &local_dsync_box, dsync_box); if (brain->sync_type == DSYNC_BRAIN_SYNC_TYPE_CHANGED && !dsync_boxes_need_sync(&local_dsync_box, dsync_box)) { /* no fields appear to have changed, skip this mailbox */ mailbox_free(&box); return TRUE; } /* start export/import */ dsync_brain_sync_mailbox_init(brain, box, &local_dsync_box, FALSE); if (dsync_brain_sync_mailbox_open(brain, dsync_box) < 0) return TRUE; brain->state = DSYNC_STATE_SYNC_MAILS; return TRUE; }
bool dsync_brain_slave_recv_mailbox(struct dsync_brain *brain) { const struct dsync_mailbox *dsync_box; struct dsync_mailbox local_dsync_box; struct mailbox *box; const char *error; int ret; i_assert(!brain->master_brain); i_assert(brain->box == NULL); if ((ret = dsync_ibc_recv_mailbox(brain->ibc, &dsync_box)) == 0) return FALSE; if (ret < 0) { brain->state = DSYNC_STATE_DONE; return TRUE; } if (dsync_brain_mailbox_alloc(brain, dsync_box->mailbox_guid, &box, &error) < 0) { i_error("Couldn't allocate mailbox GUID %s: %s", guid_128_to_string(dsync_box->mailbox_guid), error); i_assert(brain->failed); return TRUE; } if (box == NULL) { /* mailbox was probably deleted/renamed during sync */ if (brain->backup_send && brain->no_backup_overwrite) { if (brain->debug) { i_debug("brain %c: Ignore nonexistent " "mailbox GUID %s with -1 sync", brain->master_brain ? 'M' : 'S', guid_128_to_string(dsync_box->mailbox_guid)); } dsync_brain_slave_send_mailbox_lost(brain, dsync_box); return TRUE; } //FIXME: verify this from log, and if not log an error. if (brain->debug) { i_debug("brain %c: Change during sync: " "Mailbox GUID %s was lost", brain->master_brain ? 'M' : 'S', guid_128_to_string(dsync_box->mailbox_guid)); } brain->changes_during_sync = TRUE; dsync_brain_slave_send_mailbox_lost(brain, dsync_box); return TRUE; } if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) { i_error("Can't sync mailbox %s: %s", mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); mailbox_free(&box); brain->failed = TRUE; return TRUE; } if ((ret = dsync_box_get(box, &local_dsync_box)) <= 0) { mailbox_free(&box); if (ret < 0) { brain->failed = TRUE; return TRUE; } /* another process just deleted this mailbox? */ dsync_brain_slave_send_mailbox_lost(brain, dsync_box); return TRUE; } i_assert(local_dsync_box.uid_validity != 0); i_assert(memcmp(dsync_box->mailbox_guid, local_dsync_box.mailbox_guid, sizeof(dsync_box->mailbox_guid)) == 0); dsync_ibc_send_mailbox(brain->ibc, &local_dsync_box); dsync_brain_mailbox_update_pre(brain, box, &local_dsync_box, dsync_box); if (!dsync_boxes_need_sync(brain, &local_dsync_box, dsync_box)) { /* no fields appear to have changed, skip this mailbox */ mailbox_free(&box); return TRUE; } /* start export/import */ dsync_brain_sync_mailbox_init(brain, box, &local_dsync_box, FALSE); if (dsync_brain_sync_mailbox_open(brain, dsync_box) < 0) return TRUE; brain->state = DSYNC_STATE_SYNC_MAILS; return TRUE; }