#include "mail-namespace.h"
#include "mail-storage.h"
#include "mailbox-list-iter.h"
+#include "dsync-brain.h"
#include "dsync-mailbox-tree-private.h"
+static const char *
+dsync_mailbox_tree_name_unescape(struct mail_namespace *ns,
+ const char *old_vname, char alt_char)
+{
+ const char ns_sep = mail_namespace_get_sep(ns);
+ const char escape_char =
+ mailbox_list_get_settings(ns->list)->vname_escape_char;
+ const char *const *old_vname_parts =
+ dsync_mailbox_name_to_parts(old_vname, ns_sep, escape_char);
+
+ string_t *new_vname = t_str_new(128);
+ for (; *old_vname_parts != NULL; old_vname_parts++) {
+ for (const char *p = *old_vname_parts; *p != '\0'; p++) {
+ if (*p != ns_sep)
+ str_append_c(new_vname, *p);
+ else
+ str_append_c(new_vname, alt_char);
+ }
+ str_append_c(new_vname, ns_sep);
+ }
+ str_truncate(new_vname, str_len(new_vname)-1);
+ return str_c(new_vname);
+};
+
static int
dsync_mailbox_tree_add_node(struct dsync_mailbox_tree *tree,
const struct mailbox_info *info,
+ char alt_char,
struct dsync_mailbox_node **node_r)
{
struct dsync_mailbox_node *node;
+ const char *vname = info->vname;
+
+ struct dsync_mailbox_list *dlist = DSYNC_LIST_CONTEXT(info->ns->list);
+ if (dlist != NULL && !dlist->have_orig_escape_char) {
+ /* The escape character was added only for dsync internally.
+ Normally there is no escape character configured. Change
+ the mailbox names so that it doesn't rely on it. */
+ vname = dsync_mailbox_tree_name_unescape(info->ns, vname, alt_char);
+ }
- node = dsync_mailbox_tree_get(tree, info->vname);
+ node = dsync_mailbox_tree_get(tree, vname);
if (node->ns == info->ns)
;
else if (node->ns == NULL) {
dsync_mailbox_tree_add_exists_node(struct dsync_mailbox_tree *tree,
const struct mailbox_info *info,
struct dsync_mailbox_node **node_r,
+ char alt_char,
enum mail_error *error_r)
{
- if (dsync_mailbox_tree_add_node(tree, info, node_r) < 0) {
+ if (dsync_mailbox_tree_add_node(tree, info, alt_char, node_r) < 0) {
*error_r = MAIL_ERROR_TEMP;
return -1;
}
static int dsync_mailbox_tree_add(struct dsync_mailbox_tree *tree,
const struct mailbox_info *info,
const guid_128_t box_guid,
+ char alt_char,
enum mail_error *error_r)
{
struct dsync_mailbox_node *node;
return 0;
if ((info->flags & MAILBOX_NOSELECT) != 0) {
return !guid_128_is_empty(box_guid) ? 0 :
- dsync_mailbox_tree_add_exists_node(tree, info, &node, error_r);
+ dsync_mailbox_tree_add_exists_node(
+ tree, info, &node, alt_char, error_r);
}
/* get GUID and UIDVALIDITY for selectable mailbox */
if (existence == MAILBOX_EXISTENCE_NOSELECT) {
return !guid_128_is_empty(box_guid) ? 0 :
dsync_mailbox_tree_add_exists_node(
- tree, info, &node, error_r);
+ tree, info, &node, alt_char, error_r);
} else {
return 0;
}
/* unwanted mailbox */
return 0;
}
- if (dsync_mailbox_tree_add_exists_node(tree, info, &node, error_r) < 0)
+ if (dsync_mailbox_tree_add_exists_node(
+ tree, info, &node, alt_char, error_r) < 0)
return -1;
memcpy(node->mailbox_guid, metadata.guid,
sizeof(node->mailbox_guid));
struct mail_namespace *ns, const char *box_name,
const guid_128_t box_guid,
const char *const *exclude_mailboxes,
+ char alt_char,
enum mail_error *error_r)
{
const enum mailbox_list_iter_flags list_flags =
.vname = vname,
.ns = ns,
};
- if (dsync_mailbox_tree_add(tree, &ns_info, box_guid, error_r) < 0)
+ if (dsync_mailbox_tree_add(
+ tree, &ns_info, box_guid, alt_char, error_r) < 0)
return -1;
} else {
tree->root.ns = ns;
while ((info = mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
if (dsync_mailbox_info_is_wanted(info, box_name,
exclude_mailboxes)) {
- if (dsync_mailbox_tree_add(tree, info, box_guid, error_r) < 0)
+ if (dsync_mailbox_tree_add(
+ tree, info, box_guid, alt_char, error_r) < 0)
ret = -1;
}
} T_END;
/* add subscriptions */
iter = mailbox_list_iter_init(ns->list, list_pattern, subs_list_flags);
while ((info = mailbox_list_iter_next(iter)) != NULL) {
- if (dsync_mailbox_tree_add_node(tree, info, &node) == 0)
+ if (dsync_mailbox_tree_add_node(tree, info, alt_char, &node) == 0)
node->subscribed = TRUE;
else {
*error_r = MAIL_ERROR_TEMP;