/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "mail-namespace.h"
#include "mail-storage.h"
#include "dsync-mailbox-tree.h"
#include "dsync-brain-private.h"
static int
enum mail_error *error_r)
{
const char *errstr;
int ret;
if (error != MAIL_ERROR_EXISTS) {
i_error("Can't create mailbox %s: %s",
return -1;
}
}
if (brain->no_mail_sync) {
/* trust that create worked, we can't actually open it
and verify. */
return 0;
}
/* sync the mailbox so we can look up its latest status */
i_error("Can't sync mailbox %s: %s",
return -1;
}
/* verify that the GUID is what we wanted. if it's not, it probably
means that the mailbox had already been created. then we'll use the
GUID that is higher.
mismatching UIDVALIDITY is handled later, because we choose it by
checking which mailbox has more messages */
i_error("Can't get mailbox GUID %s: %s",
return -1;
}
/* if THEIR guid is bigger than OUR guid, and we are not doing
backup in either direction, OR GUID did not match and we are
receiving backup, try change the mailbox GUID.
*/
i_debug("brain %c: Changing mailbox %s GUID %s -> %s",
}
sizeof(update.mailbox_guid));
i_error("Can't update mailbox GUID %s: %s",
return -1;
}
/* verify that the update worked */
&metadata) < 0) {
i_error("Can't get mailbox GUID %s: %s",
return -1;
}
i_error("Backend didn't update mailbox %s GUID",
return -1;
}
} else if (ret < 0) {
i_debug("brain %c: Other brain should change mailbox "
"%s GUID %s -> %s",
}
}
return 0;
}
const struct dsync_mailbox_tree_sync_change *change,
enum mail_error *error_r)
{
if (brain->backup_send) {
return 0;
}
/* make sure we're deleting the correct mailbox */
if (ret < 0) {
i_error("Mailbox sync: Couldn't allocate mailbox %s GUID %s: %s",
return -1;
}
if (ret == 0) {
"Mailbox %s GUID %s deletion conflict: %s",
return 0;
}
break;
return 0;
if (error == MAIL_ERROR_NOTFOUND ||
error == MAIL_ERROR_EXISTS) {
"Mailbox %s mailbox_list_delete_dir conflict: %s",
return 0;
} else {
i_error("Mailbox sync: mailbox_list_delete_dir failed: %s",
errstr);
return -1;
}
default:
break;
}
mailbox_free(&box);
return ret;
if (ret < 0 &&
/* it doesn't matter if somebody else created this
directory or we automatically did while creating its
child mailbox. it's there now anyway and we don't
gain anything by treating this failure any
differently from success. */
ret = 0;
}
func_name = "mailbox_create";
break;
func_name = "mailbox_delete";
break;
i_unreached();
change->rename_dest_name, 0);
func_name = "mailbox_rename";
break;
func_name = "mailbox_set_subscribed";
break;
func_name = "mailbox_set_subscribed";
break;
}
if (ret < 0) {
if (error == MAIL_ERROR_EXISTS ||
error == MAIL_ERROR_NOTFOUND) {
/* mailbox was already created or was already deleted.
let the next sync figure out what to do */
"Mailbox %s %s conflict: %s",
ret = 0;
} else {
i_error("Mailbox %s sync: %s failed: %s",
}
}
mailbox_free(&box);
return ret;
}