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;
}
Exemple #2
0
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;
}