"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/doveadm/doveadm-mail.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

doveadm-mail.c  (dovecot-2.3.16):doveadm-mail.c  (dovecot-2.3.17)
skipping to change at line 40 skipping to change at line 40
#include <stdio.h> #include <stdio.h>
#define DOVEADM_MAIL_CMD_INPUT_TIMEOUT_MSECS (5*60*1000) #define DOVEADM_MAIL_CMD_INPUT_TIMEOUT_MSECS (5*60*1000)
struct force_resync_cmd_context { struct force_resync_cmd_context {
struct doveadm_mail_cmd_context ctx; struct doveadm_mail_cmd_context ctx;
bool fsck; bool fsck;
}; };
ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
void (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx); void (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
struct doveadm_mail_cmd_module_register struct doveadm_mail_cmd_module_register
doveadm_mail_cmd_module_register = { 0 }; doveadm_mail_cmd_module_register = { 0 };
char doveadm_mail_cmd_hide = '\0'; char doveadm_mail_cmd_hide = '\0';
static int killed_signo = 0; static int killed_signo = 0;
bool doveadm_is_killed(void) bool doveadm_is_killed(void)
{ {
return killed_signo != 0; return killed_signo != 0;
skipping to change at line 462 skipping to change at line 461
} }
ret = mail_storage_service_next(ctx->storage_service, ret = mail_storage_service_next(ctx->storage_service,
ctx->cur_service_user, ctx->cur_service_user,
&ctx->cur_mail_user, error_r); &ctx->cur_mail_user, error_r);
if (ret < 0) { if (ret < 0) {
mail_storage_service_user_unref(&ctx->cur_service_user); mail_storage_service_user_unref(&ctx->cur_service_user);
return ret; return ret;
} }
if (ctx->v.run(ctx, ctx->cur_mail_user) < 0) { T_BEGIN {
i_assert(ctx->exit_code != 0); if (ctx->v.run(ctx, ctx->cur_mail_user) < 0) {
} i_assert(ctx->exit_code != 0);
}
} T_END;
mail_user_deinit(&ctx->cur_mail_user); mail_user_deinit(&ctx->cur_mail_user);
mail_storage_service_user_unref(&ctx->cur_service_user); mail_storage_service_user_unref(&ctx->cur_service_user);
return 1; return 1;
} }
static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED) static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
{ {
killed_signo = si->si_signo; killed_signo = si->si_signo;
} }
skipping to change at line 666 skipping to change at line 667
doveadm_exit_code = EX_TEMPFAIL; doveadm_exit_code = EX_TEMPFAIL;
i_error("%s", error); i_error("%s", error);
} else if (ret == 0) { } else if (ret == 0) {
doveadm_exit_code = EX_NOUSER; doveadm_exit_code = EX_NOUSER;
i_error("User doesn't exist"); i_error("User doesn't exist");
} }
} else { } else {
ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
doveadm_mail_all_users(ctx, wildcard_user); doveadm_mail_all_users(ctx, wildcard_user);
} }
if (ctx->search_args != NULL)
mail_search_args_unref(&ctx->search_args);
doveadm_mail_server_flush(); doveadm_mail_server_flush();
ctx->v.deinit(ctx); doveadm_mail_cmd_deinit(ctx);
doveadm_print_flush(); doveadm_print_flush();
/* service deinit unloads mail plugins, so do it late */ /* service deinit unloads mail plugins, so do it late */
mail_storage_service_deinit(&ctx->storage_service); mail_storage_service_deinit(&ctx->storage_service);
if (ctx->exit_code != 0) if (ctx->exit_code != 0)
doveadm_exit_code = ctx->exit_code; doveadm_exit_code = ctx->exit_code;
} }
static void doveadm_mail_cmd_free(struct doveadm_mail_cmd_context *ctx) void doveadm_mail_cmd_deinit(struct doveadm_mail_cmd_context *ctx)
{ {
i_stream_unref(&ctx->users_list_input); ctx->v.deinit(ctx);
i_stream_unref(&ctx->cmd_input); if (ctx->search_args != NULL)
pool_unref(&ctx->pool); mail_search_args_unref(&ctx->search_args);
}
static void
doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
{
struct doveadm_cmd_context cctx;
struct doveadm_mail_cmd_context *ctx;
const char *getopt_args, *wildcard_user;
int c;
i_zero(&cctx);
cctx.conn_type = DOVEADM_CONNECTION_TYPE_CLI;
cctx.username = getenv("USER");
ctx = doveadm_mail_cmdline_init(cmd);
ctx->cctx = &cctx;
ctx->full_args = (const void *)(argv + 1);
getopt_args = "AF:S:u:";
/* keep context's getopt_args first in case it contains '+' */
if (ctx->getopt_args != NULL)
getopt_args = t_strconcat(ctx->getopt_args, getopt_args, NULL);
i_assert(master_getopt_str_is_valid(getopt_args));
wildcard_user = NULL;
while ((c = getopt(argc, argv, getopt_args)) > 0) {
switch (c) {
case 'A':
ctx->iterate_all_users = TRUE;
break;
case 'S':
doveadm_settings->doveadm_socket_path = optarg;
if (doveadm_settings->doveadm_worker_count == 0)
doveadm_settings->doveadm_worker_count = 1;
break;
case 'u':
ctx->service_flags |=
MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
cctx.username = optarg;
if (strchr(cctx.username, '*') != NULL ||
strchr(cctx.username, '?') != NULL) {
wildcard_user = cctx.username;
cctx.username = NULL;
}
break;
case 'F':
ctx->service_flags |=
MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
wildcard_user = "*";
ctx->users_list_input =
i_stream_create_file(optarg, 1024);
break;
default:
if (ctx->v.parse_arg == NULL ||
!ctx->v.parse_arg(ctx, c))
doveadm_mail_help(cmd);
}
}
argv += optind;
if (argv[0] != NULL && cmd->usage_args == NULL) {
i_fatal_status(EX_USAGE, "doveadm %s: Unknown parameter: %s",
cmd->name, argv[0]);
}
ctx->args = (const void *)argv;
doveadm_mail_cmd_exec(ctx, wildcard_user);
doveadm_mail_cmd_free(ctx);
}
static bool
doveadm_mail_cmd_try_find_multi_word(const struct doveadm_mail_cmd *cmd,
const char *cmdname, int *argc,
const char *const **argv)
{
size_t len;
if (*argc < 2)
return FALSE;
*argc -= 1;
*argv += 1;
len = strlen((*argv)[0]);
if (!str_begins(cmdname, (*argv)[0]))
return FALSE;
if (cmdname[len] == ' ') {
/* more args */
return doveadm_mail_cmd_try_find_multi_word(cmd, cmdname + len +
1,
argc, argv);
}
if (cmdname[len] != '\0')
return FALSE;
/* match */
return TRUE;
}
const struct doveadm_mail_cmd *
doveadm_mail_cmd_find_from_argv(const char *cmd_name, int *argc,
const char *const **argv)
{
const struct doveadm_mail_cmd *cmd;
size_t cmd_name_len;
const char *const *orig_argv;
int orig_argc;
i_assert(*argc > 0);
cmd_name_len = strlen(cmd_name);
array_foreach(&doveadm_mail_cmds, cmd) {
if (strcmp(cmd->name, cmd_name) == 0)
return cmd;
/* see if it matches a multi-word command */
if (strncmp(cmd->name, cmd_name, cmd_name_len) == 0 &&
cmd->name[cmd_name_len] == ' ') {
const char *subcmd = cmd->name + cmd_name_len + 1;
orig_argc = *argc;
orig_argv = *argv;
if (doveadm_mail_cmd_try_find_multi_word(cmd, subcmd,
argc, argv))
return cmd;
*argc = orig_argc;
*argv = orig_argv;
}
}
return NULL;
}
bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[])
{
const struct doveadm_mail_cmd *cmd;
cmd = doveadm_mail_cmd_find_from_argv(cmd_name, &argc, (void *)&argv);
if (cmd == NULL)
return FALSE;
doveadm_mail_cmd(cmd, argc, argv);
return TRUE;
}
void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd)
{
/* for now we'll just assume that cmd will be permanently in memory */
array_push_back(&doveadm_mail_cmds, cmd);
}
const struct doveadm_mail_cmd *doveadm_mail_cmd_find(const char *cmd_name)
{
const struct doveadm_mail_cmd *cmd;
array_foreach(&doveadm_mail_cmds, cmd) {
if (strcmp(cmd->name, cmd_name) == 0)
return cmd;
}
return NULL;
} }
void doveadm_mail_usage(string_t *out) void doveadm_mail_cmd_free(struct doveadm_mail_cmd_context *ctx)
{ {
const struct doveadm_mail_cmd *cmd; i_stream_unref(&ctx->users_list_input);
i_stream_unref(&ctx->cmd_input);
array_foreach(&doveadm_mail_cmds, cmd) { pool_unref(&ctx->pool);
if (cmd->usage_args == &doveadm_mail_cmd_hide)
continue;
str_printfa(out, "%s\t"DOVEADM_CMD_MAIL_USAGE_PREFIX, cmd->name);
if (cmd->usage_args != NULL)
str_append(out, cmd->usage_args);
str_append_c(out, '\n');
}
} }
void doveadm_mail_help(const struct doveadm_mail_cmd *cmd) void doveadm_mail_help(const struct doveadm_mail_cmd *cmd)
{ {
fprintf(stderr, "doveadm %s "DOVEADM_CMD_MAIL_USAGE_PREFIX" %s\n", fprintf(stderr, "doveadm %s "DOVEADM_CMD_MAIL_USAGE_PREFIX" %s\n",
cmd->name, cmd->usage_args == NULL ? "" : cmd->usage_args); cmd->name, cmd->usage_args == NULL ? "" : cmd->usage_args);
lib_exit(EX_USAGE); lib_exit(EX_USAGE);
} }
void doveadm_mail_try_help_name(const char *cmd_name) void doveadm_mail_try_help_name(const char *cmd_name)
{ {
const struct doveadm_cmd_ver2 *cmd2; const struct doveadm_cmd_ver2 *cmd2;
const struct doveadm_mail_cmd *cmd;
cmd2 = doveadm_cmd_find_ver2(cmd_name); cmd2 = doveadm_cmd_find_ver2(cmd_name);
if (cmd2 != NULL) if (cmd2 != NULL)
help_ver2(cmd2); help_ver2(cmd2);
cmd = doveadm_mail_cmd_find(cmd_name);
if (cmd != NULL)
doveadm_mail_help(cmd);
}
bool doveadm_mail_has_subcommands(const char *cmd_name)
{
const struct doveadm_mail_cmd *cmd;
size_t len = strlen(cmd_name);
array_foreach(&doveadm_mail_cmds, cmd) {
if (strncmp(cmd->name, cmd_name, len) == 0 &&
cmd->name[len] == ' ')
return TRUE;
}
return FALSE;
} }
void doveadm_mail_help_name(const char *cmd_name) void doveadm_mail_help_name(const char *cmd_name)
{ {
doveadm_mail_try_help_name(cmd_name); doveadm_mail_try_help_name(cmd_name);
i_fatal("Missing help for command %s", cmd_name); i_fatal("Missing help for command %s", cmd_name);
} }
static struct doveadm_cmd_ver2 doveadm_cmd_force_resync_ver2 = { static struct doveadm_cmd_ver2 doveadm_cmd_force_resync_ver2 = {
.name = "force-resync", .name = "force-resync",
skipping to change at line 916 skipping to change at line 734
static struct doveadm_cmd_ver2 doveadm_cmd_purge_ver2 = { static struct doveadm_cmd_ver2 doveadm_cmd_purge_ver2 = {
.name = "purge", .name = "purge",
.mail_cmd = cmd_purge_alloc, .mail_cmd = cmd_purge_alloc,
.usage = DOVEADM_CMD_MAIL_USAGE_PREFIX, .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX,
DOVEADM_CMD_PARAMS_START DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_MAIL_COMMON DOVEADM_CMD_MAIL_COMMON
DOVEADM_CMD_PARAMS_END DOVEADM_CMD_PARAMS_END
}; };
static struct doveadm_mail_cmd *mail_commands[] = {
&cmd_batch,
&cmd_dsync_backup,
&cmd_dsync_mirror,
&cmd_dsync_server
};
static struct doveadm_cmd_ver2 *mail_commands_ver2[] = { static struct doveadm_cmd_ver2 *mail_commands_ver2[] = {
&doveadm_cmd_batch,
&doveadm_cmd_dsync_backup,
&doveadm_cmd_dsync_mirror,
&doveadm_cmd_dsync_server,
&doveadm_cmd_mailbox_metadata_set_ver2, &doveadm_cmd_mailbox_metadata_set_ver2,
&doveadm_cmd_mailbox_metadata_unset_ver2, &doveadm_cmd_mailbox_metadata_unset_ver2,
&doveadm_cmd_mailbox_metadata_get_ver2, &doveadm_cmd_mailbox_metadata_get_ver2,
&doveadm_cmd_mailbox_metadata_list_ver2, &doveadm_cmd_mailbox_metadata_list_ver2,
&doveadm_cmd_mailbox_status_ver2, &doveadm_cmd_mailbox_status_ver2,
&doveadm_cmd_mailbox_list_ver2, &doveadm_cmd_mailbox_list_ver2,
&doveadm_cmd_mailbox_create_ver2, &doveadm_cmd_mailbox_create_ver2,
&doveadm_cmd_mailbox_delete_ver2, &doveadm_cmd_mailbox_delete_ver2,
&doveadm_cmd_mailbox_rename_ver2, &doveadm_cmd_mailbox_rename_ver2,
&doveadm_cmd_mailbox_subscribe_ver2, &doveadm_cmd_mailbox_subscribe_ver2,
skipping to change at line 962 skipping to change at line 777
&doveadm_cmd_mailbox_cache_decision, &doveadm_cmd_mailbox_cache_decision,
&doveadm_cmd_mailbox_cache_remove, &doveadm_cmd_mailbox_cache_remove,
&doveadm_cmd_mailbox_cache_purge, &doveadm_cmd_mailbox_cache_purge,
&doveadm_cmd_rebuild_attachments, &doveadm_cmd_rebuild_attachments,
}; };
void doveadm_mail_init(void) void doveadm_mail_init(void)
{ {
unsigned int i; unsigned int i;
i_array_init(&doveadm_mail_cmds, 32);
for (i = 0; i < N_ELEMENTS(mail_commands); i++)
doveadm_mail_register_cmd(mail_commands[i]);
for (i = 0; i < N_ELEMENTS(mail_commands_ver2); i++) for (i = 0; i < N_ELEMENTS(mail_commands_ver2); i++)
doveadm_cmd_register_ver2(mail_commands_ver2[i]); doveadm_cmd_register_ver2(mail_commands_ver2[i]);
} }
void doveadm_mail_init_finish(void) void doveadm_mail_init_finish(void)
{ {
struct module_dir_load_settings mod_set; struct module_dir_load_settings mod_set;
i_zero(&mod_set); i_zero(&mod_set);
mod_set.abi_version = DOVECOT_ABI_VERSION; mod_set.abi_version = DOVECOT_ABI_VERSION;
skipping to change at line 994 skipping to change at line 805
doveadm_settings->mail_plugins, doveadm_settings->mail_plugins,
&mod_set); &mod_set);
/* keep mail_storage_init() referenced so that its _deinit() doesn't /* keep mail_storage_init() referenced so that its _deinit() doesn't
try to free doveadm plugins' hooks too early. */ try to free doveadm plugins' hooks too early. */
mail_storage_init(); mail_storage_init();
} }
void doveadm_mail_deinit(void) void doveadm_mail_deinit(void)
{ {
mail_storage_deinit(); mail_storage_deinit();
array_free(&doveadm_mail_cmds); module_dir_unload(&mail_storage_service_modules);
}
static int doveadm_cmd_parse_arg(struct doveadm_mail_cmd_context *mctx,
const struct doveadm_cmd_param *arg,
ARRAY_TYPE(const_string) *full_args)
{
const char *short_opt_str =
p_strdup_printf(mctx->pool, "-%c", arg->short_opt);
const char *arg_value = NULL;
switch (arg->type) {
case CMD_PARAM_BOOL:
break;
case CMD_PARAM_INT64:
arg_value = dec2str(arg->value.v_int64);
break;
case CMD_PARAM_IP:
arg_value = net_ip2addr(&arg->value.v_ip);
break;
case CMD_PARAM_STR:
arg_value = arg->value.v_string;
break;
case CMD_PARAM_ARRAY: {
const char *str;
array_foreach_elem(&arg->value.v_array, str) {
optarg = (char *)str;
if (!mctx->v.parse_arg(mctx, arg->short_opt))
return -1;
array_push_back(full_args, &short_opt_str);
array_push_back(full_args, &str);
}
return 0;
}
default:
i_panic("Cannot convert parameter %s to short opt", arg->name);
}
optarg = (char *)arg_value;
if (!mctx->v.parse_arg(mctx, arg->short_opt))
return -1;
array_push_back(full_args, &short_opt_str);
if (arg_value != NULL)
array_push_back(full_args, &arg_value);
return 0;
} }
void void
doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx)
{ {
struct doveadm_mail_cmd_context *mctx; struct doveadm_mail_cmd_context *mctx;
const char *wildcard_user; const char *wildcard_user;
const char *fieldstr; const char *fieldstr;
ARRAY_TYPE(const_string) pargv, full_args; ARRAY_TYPE(const_string) pargv, full_args;
int i; int i;
skipping to change at line 1095 skipping to change at line 952
i_stream_ref(mctx->cmd_input); i_stream_ref(mctx->cmd_input);
} else if (strcmp(arg->name, "trans-flags") == 0) { } else if (strcmp(arg->name, "trans-flags") == 0) {
/* This parameter allows to set additional /* This parameter allows to set additional
* mailbox transaction flags. */ * mailbox transaction flags. */
mctx->transaction_flags = arg->value.v_int64; mctx->transaction_flags = arg->value.v_int64;
/* Keep all named special parameters above this line */ /* Keep all named special parameters above this line */
} else if (mctx->v.parse_arg != NULL && arg->short_opt != '\0') { } else if (mctx->v.parse_arg != NULL && arg->short_opt != '\0') {
const char *short_opt_str = p_strdup_printf( if (doveadm_cmd_parse_arg(mctx, arg, &full_args) < 0) {
mctx->pool, "-%c", arg->short_opt);
switch(arg->type) {
case CMD_PARAM_BOOL:
optarg = NULL;
break;
case CMD_PARAM_INT64:
optarg = (char*)dec2str(arg->value.v_int64);
break;
case CMD_PARAM_IP:
optarg = (char*)net_ip2addr(&arg->value.v_ip);
break;
case CMD_PARAM_STR:
optarg = (char*)arg->value.v_string;
break;
default:
i_panic("Cannot convert parameter %s to short opt
",
arg->name);
}
if (!mctx->v.parse_arg(mctx, arg->short_opt)) {
i_error("Invalid parameter %c", arg->short_opt); i_error("Invalid parameter %c", arg->short_opt);
doveadm_mail_cmd_free(mctx); doveadm_mail_cmd_free(mctx);
doveadm_exit_code = EX_USAGE; doveadm_exit_code = EX_USAGE;
return;
} }
array_push_back(&full_args, &short_opt_str);
if (arg->type == CMD_PARAM_STR)
array_push_back(&full_args,
&arg->value.v_string);
} else if ((arg->flags & CMD_PARAM_FLAG_POSITIONAL) != 0) { } else if ((arg->flags & CMD_PARAM_FLAG_POSITIONAL) != 0) {
/* feed this into pargv */ /* feed this into pargv */
if (arg->type == CMD_PARAM_ARRAY) if (arg->type == CMD_PARAM_ARRAY)
array_append_array(&pargv, &arg->value.v_array); array_append_array(&pargv, &arg->value.v_array);
else if (arg->type == CMD_PARAM_STR) else if (arg->type == CMD_PARAM_STR)
array_push_back(&pargv, &arg->value.v_string); array_push_back(&pargv, &arg->value.v_string);
} else { } else {
doveadm_exit_code = EX_USAGE; doveadm_exit_code = EX_USAGE;
i_error("invalid parameter: %s", arg->name); i_error("invalid parameter: %s", arg->name);
doveadm_mail_cmd_free(mctx); doveadm_mail_cmd_free(mctx);
 End of changes. 17 change blocks. 
237 lines changed or deleted 66 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)