dsync-brain-mailbox-tree.c revision 4dccd2090d3318bea1c4029fb660db77118f5944
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "str.h"
#include "settings-parser.h"
#include "mail-namespace.h"
#include "doveadm-settings.h"
#include "dsync-ibc.h"
#include "dsync-mailbox-tree.h"
#include "dsync-brain-private.h"
#include <ctype.h>
struct mail_namespace *ns)
{
/* 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;
}
}
{
char sep;
return;
}
continue;
i_fatal("Synced namespaces have conflicting separators "
"('%c' for prefix=\"%s\", '%c' for prefix=\"%s\")",
}
}
return;
i_fatal("All your namespaces have a location setting. "
"Only namespaces with empty location settings are converted. "
"(One namespace should default to mail_location setting)");
}
{
struct mail_namespace *ns;
/* we'll convert remote mailbox names to use our own separator */
/* fill the local mailbox tree */
continue;
brain->exclude_mailboxes) < 0)
}
}
{
struct dsync_mailbox_node *node;
enum dsync_ibc_send_ret ret;
const char *full_name;
char sep[2];
T_BEGIN {
const char *const *parts;
} T_END;
if (ret == DSYNC_IBC_SEND_RET_FULL)
return;
}
}
{
const struct dsync_mailbox_delete *deletes;
unsigned int count;
&count);
}
static bool
const char *const *name_parts)
{
unsigned int part_len;
return TRUE;
part = *name_parts;
return FALSE;
return FALSE;
}
return *name_parts != NULL;
}
static struct mail_namespace *
{
continue;
if (ns->prefix_len == 0) {
/* prefix="" is the fallback namespace */
}
}
return best_ns;
}
static bool
{
bool ret;
mailbox_free(&box);
return ret;
}
static void
char alt_char)
{
const char *old_vname;
/* replace control chars */
if ((unsigned char)*p < ' ')
*p = alt_char;
}
/* make it valid UTF8 */
str_truncate(vname, 0);
if (uni_utf8_get_valid_data((const void *)old_vname,
i_unreached();
}
return;
/* 1) change any real separators to alt separators (this wouldn't
be necessary with listescape, but don't bother detecting it) */
if (*p == list_sep)
*p = alt_char;
}
return;
}
/* 2) '/' characters aren't valid without listescape */
if (*p == '/')
*p = alt_char;
}
return;
}
/* 3) probably some reserved name (e.g. dbox-Mails) */
return;
/* 4) name is too long? just give up and generate a unique name */
str_truncate(vname, 0);
}
static int
{
struct mail_namespace *ns;
const char *p;
return -1;
/* build the mailbox name */
for (p = *name_parts; *p != '\0'; p++) {
if (*p != ns_sep)
str_append_c(vname, *p);
else
}
}
return 0;
}
{
struct dsync_mailbox_tree_sync_ctx *ctx;
const struct dsync_mailbox_tree_sync_change *change;
if (brain->backup_send)
else if (brain->backup_recv)
else
}
}
{
const struct dsync_mailbox_node *remote_node;
struct mail_namespace *ns;
enum dsync_ibc_recv_ret ret;
char sep[2];
&remote_node)) > 0) {
i_error("Couldn't find namespace for mailbox %s",
return TRUE;
}
}
if (ret != DSYNC_IBC_RECV_RET_FINISHED)
return changed;
i_error("Remote sent duplicate mailbox GUID %s for mailboxes %s and %s",
dup_node2));
}
return TRUE;
}
static void
struct dsync_mailbox_tree *other_tree,
const struct dsync_mailbox_delete *other_del)
{
const struct dsync_mailbox_node *node;
const char *name;
/* see if we can find the deletion based on mailbox tree that should
still have the mailbox */
return;
/* mailbox is always deleted */
break;
/* we don't want to delete this directory, we already
have a newer timestamp for it */
return;
}
break;
/* we don't want to unsubscribe, since we already have
a newer subscription timestamp */
return;
}
break;
}
/* make a node for it in the other mailbox tree */
/* other side has already created a new mailbox or
directory with this name, we can't delete it */
return;
}
/* ok, mark the other node deleted */
sizeof(other_node->mailbox_guid));
}
else {
}
&old_node) < 0)
i_unreached();
}
{
const struct dsync_mailbox_delete *deletes;
unsigned int i, count;
char sep;
&sep) == 0)
return FALSE;
/* apply remote's mailbox deletions based on our local tree */
for (i = 0; i < count; i++) {
&deletes[i]);
}
/* apply local mailbox deletions based on remote tree */
&count);
for (i = 0; i < count; i++) {
&deletes[i]);
}
return TRUE;
}