doveadm-dsync.c revision f538498d8ad0c7781c7aef6c08483b3ea1bea2cd
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2009-2016 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define DSYNC_COMMON_GETOPT_ARGS "+1a:dDEfg:I:l:m:n:NO:Pr:Rs:t:T:Ux:"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* The broken_char is mainly set to get a proper error message when trying to
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen convert a mailbox with a name that can't be used properly translated between
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen vname/storage_name and would otherwise be mixed up with a normal "mailbox
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen doesn't exist" error message. This could be any control character, since
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen none of them are allowed to be created in regular mailbox names. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define DSYNC_DEFAULT_IO_STREAM_TIMEOUT_SECS (60*10)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen const char *const *remote_cmd_args;
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen size_t input_orig_bufsize, output_orig_bufsize;
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainenstatic void remote_error_input(struct dsync_cmd_context *ctx)
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen const unsigned char *data;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen data = i_stream_get_data(ctx->err_stream, &size);
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen while ((line = i_stream_next_line(ctx->err_stream)) != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenrun_cmd(struct dsync_cmd_context *ctx, const char *const *args)
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen ctx->remote_cmd_args = p_strarray_dup(ctx->ctx.pool, args);
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen if (pipe(fd_in) < 0 || pipe(fd_out) < 0 || pipe(fd_err) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* child, which will execute the proxy server. stdin/stdout
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen goes to pipes which we'll pass to proxy client. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *prefix =
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen t_strdup_printf("%s\n", ctx->ctx.cur_username);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (write_full(ctx->fd_out, prefix, strlen(prefix)) < 0)
456f3c79aafea8f6d009fab3d94946f38047dcd0Timo Sirainen ctx->err_stream = i_stream_create_fd(ctx->fd_err, IO_BLOCK_SIZE);
456f3c79aafea8f6d009fab3d94946f38047dcd0Timo Sirainen i_stream_set_return_partial_line(ctx->err_stream, TRUE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenmirror_get_remote_cmd_line(const char *const *argv,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *const **cmd_args_r)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *p;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* we're executing dsync */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen p = "server";
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* we're executing doveadm */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen p = "dsync-server";
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic const char *const *
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenget_ssh_cmd_args(const char *host, const char *login, const char *mail_user)
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen static struct var_expand_table static_tab[] = {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen args = t_strsplit(doveadm_settings->dsync_remote_cmd, " ");
fe8af34153615d9007f2238fca87df11ff32d614Timo Sirainen /* some automation: if parameter's all %variables
fe8af34153615d9007f2238fca87df11ff32d614Timo Sirainen expand to empty, but the %variable isn't the only
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen text in the parameter, skip it. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic bool mirror_get_remote_cmd(struct dsync_cmd_context *ctx,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *const **cmd_args_r)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *p, *host, *const *argv = ctx->ctx.args;
return TRUE;
if (!i_isalnum(*p)) {
return FALSE;
return TRUE;
return TRUE;
int ret;
*mail_error_r = 0;
i_unreached();
if (ret < 0) {
if (doveadm_is_killed()) {
const char *const *remote_cmd_args)
static struct dsync_ibc *
const char *state_str)
const char *path;
int fd;
const char *const *strp;
int ret = 0;
if (doveadm_debug)
case DSYNC_RUN_TYPE_LOCAL:
case DSYNC_RUN_TYPE_CMD:
case DSYNC_RUN_TYPE_STREAM:
if (ret < 0) {
if (mail_error2 != 0 &&
return ret;
void *context)
switch (exit_code) {
case EX_NOUSER:
const char **error_r)
const char *error;
if (ssl) {
if (doveadm_debug)
const char *location,
const char **error_r)
const char *const args[])
str++;
return FALSE;
return TRUE;
return _ctx;
return FALSE;
return TRUE;
"[-1fPRU] [-l <secs>] [-r <rawlog path>] [-m <mailbox>] [-g <mailbox_guid>] [-n <namespace> | -N] [-x <exclude>] [-s <state>] -d|<dest>"
"[-fPRU] [-l <secs>] [-r <rawlog path>] [-m <mailbox>] [-g <mailbox_guid>] [-n <namespace> | -N] [-x <exclude>] [-s <state>] -d|<dest>"
const char *getopt_str;
if (flag_m) {
if (flag_u) {
if (flag_C) {
if (!dsync_server) {
if (flag_f)
if (flag_R)