.doveadm_password = "",
.doveadm_allowed_commands = "",
.dsync_alt_char = "_",
- .dsync_remote_cmd = "ssh -l%{login} %{host} doveadm dsync-server -u%u -l%{lock_timeout}",
+ .dsync_remote_cmd = "ssh -l%{login} %{host} doveadm dsync-server -u%u -l%{lock_timeout} -n%{namespace}",
.plugin_envs = ARRAY_INIT
};
struct dsync_cmd_context {
struct doveadm_mail_cmd_context ctx;
enum dsync_brain_flags brain_flags;
- const char *mailbox;
+ const char *mailbox, *namespace_prefix;
const char *local_location;
{ '\0', NULL, "login" },
{ '\0', NULL, "host" },
{ '\0', NULL, "lock_timeout" },
+ { '\0', NULL, "namespace" },
{ '\0', NULL, NULL }
};
struct var_expand_table *tab;
tab[1].value = login;
tab[2].value = host;
tab[3].value = dec2str(ctx->lock_timeout);
+ tab[4].value = ctx->namespace_prefix;
t_array_init(&cmd_args, 8);
str = t_str_new(128);
"points to same directory: %s", path1);
}
- worker2 = dsync_worker_init_local(user2, *ctx->ctx.set->dsync_alt_char);
+ worker2 = dsync_worker_init_local(user2, ctx->namespace_prefix,
+ *ctx->ctx.set->dsync_alt_char);
mail_user_unref(&user2);
return worker2;
}
user->admin = TRUE;
/* create workers */
- worker1 = dsync_worker_init_local(user, *_ctx->set->dsync_alt_char);
+ worker1 = dsync_worker_init_local(user, ctx->namespace_prefix,
+ *_ctx->set->dsync_alt_char);
if (!ctx->remote)
worker2 = cmd_dsync_run_local(ctx, user);
else
case 'm':
ctx->mailbox = optarg;
break;
+ case 'n':
+ ctx->namespace_prefix = optarg;
+ break;
case 'R':
ctx->reverse_workers = TRUE;
break;
struct dsync_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct dsync_cmd_context);
- ctx->ctx.getopt_args = "+dEfl:m:R";
+ ctx->ctx.getopt_args = "+dEfl:m:n:R";
ctx->ctx.v.parse_arg = cmd_mailbox_dsync_parse_arg;
ctx->ctx.v.preinit = cmd_dsync_preinit;
ctx->ctx.v.init = cmd_dsync_init;
i_set_failure_prefix(t_strdup_printf("dsync-remote(%s): ",
user->username));
- worker = dsync_worker_init_local(user, *_ctx->set->dsync_alt_char);
+ worker = dsync_worker_init_local(user, ctx->namespace_prefix,
+ *_ctx->set->dsync_alt_char);
server = dsync_proxy_server_init(STDIN_FILENO, STDOUT_FILENO, worker);
if (!ctx->lock)
if (str_to_uint(optarg, &ctx->lock_timeout) < 0)
i_error("Invalid -l parameter: %s", optarg);
break;
+ case 'n':
+ ctx->namespace_prefix = optarg;
+ break;
default:
return FALSE;
}
struct dsync_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct dsync_cmd_context);
- ctx->ctx.getopt_args = "El:";
+ ctx->ctx.getopt_args = "El:n:";
ctx->ctx.v.parse_arg = cmd_mailbox_dsync_server_parse_arg;
ctx->ctx.v.run = cmd_dsync_server_run;
return &ctx->ctx;
}
struct doveadm_mail_cmd cmd_dsync_mirror = {
- cmd_dsync_alloc, "sync", "[-dfR] [-l <secs>] [-m <mailbox>] <dest>"
+ cmd_dsync_alloc, "sync",
+ "[-dfR] [-l <secs>] [-m <mailbox>] [-n <namespace>] <dest>"
};
struct doveadm_mail_cmd cmd_dsync_backup = {
cmd_dsync_backup_alloc, "backup",
- "[-dfR] [-l <secs>] [-m <mailbox>] <dest>"
+ "[-dfR] [-l <secs>] [-m <mailbox>] [-n <namespace>] <dest>"
};
struct doveadm_mail_cmd cmd_dsync_server = {
cmd_dsync_server_alloc, "dsync-server", &doveadm_mail_cmd_hide
struct hash_table *dir_changes_hash;
char alt_char;
- ARRAY_DEFINE(wanted_namespaces, struct mail_namespace *);
+ const char *namespace_prefix;
mailbox_guid_t selected_box_guid;
struct mailbox *selected_box;
return h;
}
-static bool local_worker_want_namespace(struct mail_namespace *ns)
+static bool local_worker_want_namespace(struct local_dsync_worker *worker,
+ struct mail_namespace *ns)
{
- return strcmp(ns->unexpanded_set->location,
- SETTING_STRVAR_UNEXPANDED) == 0;
+ if (worker->namespace_prefix == NULL) {
+ return strcmp(ns->unexpanded_set->location,
+ SETTING_STRVAR_UNEXPANDED) == 0;
+ } else {
+ return strcmp(ns->prefix, worker->namespace_prefix) == 0;
+ }
}
static void dsync_check_namespaces(struct local_dsync_worker *worker)
{
struct mail_namespace *ns;
+ if (worker->namespace_prefix != NULL) {
+ ns = mail_namespace_find_prefix(worker->user->namespaces,
+ worker->namespace_prefix);
+ if (ns == NULL) {
+ i_fatal("Namespace prefix '%s' not found",
+ worker->namespace_prefix);
+ }
+ return;
+ }
+
for (ns = worker->user->namespaces; ns != NULL; ns = ns->next) {
- if (local_worker_want_namespace(ns))
+ if (local_worker_want_namespace(worker, ns))
return;
}
i_fatal("All your namespaces have a location setting. "
}
struct dsync_worker *
-dsync_worker_init_local(struct mail_user *user, char alt_char)
+dsync_worker_init_local(struct mail_user *user, const char *namespace_prefix,
+ char alt_char)
{
struct local_dsync_worker *worker;
pool_t pool;
worker->worker.v = local_dsync_worker;
worker->user = user;
worker->pool = pool;
+ worker->namespace_prefix = p_strdup(pool, namespace_prefix);
worker->alt_char = alt_char;
worker->mailbox_hash =
hash_table_create(default_pool, pool, 0,
mailbox_guid_hash, mailbox_guid_cmp);
i_array_init(&worker->saved_uids, 128);
i_array_init(&worker->msg_get_queue, 32);
- p_array_init(&worker->wanted_namespaces, pool, 8);
dsync_check_namespaces(worker);
mail_user_ref(worker->user);
hash_table_create(default_pool, worker->pool, 0,
dir_change_hash, dir_change_cmp);
for (ns = worker->user->namespaces; ns != NULL; ns = ns->next) {
- if (ns->alias_for != NULL || !local_worker_want_namespace(ns))
+ if (ns->alias_for != NULL ||
+ !local_worker_want_namespace(worker, ns))
continue;
if (dsync_worker_get_list_mailbox_log(worker, ns->list) < 0)
memset(dsync_box_r, 0, sizeof(*dsync_box_r));
while ((info = mailbox_list_iter_next(iter->list_iter)) != NULL) {
- if (local_worker_want_namespace(info->ns))
+ if (local_worker_want_namespace(worker, info->ns))
break;
}
if (info == NULL)
memset(rec_r, 0, sizeof(*rec_r));
while ((info = mailbox_list_iter_next(iter->list_iter)) != NULL) {
- if (local_worker_want_namespace(info->ns) ||
+ if (local_worker_want_namespace(worker, info->ns) ||
(info->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0)
break;
}
typedef void dsync_worker_finish_callback_t(bool success, void *context);
struct dsync_worker *
-dsync_worker_init_local(struct mail_user *user, char alt_char);
+dsync_worker_init_local(struct mail_user *user, const char *namespace_prefix,
+ char alt_char);
struct dsync_worker *dsync_worker_init_proxy_client(int fd_in, int fd_out);
void dsync_worker_deinit(struct dsync_worker **worker);