Also plugins can now override the list of -A users.
--HG--
branch : HEAD
#include "doveadm-mail-iter.h"
#include "doveadm-mail.h"
-struct altmove_cmd_context {
- struct doveadm_mail_cmd_context ctx;
- struct mail_search_args *search_args;
-};
-
static int
cmd_altmove_box(const struct mailbox_info *info,
struct mail_search_args *search_args)
}
static void
-cmd_altmove_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
+cmd_altmove_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user)
{
- struct altmove_cmd_context *ctx = (struct altmove_cmd_context *)_ctx;
const enum mailbox_list_iter_flags iter_flags =
MAILBOX_LIST_ITER_RAW_LIST |
MAILBOX_LIST_ITER_VIRTUAL_NAMES |
}
}
-static void cmd_altmove_init(struct doveadm_mail_cmd_context *_ctx,
+static void cmd_altmove_init(struct doveadm_mail_cmd_context *ctx,
const char *const args[])
{
- struct altmove_cmd_context *ctx = (struct altmove_cmd_context *)_ctx;
-
if (args[0] == NULL)
doveadm_mail_help_name("altmove");
ctx->search_args = doveadm_mail_build_search_args(args);
static struct doveadm_mail_cmd_context *cmd_altmove_alloc(void)
{
- struct altmove_cmd_context *ctx;
+ struct doveadm_mail_cmd_context *ctx;
- ctx = doveadm_mail_cmd_alloc(struct altmove_cmd_context);
- ctx->ctx.init = cmd_altmove_init;
- ctx->ctx.run = cmd_altmove_run;
- return &ctx->ctx;
+ ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
+ ctx->v.init = cmd_altmove_init;
+ ctx->v.run = cmd_altmove_run;
+ return ctx;
}
struct doveadm_mail_cmd cmd_altmove = {
#include "doveadm-mail-iter.h"
#include "doveadm-mail.h"
-struct expunge_cmd_context {
- struct doveadm_mail_cmd_context ctx;
- struct mail_search_args *search_args;
-};
-
static int
cmd_expunge_box(const struct mailbox_info *info,
struct mail_search_args *search_args)
}
static void
-cmd_expunge_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
+cmd_expunge_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user)
{
- struct expunge_cmd_context *ctx = (struct expunge_cmd_context *)_ctx;
const enum mailbox_list_iter_flags iter_flags =
MAILBOX_LIST_ITER_RAW_LIST |
MAILBOX_LIST_ITER_VIRTUAL_NAMES |
doveadm_mail_list_iter_deinit(&iter);
}
-static void cmd_expunge_init(struct doveadm_mail_cmd_context *_ctx,
+static void cmd_expunge_init(struct doveadm_mail_cmd_context *ctx,
const char *const args[])
{
- struct expunge_cmd_context *ctx = (struct expunge_cmd_context *)_ctx;
-
if (args[0] == NULL)
doveadm_mail_help_name("expunge");
static struct doveadm_mail_cmd_context *cmd_expunge_alloc(void)
{
- struct expunge_cmd_context *ctx;
+ struct doveadm_mail_cmd_context *ctx;
- ctx = doveadm_mail_cmd_alloc(struct expunge_cmd_context);
- ctx->ctx.init = cmd_expunge_init;
- ctx->ctx.run = cmd_expunge_run;
- return &ctx->ctx;
+ ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
+ ctx->v.init = cmd_expunge_init;
+ ctx->v.run = cmd_expunge_run;
+ return ctx;
}
struct doveadm_mail_cmd cmd_expunge = {
struct fetch_cmd_context {
struct doveadm_mail_cmd_context ctx;
- struct mail_search_args *search_args;
struct ostream *output;
struct mail *mail;
struct mail *mail;
struct mailbox_header_lookup_ctx *headers = NULL;
- if (doveadm_mail_iter_init(info, ctx->search_args, &trans, &iter) < 0)
+ if (doveadm_mail_iter_init(info, ctx->ctx.search_args,
+ &trans, &iter) < 0)
return -1;
if (array_count(&ctx->header_fields) > 1) {
struct doveadm_mail_list_iter *iter;
const struct mailbox_info *info;
- iter = doveadm_mail_list_iter_init(user, ctx->search_args, iter_flags);
+ iter = doveadm_mail_list_iter_init(user, _ctx->search_args, iter_flags);
while ((info = doveadm_mail_list_iter_next(iter)) != NULL) T_BEGIN {
(void)cmd_fetch_box(ctx, info);
} T_END;
doveadm_mail_help_name("fetch");
parse_fetch_fields(ctx, fetch_fields);
- ctx->search_args = doveadm_mail_build_search_args(args + 1);
+ _ctx->search_args = doveadm_mail_build_search_args(args + 1);
ctx->output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
ctx->hdr = str_new(default_pool, 512);
- if (search_args_have_unique_fetch(ctx->search_args))
+ if (search_args_have_unique_fetch(_ctx->search_args))
ctx->prefix = "";
else {
random_fill_weak(prefix_buf, sizeof(prefix_buf));
struct fetch_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct fetch_cmd_context);
- ctx->ctx.init = cmd_fetch_init;
- ctx->ctx.run = cmd_fetch_run;
- ctx->ctx.deinit = cmd_fetch_deinit;
+ ctx->ctx.v.init = cmd_fetch_init;
+ ctx->ctx.v.run = cmd_fetch_run;
+ ctx->ctx.v.deinit = cmd_fetch_deinit;
return &ctx->ctx;
}
ctx = doveadm_mail_cmd_alloc_size(size);
ctx->getopt_args = "78s";
- ctx->parse_arg = cmd_mailbox_parse_arg;
+ ctx->v.parse_arg = cmd_mailbox_parse_arg;
return ctx;
}
struct list_cmd_context *ctx;
ctx = doveadm_mailbox_cmd_alloc(struct list_cmd_context);
- ctx->ctx.ctx.init = cmd_mailbox_list_init;
- ctx->ctx.ctx.run = cmd_mailbox_list_run;
+ ctx->ctx.ctx.v.init = cmd_mailbox_list_init;
+ ctx->ctx.ctx.v.run = cmd_mailbox_list_run;
return &ctx->ctx.ctx;
}
struct mailbox_cmd_context *ctx;
ctx = doveadm_mailbox_cmd_alloc(struct mailbox_cmd_context);
- ctx->ctx.ctx.init = cmd_mailbox_create_init;
- ctx->ctx.ctx.run = cmd_mailbox_create_run;
+ ctx->ctx.ctx.v.init = cmd_mailbox_create_init;
+ ctx->ctx.ctx.v.run = cmd_mailbox_create_run;
p_array_init(&ctx->mailboxes, ctx->ctx.ctx.pool, 16);
return &ctx->ctx.ctx;
}
struct mailbox_cmd_context *ctx;
ctx = doveadm_mailbox_cmd_alloc(struct mailbox_cmd_context);
- ctx->ctx.ctx.init = cmd_mailbox_delete_init;
- ctx->ctx.ctx.run = cmd_mailbox_delete_run;
+ ctx->ctx.ctx.v.init = cmd_mailbox_delete_init;
+ ctx->ctx.ctx.v.run = cmd_mailbox_delete_run;
p_array_init(&ctx->mailboxes, ctx->ctx.ctx.pool, 16);
return &ctx->ctx.ctx;
}
struct rename_cmd_context *ctx;
ctx = doveadm_mailbox_cmd_alloc(struct rename_cmd_context);
- ctx->ctx.ctx.init = cmd_mailbox_rename_init;
- ctx->ctx.ctx.run = cmd_mailbox_rename_run;
+ ctx->ctx.ctx.v.init = cmd_mailbox_rename_init;
+ ctx->ctx.ctx.v.run = cmd_mailbox_rename_run;
return &ctx->ctx.ctx;
}
ctx->ctx.subscriptions = subscriptions;
ctx->ctx.ctx.getopt_args = "78";
- ctx->ctx.ctx.parse_arg = cmd_mailbox_parse_arg;
- ctx->ctx.ctx.init = cmd_mailbox_subscribe_init;
- ctx->ctx.ctx.run = cmd_mailbox_subscribe_run;
+ ctx->ctx.ctx.v.parse_arg = cmd_mailbox_parse_arg;
+ ctx->ctx.ctx.v.init = cmd_mailbox_subscribe_init;
+ ctx->ctx.ctx.v.run = cmd_mailbox_subscribe_run;
p_array_init(&ctx->mailboxes, ctx->ctx.ctx.pool, 16);
return &ctx->ctx.ctx;
}
#include <stdio.h>
-struct search_cmd_context {
- struct doveadm_mail_cmd_context ctx;
- struct mail_search_args *search_args;
-};
-
static int
cmd_search_box(const struct mailbox_info *info,
struct mail_search_args *search_args)
}
static void
-cmd_search_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
+cmd_search_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user)
{
- struct search_cmd_context *ctx = (struct search_cmd_context *)_ctx;
const enum mailbox_list_iter_flags iter_flags =
MAILBOX_LIST_ITER_RAW_LIST |
MAILBOX_LIST_ITER_VIRTUAL_NAMES |
doveadm_mail_list_iter_deinit(&iter);
}
-static void cmd_search_init(struct doveadm_mail_cmd_context *_ctx,
+static void cmd_search_init(struct doveadm_mail_cmd_context *ctx,
const char *const args[])
{
- struct search_cmd_context *ctx = (struct search_cmd_context *)_ctx;
-
if (args[0] == NULL)
doveadm_mail_help_name("search");
static struct doveadm_mail_cmd_context *cmd_search_alloc(void)
{
- struct search_cmd_context *ctx;
+ struct doveadm_mail_cmd_context *ctx;
- ctx = doveadm_mail_cmd_alloc(struct search_cmd_context);
- ctx->ctx.init = cmd_search_init;
- ctx->ctx.run = cmd_search_run;
- return &ctx->ctx;
+ ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
+ ctx->v.init = cmd_search_init;
+ ctx->v.run = cmd_search_run;
+ return ctx;
}
struct doveadm_mail_cmd cmd_search = {
#include <stdlib.h>
ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
+void (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
+struct doveadm_mail_cmd_module_register
+ doveadm_mail_cmd_module_register = { 0 };
static int killed_signo = 0;
struct doveadm_mail_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
- ctx->run = cmd_purge_run;
+ ctx->v.run = cmd_purge_run;
return ctx;
}
struct force_resync_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct force_resync_cmd_context);
- ctx->ctx.init = cmd_force_resync_init;
- ctx->ctx.run = cmd_force_resync_run;
+ ctx->ctx.v.init = cmd_force_resync_init;
+ ctx->ctx.v.run = cmd_force_resync_run;
return &ctx->ctx;
}
static int
doveadm_mail_next_user(struct doveadm_mail_cmd_context *ctx,
- struct mail_storage_service_ctx *storage_service,
const struct mail_storage_service_input *input,
const char **error_r)
{
int ret;
i_set_failure_prefix(t_strdup_printf("doveadm(%s): ", input->username));
- ret = mail_storage_service_lookup(storage_service, input,
+
+ ret = mail_storage_service_lookup(ctx->storage_service, input,
&service_user, &error);
if (ret <= 0) {
if (ret < 0) {
return ret;
}
- ret = mail_storage_service_next(storage_service, service_user,
+ ret = mail_storage_service_next(ctx->storage_service, service_user,
&mail_user);
if (ret < 0) {
*error_r = "User init failed";
return ret;
}
- ctx->run(ctx, mail_user);
- mail_storage_service_user_free(&service_user);
+ ctx->v.run(ctx, mail_user);
mail_user_unref(&mail_user);
+ mail_storage_service_user_free(&service_user);
return 1;
}
const char *username,
enum mail_storage_service_flags service_flags)
{
- struct mail_storage_service_ctx *storage_service;
struct mail_storage_service_input input;
const char *error;
int ret;
memset(&input, 0, sizeof(input));
input.username = username;
- storage_service = mail_storage_service_init(master_service, NULL,
- service_flags);
- ret = doveadm_mail_next_user(ctx, storage_service, &input, &error);
+ ctx->storage_service = mail_storage_service_init(master_service, NULL,
+ service_flags);
+ if (hook_doveadm_mail_init != NULL)
+ hook_doveadm_mail_init(ctx);
+
+ ret = doveadm_mail_next_user(ctx, &input, &error);
if (ret < 0)
i_fatal("%s", error);
else if (ret == 0)
i_fatal("User no longer exists");
- mail_storage_service_deinit(&storage_service);
+ mail_storage_service_deinit(&ctx->storage_service);
}
static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
enum mail_storage_service_flags service_flags)
{
struct mail_storage_service_input input;
- struct mail_storage_service_ctx *storage_service;
unsigned int user_idx, user_count, interval, n;
const char *user, *error;
int ret;
memset(&input, 0, sizeof(input));
input.service = "doveadm";
- storage_service = mail_storage_service_init(master_service, NULL,
- service_flags);
-
+ ctx->storage_service = mail_storage_service_init(master_service, NULL,
+ service_flags);
lib_signals_set_handler(SIGINT, FALSE, sig_die, NULL);
lib_signals_set_handler(SIGTERM, FALSE, sig_die, NULL);
- user_count = mail_storage_service_all_init(storage_service);
+ if (hook_doveadm_mail_init != NULL)
+ hook_doveadm_mail_init(ctx);
+
+ user_count = mail_storage_service_all_init(ctx->storage_service);
n = user_count / 10000;
for (interval = 10; n > 0 && interval < 1000; interval *= 10)
n /= 10;
user_idx = 0;
- while ((ret = mail_storage_service_all_next(storage_service,
- &user)) > 0) {
+ while ((ret = ctx->v.get_next_user(ctx, &user)) > 0) {
input.username = user;
T_BEGIN {
- ret = doveadm_mail_next_user(ctx, storage_service,
- &input, &error);
+ ret = doveadm_mail_next_user(ctx, &input, &error);
if (ret < 0)
i_error("%s", error);
else if (ret == 0)
i_set_failure_prefix("doveadm: ");
if (ret < 0)
i_error("Failed to iterate through some users");
- mail_storage_service_deinit(&storage_service);
+ mail_storage_service_deinit(&ctx->storage_service);
+}
+
+static void
+doveadm_mail_cmd_init_noop(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED,
+ const char *const args[] ATTR_UNUSED)
+{
+}
+
+static int
+doveadm_mail_cmd_get_next_user(struct doveadm_mail_cmd_context *ctx,
+ const char **username_r)
+{
+ return mail_storage_service_all_next(ctx->storage_service, username_r);
+}
+
+static void
+doveadm_mail_cmd_deinit_noop(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED)
+{
}
static void
service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
ctx = cmd->alloc();
+ if (ctx->v.init == NULL)
+ ctx->v.init = doveadm_mail_cmd_init_noop;
+ if (ctx->v.get_next_user == NULL)
+ ctx->v.get_next_user = doveadm_mail_cmd_get_next_user;
+ if (ctx->v.deinit == NULL)
+ ctx->v.deinit = doveadm_mail_cmd_deinit_noop;
+
+ p_array_init(&ctx->module_contexts, ctx->pool, 5);
+
getopt_args = t_strconcat("Au:", ctx->getopt_args, NULL);
username = getenv("USER");
while ((c = getopt(argc, argv, getopt_args)) > 0) {
username = optarg;
break;
default:
- if (ctx->parse_arg == NULL || !ctx->parse_arg(ctx, c))
+ if (ctx->v.parse_arg == NULL ||
+ !ctx->v.parse_arg(ctx, c))
doveadm_mail_help(cmd);
}
}
cmd->name, argv[0]);
}
- if (ctx->init != NULL)
- ctx->init(ctx, (const void *)argv);
+ ctx->v.init(ctx, (const void *)argv);
+
if (!all_users) {
doveadm_mail_single_user(ctx, username, service_flags);
} else {
service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
doveadm_mail_all_users(ctx, service_flags);
}
- if (ctx->deinit != NULL)
- ctx->deinit(ctx);
+ ctx->v.deinit(ctx);
}
static bool
#define DOVEADM_MAIL_H
#include "doveadm.h"
+#include "module-context.h"
struct mail_user;
+struct mail_storage_service_ctx;
+struct mail_storage_service_input;
+struct mail_storage_service_user;
struct doveadm_mail_cmd_context;
-struct doveadm_mail_cmd_context {
- pool_t pool;
- const char *getopt_args;
-
+struct doveadm_mail_cmd_vfuncs {
bool (*parse_arg)(struct doveadm_mail_cmd_context *ctx,int c);
void (*init)(struct doveadm_mail_cmd_context *ctx,
const char *const args[]);
+ int (*get_next_user)(struct doveadm_mail_cmd_context *ctx,
+ const char **username_r);
void (*run)(struct doveadm_mail_cmd_context *ctx,
struct mail_user *mail_user);
void (*deinit)(struct doveadm_mail_cmd_context *ctx);
};
+struct doveadm_mail_cmd_module_register {
+ unsigned int id;
+};
+
+union doveadm_mail_cmd_module_context {
+ struct doveadm_mail_cmd_vfuncs super;
+ struct doveadm_mail_cmd_module_register *reg;
+};
+
+struct doveadm_mail_cmd_context {
+ pool_t pool;
+ const char *getopt_args;
+ struct mail_storage_service_ctx *storage_service;
+ /* search args aren't set for all mail commands */
+ struct mail_search_args *search_args;
+
+ struct doveadm_mail_cmd_vfuncs v;
+
+ ARRAY_DEFINE(module_contexts, union doveadm_mail_cmd_module_context *);
+};
+
struct doveadm_mail_cmd {
struct doveadm_mail_cmd_context *(*alloc)(void);
const char *name;
ARRAY_DEFINE_TYPE(doveadm_mail_cmd, struct doveadm_mail_cmd);
extern ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
+extern void (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
+extern struct doveadm_mail_cmd_module_register doveadm_mail_cmd_module_register;
bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]);
void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd);
DEF(SET_STR, base_dir),
DEF(SET_STR, mail_plugins),
DEF(SET_STR, mail_plugin_dir),
+ { SET_STRLIST, "plugin", offsetof(struct doveadm_settings, plugin_envs), NULL },
SETTING_DEFINE_LIST_END
};
const struct doveadm_settings doveadm_default_settings = {
.base_dir = PKG_RUNDIR,
.mail_plugins = "",
- .mail_plugin_dir = MODULEDIR
+ .mail_plugin_dir = MODULEDIR,
+
+ .plugin_envs = ARRAY_INIT
};
const struct setting_parser_info doveadm_setting_parser_info = {
const char *base_dir;
const char *mail_plugins;
const char *mail_plugin_dir;
+
+ ARRAY_DEFINE(plugin_envs, const char *);
};
extern const struct setting_parser_info doveadm_setting_parser_info;
return buf;
}
+const char *doveadm_plugin_getenv(const char *name)
+{
+ const char *const *envs;
+ unsigned int i, count;
+
+ if (!array_is_created(&doveadm_settings->plugin_envs))
+ return NULL;
+
+ envs = array_get(&doveadm_settings->plugin_envs, &count);
+ for (i = 0; i < count; i += 2) {
+ if (strcmp(envs[i], name) == 0)
+ return envs[i+1];
+ }
+ return NULL;
+}
+
static void cmd_help(int argc, char *argv[])
{
const struct doveadm_cmd *cmd;
void help(const struct doveadm_cmd *cmd);
const char *unixdate2str(time_t timestamp);
+const char *doveadm_plugin_getenv(const char *name);
void doveadm_register_director_commands(void);
#endif