/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "hash.h"
#include "hostpid.h"
#include "str.h"
#include "file-create-locked.h"
#include "process-title.h"
#include "settings-parser.h"
#include "master-service.h"
#include "master-service-settings.h"
#include "mail-namespace.h"
#include "dsync-mailbox-tree.h"
#include "dsync-ibc.h"
#include "dsync-brain-private.h"
#include "dsync-mailbox-import.h"
#include "dsync-mailbox-export.h"
enum dsync_brain_title {
};
static const char *dsync_state_names[] = {
"master_recv_handshake",
"slave_recv_handshake",
"master_send_last_common",
"slave_recv_last_common",
"send_mailbox_tree",
"send_mailbox_tree_deletes",
"recv_mailbox_tree",
"recv_mailbox_tree_deletes",
"master_send_mailbox",
"slave_recv_mailbox",
"sync_mails",
"finish",
"done"
};
static const char *
enum dsync_brain_title title)
{
} else {
} else {
if (import_title[0] != '\0') {
}
if (export_title[0] != '\0') {
}
}
}
switch (title) {
case DSYNC_BRAIN_TITLE_NONE:
break;
break;
}
}
{
}
{
return;
}
try_pending = TRUE;
do {
break;
}
if (changed)
try_pending = TRUE;
else if (try_pending) {
try_pending = FALSE;
}
} while (changed);
}
static struct dsync_brain *
{
return brain;
}
static void
{
(flags & DSYNC_BRAIN_FLAG_SEND_MAIL_REQUESTS) != 0;
(flags & DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE) != 0;
(flags & DSYNC_BRAIN_FLAG_NO_MAIL_PREFETCH) != 0;
(flags & DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES) != 0;
}
static void
const char *vname)
{
}
struct dsync_brain *
enum dsync_brain_flags flags,
const struct dsync_brain_settings *set)
{
const char *error;
}
}
sizeof(brain->sync_box_guid));
if (brain->lock_timeout != 0)
else
if (sync_type != DSYNC_BRAIN_SYNC_TYPE_STATE)
;
i_error("Saved sync state is invalid, "
"falling back to full sync: %s", error);
} else {
i_debug("brain %c: Imported mailbox states:",
}
}
sizeof(ibc_set.sync_box_guid));
/* reverse the backup direction for the slave */
if ((flags & DSYNC_BRAIN_FLAG_BACKUP_SEND) != 0)
else if ((flags & DSYNC_BRAIN_FLAG_BACKUP_RECV) != 0)
if (brain->verbose_proctitle)
return brain;
}
struct dsync_brain *
bool local, const char *process_title_prefix)
{
if (local) {
/* both master and slave are running within the same process,
update the proctitle only for master. */
}
if (brain->verbose_proctitle)
return brain;
}
{
continue;
if (mail_storage_purge(storage) < 0) {
}
}
}
{
int ret;
i_error("Timeout during state=%s%s",
t_strdup_printf(" (send=%s recv=%s)",
}
/* unlink the lock file before it gets unlocked */
i_debug("brain %c: Unlocked %s",
}
}
return ret;
}
static int
{
};
bool created;
int ret;
/* locking done by remote */
i_debug("brain %c: Locking done by remote "
"(local hostname=%s, remote hostname=%s)",
}
return 0;
}
/* running dsync within the same server.
locking done by master brain. */
i_debug("brain %c: Locking done by local master-brain "
"(local hostname=%s, remote hostname=%s)",
}
return 0;
}
i_error("Couldn't look up user's home dir");
return -1;
}
if (ret == 0) {
i_error("User has no home directory");
return -1;
}
if (brain->verbose_proctitle)
i_debug("brain %c: Locking done locally in %s "
"(local hostname=%s, remote hostname=%s)",
}
if (brain->verbose_proctitle)
}
static void
const struct dsync_ibc_settings *ibc_set)
{
if (ibc_set->hdr_hash_v3)
else if (ibc_set->hdr_hash_v2)
else
}
{
return FALSE;
if (brain->lock_timeout > 0) {
return FALSE;
}
}
return TRUE;
}
{
const char *const *prefixes;
return FALSE;
if (ibc_set->lock_timeout > 0) {
return FALSE;
}
} else {
}
/* ugly workaround for strsplit API: there was one
prefix="" entry */
}
*prefixes);
return FALSE;
}
}
}
sizeof(brain->sync_box_guid));
/* this flag is only set on the remote slave brain */
else
return TRUE;
}
{
}
for (;;) {
if (ret == DSYNC_IBC_SEND_RET_FULL)
return;
break;
}
}
const struct dsync_mailbox_state *state)
{
}
{
}
if (ret == DSYNC_IBC_RECV_RET_FINISHED) {
}
return changed;
}
{
const char *error;
bool require_full_resync;
if (!brain->master_brain) {
return TRUE;
}
if (ret == DSYNC_IBC_RECV_RET_TRYAGAIN)
return FALSE;
if (mail_error != 0 &&
}
if (require_full_resync)
return TRUE;
}
{
return FALSE;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
case DSYNC_STATE_SYNC_MAILS:
break;
case DSYNC_STATE_FINISH:
break;
case DSYNC_STATE_DONE:
break;
}
if (brain->verbose_proctitle) {
}
}
{
bool ret;
return FALSE;
}
T_BEGIN {
} T_END;
return ret;
}
{
i_debug("brain %c: Mailbox %s state: uidvalidity=%u uid=%u modseq=%"PRIu64" pvt_modseq=%"PRIu64" messages=%u changes_during_sync=%d",
}
}
{
if (brain->require_full_resync)
return;
/* update mailbox states */
else
}
/* remove nonexistent mailboxes */
guid);
i_debug("brain %c: Removed state for deleted mailbox %s",
}
}
}
i_debug("brain %c: Exported mailbox states:",
}
}
{
}
{
}
bool *remote_only_r)
{
*remote_only_r = TRUE;
return "Remote notified that changes happened during sync";
}
*remote_only_r = FALSE;
return brain->changes_during_sync;
}
struct mail_namespace *ns)
{
return TRUE;
}
return FALSE;
}
/* always skip aliases */
return FALSE;
}
if (brain->sync_visible_namespaces) {
return TRUE;
NAMESPACE_FLAG_LIST_CHILDREN)) != 0)
return TRUE;
return FALSE;
} else {
SETTING_STRVAR_UNEXPANDED) == 0;
}
}
const char *reason)
{
i_debug("brain %c: Change during sync: %s",
}
}