Beispiel #1
0
static void
dsync_brain_sync_mailbox_init(struct dsync_brain *brain,
			      struct mailbox *box,
			      const struct dsync_mailbox *local_dsync_box,
			      bool wait_for_remote_box)
{
	const struct dsync_mailbox_state *state;

	i_assert(brain->box_importer == NULL);
	i_assert(brain->box_exporter == NULL);
	i_assert(box->synced);

	brain->box = box;
	brain->pre_box_state = brain->state;
	if (wait_for_remote_box) {
		brain->box_send_state = DSYNC_BOX_STATE_MAILBOX;
		brain->box_recv_state = DSYNC_BOX_STATE_MAILBOX;
	} else {
		dsync_brain_sync_init_box_states(brain);
	}
	brain->local_dsync_box = *local_dsync_box;
	memset(&brain->remote_dsync_box, 0, sizeof(brain->remote_dsync_box));

	state = dsync_mailbox_state_find(brain, local_dsync_box->mailbox_guid);
	if (state != NULL)
		brain->mailbox_state = *state;
	else {
		memset(&brain->mailbox_state, 0, sizeof(brain->mailbox_state));
		memcpy(brain->mailbox_state.mailbox_guid,
		       local_dsync_box->mailbox_guid,
		       sizeof(brain->mailbox_state.mailbox_guid));
		brain->mailbox_state.last_uidvalidity =
			local_dsync_box->uid_validity;
	}
}
static void
dsync_brain_sync_mailbox_init_remote(struct dsync_brain *brain,
				     const struct dsync_mailbox *remote_dsync_box)
{
	enum dsync_mailbox_import_flags import_flags = 0;
	const struct dsync_mailbox_state *state;
	uint32_t last_common_uid;
	uint64_t last_common_modseq, last_common_pvt_modseq;

	i_assert(brain->box_importer == NULL);
	i_assert(brain->log_scan != NULL);

	i_assert(memcmp(brain->local_dsync_box.mailbox_guid,
			remote_dsync_box->mailbox_guid,
			sizeof(remote_dsync_box->mailbox_guid)) == 0);

	brain->remote_dsync_box = *remote_dsync_box;

	state = dsync_mailbox_state_find(brain, remote_dsync_box->mailbox_guid);
	if (state != NULL) {
		last_common_uid = state->last_common_uid;
		last_common_modseq = state->last_common_modseq;
		last_common_pvt_modseq = state->last_common_pvt_modseq;
	} else {
		last_common_uid = 0;
		last_common_modseq = 0;
		last_common_pvt_modseq = 0;
	}

	if (brain->mail_requests)
		import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_WANT_MAIL_REQUESTS;
	if (brain->master_brain)
		import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MASTER_BRAIN;
	if (brain->backup_recv && !brain->no_backup_overwrite)
		import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_REVERT_LOCAL_CHANGES;
	if (brain->debug)
		import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_DEBUG;
	if (brain->local_dsync_box.have_save_guids &&
	    (remote_dsync_box->have_save_guids ||
	     (brain->backup_recv && remote_dsync_box->have_guids)))
		import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_HAVE_GUIDS;
	if (brain->local_dsync_box.have_only_guid128 ||
	    remote_dsync_box->have_only_guid128)
		import_flags |= DSYNC_MAILBOX_IMPORT_FLAG_MAILS_USE_GUID128;

	brain->box_importer = brain->backup_send ? NULL :
		dsync_mailbox_import_init(brain->box, brain->log_scan,
					  last_common_uid, last_common_modseq,
					  last_common_pvt_modseq,
					  remote_dsync_box->uid_next,
					  remote_dsync_box->first_recent_uid,
					  remote_dsync_box->highest_modseq,
					  remote_dsync_box->highest_pvt_modseq,
					  import_flags);
}
Beispiel #3
0
static bool
dsync_brain_has_mailbox_state_changed(struct dsync_brain *brain,
				      const struct dsync_mailbox *dsync_box)
{
	const struct dsync_mailbox_state *state;

	if (brain->sync_type != DSYNC_BRAIN_SYNC_TYPE_STATE)
		return TRUE;

	state = dsync_mailbox_state_find(brain, dsync_box->mailbox_guid);
	return state == NULL ||
		state->last_uidvalidity != dsync_box->uid_validity ||
		state->last_common_uid+1 != dsync_box->uid_next ||
		state->last_common_modseq != dsync_box->highest_modseq ||
		state->last_common_pvt_modseq != dsync_box->highest_pvt_modseq;
}
Beispiel #4
0
void dsync_brain_mailbox_update_pre(struct dsync_brain *brain,
				    struct mailbox *box,
				    const struct dsync_mailbox *local_box,
				    const struct dsync_mailbox *remote_box)
{
	struct mailbox_update update;
	const struct dsync_mailbox_state *state;

	memset(&update, 0, sizeof(update));

	if (local_box->uid_validity != remote_box->uid_validity) {
		/* Keep the UIDVALIDITY for the mailbox that has more
		   messages. If they equal, use the higher UIDVALIDITY. */
		if (remote_box->messages_count > local_box->messages_count ||
		    (remote_box->messages_count == local_box->messages_count &&
		     remote_box->uid_validity > local_box->uid_validity))
			update.uid_validity = remote_box->uid_validity;

		state = dsync_mailbox_state_find(brain, local_box->mailbox_guid);
		if (state != NULL && state->last_common_uid > 0) {
			/* we can't continue syncing this mailbox in this
			   session, because the other side already started
			   sending mailbox changes, but not for all mails. */
			dsync_mailbox_state_remove(brain, local_box->mailbox_guid);
			// FIXME: handle this properly
		}
	}

	dsync_cache_fields_update(local_box, remote_box, &update);

	if (update.uid_validity == 0 &&
	    update.cache_updates == NULL) {
		/* no changes */
		return;
	}

	if (mailbox_update(box, &update) < 0) {
		i_error("Couldn't update mailbox %s metadata: %s",
			mailbox_get_vname(box),
			mailbox_get_last_error(box, NULL));
		brain->failed = TRUE;
	}
}