Mercurial > dovecot > core-2.2
changeset 11247:f05909834219 HEAD
doveadm: Changed mail command handler API.
This should help add some new future features.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 30 Apr 2010 19:14:57 +0300 |
parents | f195e11fd919 |
children | 1fd45deee948 |
files | src/doveadm/doveadm-mail-altmove.c src/doveadm/doveadm-mail-expunge.c src/doveadm/doveadm-mail-fetch.c src/doveadm/doveadm-mail-list.c src/doveadm/doveadm-mail-search.c src/doveadm/doveadm-mail.c src/doveadm/doveadm-mail.h src/plugins/quota/doveadm-quota.c |
diffstat | 8 files changed, 281 insertions(+), 123 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doveadm/doveadm-mail-altmove.c Fri Apr 30 18:01:08 2010 +0300 +++ b/src/doveadm/doveadm-mail-altmove.c Fri Apr 30 19:14:57 2010 +0300 @@ -9,6 +9,11 @@ #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) @@ -41,14 +46,15 @@ } } -void cmd_altmove(struct mail_user *user, const char *const args[]) +static void +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 | MAILBOX_LIST_ITER_NO_AUTO_INBOX | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - struct mail_search_args *search_args; struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; struct mail_namespace *ns, *prev_ns = NULL; @@ -56,12 +62,8 @@ struct mail_storage *const *storages; unsigned int i, count; - if (args[0] == NULL) - doveadm_mail_help_name("altmove"); - search_args = doveadm_mail_build_search_args(args); - t_array_init(&purged_storages, 8); - iter = doveadm_mail_list_iter_init(user, 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 { if (info->ns != prev_ns) { if (prev_ns != NULL) { @@ -71,7 +73,7 @@ } prev_ns = info->ns; } - (void)cmd_altmove_box(info, search_args); + (void)cmd_altmove_box(info, ctx->search_args); } T_END; doveadm_mail_list_iter_deinit(&iter); @@ -91,3 +93,16 @@ } } } + +struct doveadm_mail_cmd_context *cmd_altmove(const char *const args[]) +{ + struct altmove_cmd_context *ctx; + + if (args[0] == NULL) + doveadm_mail_help_name("altmove"); + + ctx = doveadm_mail_cmd_init(struct altmove_cmd_context); + ctx->ctx.run = cmd_altmove_run; + ctx->search_args = doveadm_mail_build_search_args(args); + return &ctx->ctx; +}
--- a/src/doveadm/doveadm-mail-expunge.c Fri Apr 30 18:01:08 2010 +0300 +++ b/src/doveadm/doveadm-mail-expunge.c Fri Apr 30 19:14:57 2010 +0300 @@ -9,6 +9,11 @@ #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) @@ -161,35 +166,45 @@ return FALSE; } -void cmd_expunge(struct mail_user *user, const char *const args[]) +static void +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 | MAILBOX_LIST_ITER_NO_AUTO_INBOX | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - struct mail_search_args *search_args; struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; - if (args[0] == NULL) - doveadm_mail_help_name("expunge"); - search_args = doveadm_mail_build_search_args(args); - mail_search_args_simplify(search_args); - - if (!expunge_search_args_is_mailbox_ok(search_args->args)) { + if (!expunge_search_args_is_mailbox_ok(ctx->search_args->args)) { i_fatal("expunge: To avoid accidents, search query " "must contain MAILBOX in all search branches"); } - if (!expunge_search_args_is_msgset_ok(search_args->args)) { + if (!expunge_search_args_is_msgset_ok(ctx->search_args->args)) { i_fatal("expunge: To avoid accidents, each branch in " "search query must contain something else " "besides MAILBOX"); } - iter = doveadm_mail_list_iter_init(user, 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_expunge_box(info, search_args); + (void)cmd_expunge_box(info, ctx->search_args); } T_END; doveadm_mail_list_iter_deinit(&iter); } + +struct doveadm_mail_cmd_context *cmd_expunge(const char *const args[]) +{ + struct expunge_cmd_context *ctx; + + if (args[0] == NULL) + doveadm_mail_help_name("expunge"); + + ctx = doveadm_mail_cmd_init(struct expunge_cmd_context); + ctx->ctx.run = cmd_expunge_run; + ctx->search_args = doveadm_mail_build_search_args(args); + mail_search_args_simplify(ctx->search_args); + return &ctx->ctx; +}
--- a/src/doveadm/doveadm-mail-fetch.c Fri Apr 30 18:01:08 2010 +0300 +++ b/src/doveadm/doveadm-mail-fetch.c Fri Apr 30 19:14:57 2010 +0300 @@ -17,7 +17,9 @@ #include <stdio.h> -struct fetch_context { +struct fetch_cmd_context { + struct doveadm_mail_cmd_context ctx; + struct mail_search_args *search_args; struct ostream *output; struct mail *mail; @@ -31,7 +33,7 @@ bool print_field_prefix; }; -static int fetch_mailbox(struct fetch_context *ctx) +static int fetch_mailbox(struct fetch_cmd_context *ctx) { const char *value; @@ -41,7 +43,7 @@ return 0; } -static int fetch_mailbox_guid(struct fetch_context *ctx) +static int fetch_mailbox_guid(struct fetch_cmd_context *ctx) { uint8_t guid[MAIL_GUID_128_SIZE]; @@ -51,19 +53,19 @@ return 0; } -static int fetch_seq(struct fetch_context *ctx) +static int fetch_seq(struct fetch_cmd_context *ctx) { str_printfa(ctx->hdr, "%u", ctx->mail->seq); return 0; } -static int fetch_uid(struct fetch_context *ctx) +static int fetch_uid(struct fetch_cmd_context *ctx) { str_printfa(ctx->hdr, "%u", ctx->mail->seq); return 0; } -static int fetch_guid(struct fetch_context *ctx) +static int fetch_guid(struct fetch_cmd_context *ctx) { const char *value; @@ -73,20 +75,20 @@ return 0; } -static int fetch_flags(struct fetch_context *ctx) +static int fetch_flags(struct fetch_cmd_context *ctx) { imap_write_flags(ctx->hdr, mail_get_flags(ctx->mail), mail_get_keywords(ctx->mail)); return 0; } -static void flush_hdr(struct fetch_context *ctx) +static void flush_hdr(struct fetch_cmd_context *ctx) { o_stream_send(ctx->output, str_data(ctx->hdr), str_len(ctx->hdr)); str_truncate(ctx->hdr, 0); } -static int fetch_hdr(struct fetch_context *ctx) +static int fetch_hdr(struct fetch_cmd_context *ctx) { struct istream *input; struct message_size hdr_size; @@ -112,7 +114,7 @@ return ret; } -static int fetch_body(struct fetch_context *ctx) +static int fetch_body(struct fetch_cmd_context *ctx) { struct istream *input; struct message_size hdr_size; @@ -137,7 +139,7 @@ return ret; } -static int fetch_text(struct fetch_context *ctx) +static int fetch_text(struct fetch_cmd_context *ctx) { struct istream *input; int ret = 0; @@ -160,7 +162,7 @@ return ret; } -static int fetch_size_physical(struct fetch_context *ctx) +static int fetch_size_physical(struct fetch_cmd_context *ctx) { uoff_t size; @@ -170,7 +172,7 @@ return 0; } -static int fetch_size_virtual(struct fetch_context *ctx) +static int fetch_size_virtual(struct fetch_cmd_context *ctx) { uoff_t size; @@ -180,7 +182,7 @@ return 0; } -static int fetch_date_received(struct fetch_context *ctx) +static int fetch_date_received(struct fetch_cmd_context *ctx) { time_t t; @@ -190,7 +192,7 @@ return 0; } -static int fetch_date_sent(struct fetch_context *ctx) +static int fetch_date_sent(struct fetch_cmd_context *ctx) { time_t t; int tz; @@ -206,7 +208,7 @@ return 0; } -static int fetch_date_saved(struct fetch_context *ctx) +static int fetch_date_saved(struct fetch_cmd_context *ctx) { time_t t; @@ -219,7 +221,7 @@ struct fetch_field { const char *name; enum mail_fetch_field wanted_fields; - int (*print)(struct fetch_context *ctx); + int (*print)(struct fetch_cmd_context *ctx); }; static const struct fetch_field fetch_fields[] = { @@ -261,7 +263,7 @@ fprintf(stderr, "\n"); } -static void parse_fetch_fields(struct fetch_context *ctx, const char *str) +static void parse_fetch_fields(struct fetch_cmd_context *ctx, const char *str) { const char *const *fields, *name; const struct fetch_field *field; @@ -283,7 +285,7 @@ ctx->print_field_prefix = array_count(&ctx->fields) > 1; } -static void cmd_fetch_mail(struct fetch_context *ctx) +static void cmd_fetch_mail(struct fetch_cmd_context *ctx) { const struct fetch_field *field; struct mail *mail = ctx->mail; @@ -305,7 +307,7 @@ } static int -cmd_fetch_box(struct fetch_context *ctx, const struct mailbox_info *info) +cmd_fetch_box(struct fetch_cmd_context *ctx, const struct mailbox_info *info) { struct doveadm_mail_iter *iter; struct mailbox_transaction_context *trans; @@ -355,43 +357,59 @@ return have_mailbox && have_msg; } -void cmd_fetch(struct mail_user *user, const char *const args[]) +static void +cmd_fetch_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { + struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx; const enum mailbox_list_iter_flags iter_flags = MAILBOX_LIST_ITER_VIRTUAL_NAMES | MAILBOX_LIST_ITER_NO_AUTO_INBOX | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - const char *fetch_fields = args[0]; - struct fetch_context ctx; struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; + + 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_list_iter_deinit(&iter); +} + +static void cmd_fetch_deinit(struct doveadm_mail_cmd_context *_ctx) +{ + struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx; + + o_stream_unref(&ctx->output); + str_free(&ctx->hdr); +} + +struct doveadm_mail_cmd_context *cmd_fetch(const char *const args[]) +{ + const char *fetch_fields = args[0]; + struct fetch_cmd_context *ctx; unsigned char prefix_buf[9]; - memset(&ctx, 0, sizeof(ctx)); if (fetch_fields == NULL || args[1] == NULL) doveadm_mail_help_name("fetch"); - parse_fetch_fields(&ctx, fetch_fields); - ctx.search_args = doveadm_mail_build_search_args(args + 1); + + ctx = doveadm_mail_cmd_init(struct fetch_cmd_context); + ctx->ctx.run = cmd_fetch_run; + ctx->ctx.deinit = cmd_fetch_deinit; - ctx.output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE); + parse_fetch_fields(ctx, fetch_fields); + ctx->search_args = doveadm_mail_build_search_args(args + 1); - ctx.hdr = str_new(default_pool, 512); - if (search_args_have_unique_fetch(ctx.search_args)) - ctx.prefix = ""; + 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)) + ctx->prefix = ""; else { random_fill_weak(prefix_buf, sizeof(prefix_buf)); - str_append(ctx.hdr, "==="); - base64_encode(prefix_buf, sizeof(prefix_buf), ctx.hdr); - str_append_c(ctx.hdr, '\n'); - ctx.prefix = t_strdup(str_c(ctx.hdr)); - str_truncate(ctx.hdr, 0); + str_append(ctx->hdr, "==="); + base64_encode(prefix_buf, sizeof(prefix_buf), ctx->hdr); + str_append_c(ctx->hdr, '\n'); + ctx->prefix = t_strdup(str_c(ctx->hdr)); + str_truncate(ctx->hdr, 0); } - - 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_list_iter_deinit(&iter); - o_stream_unref(&ctx.output); - str_free(&ctx.hdr); + return &ctx->ctx; }
--- a/src/doveadm/doveadm-mail-list.c Fri Apr 30 18:01:08 2010 +0300 +++ b/src/doveadm/doveadm-mail-list.c Fri Apr 30 19:14:57 2010 +0300 @@ -8,35 +8,51 @@ #include <stdio.h> -void cmd_list(struct mail_user *user, const char *const args[]) +struct list_cmd_context { + struct doveadm_mail_cmd_context ctx; + struct mail_search_args *search_args; +}; + +static void +cmd_list_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { + struct list_cmd_context *ctx = (struct list_cmd_context *)_ctx; const enum mailbox_list_iter_flags iter_flags = MAILBOX_LIST_ITER_RAW_LIST | MAILBOX_LIST_ITER_VIRTUAL_NAMES | MAILBOX_LIST_ITER_NO_AUTO_INBOX | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - struct mail_search_args *search_args; - struct mail_search_arg *arg; struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; - unsigned int i; - search_args = mail_search_build_init(); - for (i = 0; args[i] != NULL; i++) { - arg = mail_search_build_add(search_args, SEARCH_MAILBOX_GLOB); - arg->value.str = p_strdup(search_args->pool, args[i]); - } - if (i > 1) { - struct mail_search_arg *subargs = search_args->args; - - search_args->args = NULL; - arg = mail_search_build_add(search_args, SEARCH_OR); - arg->value.subargs = subargs; - } - - iter = doveadm_mail_list_iter_init(user, 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) { printf("%s\n", info->name); } doveadm_mail_list_iter_deinit(&iter); } + +struct doveadm_mail_cmd_context *cmd_list(const char *const args[]) +{ + struct list_cmd_context *ctx; + struct mail_search_arg *arg; + unsigned int i; + + ctx = doveadm_mail_cmd_init(struct list_cmd_context); + ctx->ctx.run = cmd_list_run; + + ctx->search_args = mail_search_build_init(); + for (i = 0; args[i] != NULL; i++) { + arg = mail_search_build_add(ctx->search_args, + SEARCH_MAILBOX_GLOB); + arg->value.str = p_strdup(ctx->search_args->pool, args[i]); + } + if (i > 1) { + struct mail_search_arg *subargs = ctx->search_args->args; + + ctx->search_args->args = NULL; + arg = mail_search_build_add(ctx->search_args, SEARCH_OR); + arg->value.subargs = subargs; + } + return &ctx->ctx; +}
--- a/src/doveadm/doveadm-mail-search.c Fri Apr 30 18:01:08 2010 +0300 +++ b/src/doveadm/doveadm-mail-search.c Fri Apr 30 19:14:57 2010 +0300 @@ -8,6 +8,11 @@ #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) @@ -36,24 +41,34 @@ return ret; } -void cmd_search(struct mail_user *user, const char *const args[]) +static void +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 | MAILBOX_LIST_ITER_NO_AUTO_INBOX | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; - struct mail_search_args *search_args; struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; + 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_search_box(info, ctx->search_args); + } T_END; + doveadm_mail_list_iter_deinit(&iter); +} + +struct doveadm_mail_cmd_context *cmd_search(const char *const args[]) +{ + struct search_cmd_context *ctx; + if (args[0] == NULL) doveadm_mail_help_name("search"); - search_args = doveadm_mail_build_search_args(args); - iter = doveadm_mail_list_iter_init(user, search_args, iter_flags); - while ((info = doveadm_mail_list_iter_next(iter)) != NULL) T_BEGIN { - (void)cmd_search_box(info, search_args); - } T_END; - doveadm_mail_list_iter_deinit(&iter); + ctx = doveadm_mail_cmd_init(struct search_cmd_context); + ctx->ctx.run = cmd_search_run; + ctx->search_args = doveadm_mail_build_search_args(args); + return &ctx->ctx; }
--- a/src/doveadm/doveadm-mail.c Fri Apr 30 18:01:08 2010 +0300 +++ b/src/doveadm/doveadm-mail.c Fri Apr 30 19:14:57 2010 +0300 @@ -24,8 +24,23 @@ static int killed_signo = 0; +struct doveadm_mail_cmd_context * +doveadm_mail_cmd_init_size(size_t size) +{ + struct doveadm_mail_cmd_context *ctx; + pool_t pool; + + i_assert(size >= sizeof(struct doveadm_mail_cmd_context)); + + pool = pool_alloconly_create("doveadm mail cmd", 1024); + ctx = p_malloc(pool, size); + ctx->pool = pool; + return ctx; +} + static void -cmd_purge(struct mail_user *user, const char *const args[] ATTR_UNUSED) +cmd_purge_run(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, + struct mail_user *user) { struct mail_namespace *ns; @@ -40,6 +55,16 @@ } } +static struct doveadm_mail_cmd_context * +cmd_purge(const char *const args[] ATTR_UNUSED) +{ + struct doveadm_mail_cmd_context *ctx; + + ctx = doveadm_mail_cmd_init(struct doveadm_mail_cmd_context); + ctx->run = cmd_purge_run; + return ctx; +} + static struct mailbox * mailbox_find_and_open(struct mail_user *user, const char *mailbox) { @@ -90,30 +115,50 @@ return sargs; } -static void cmd_force_resync(struct mail_user *user, const char *const args[]) +struct force_resync_cmd_context { + struct doveadm_mail_cmd_context ctx; + const char *mailbox; +}; + +static void cmd_force_resync_run(struct doveadm_mail_cmd_context *_ctx, + struct mail_user *user) { - const char *mailbox = args[0]; + struct force_resync_cmd_context *ctx = + (struct force_resync_cmd_context *)_ctx; struct mail_storage *storage; struct mailbox *box; - if (mailbox == NULL) - doveadm_mail_help_name("force-resync"); - - box = mailbox_find_and_open(user, mailbox); + box = mailbox_find_and_open(user, ctx->mailbox); storage = mailbox_get_storage(box); if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC | MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) < 0) { - i_fatal("Forcing a resync on mailbox %s failed: %s", mailbox, + i_fatal("Forcing a resync on mailbox %s failed: %s", + ctx->mailbox, mail_storage_get_last_error(storage, NULL)); } mailbox_free(&box); } +static struct doveadm_mail_cmd_context * +cmd_force_resync(const char *const args[]) +{ + struct force_resync_cmd_context *ctx; + const char *mailbox = args[0]; + + if (mailbox == NULL || args[1] != NULL) + doveadm_mail_help_name("force-resync"); + + ctx = doveadm_mail_cmd_init(struct force_resync_cmd_context); + ctx->ctx.run = cmd_force_resync_run; + ctx->mailbox = p_strdup(ctx->ctx.pool, mailbox); + return &ctx->ctx; +} + static int -doveadm_mail_next_user(doveadm_mail_command_t *cmd, +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 *const args[], const char **error_r) + const char **error_r) { struct mail_storage_service_user *service_user; struct mail_user *mail_user; @@ -139,16 +184,16 @@ return ret; } - cmd(mail_user, args); + ctx->run(ctx, mail_user); mail_storage_service_user_free(&service_user); mail_user_unref(&mail_user); return 1; } static void -doveadm_mail_single_user(doveadm_mail_command_t *cmd, const char *username, - enum mail_storage_service_flags service_flags, - const char *const args[]) +doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx, + const char *username, + enum mail_storage_service_flags service_flags) { struct mail_storage_service_ctx *storage_service; struct mail_storage_service_input input; @@ -163,8 +208,7 @@ storage_service = mail_storage_service_init(master_service, NULL, service_flags); - ret = doveadm_mail_next_user(cmd, storage_service, &input, - args, &error); + ret = doveadm_mail_next_user(ctx, storage_service, &input, &error); if (ret < 0) i_fatal("%s", error); else if (ret == 0) @@ -178,9 +222,8 @@ } static void -doveadm_mail_all_users(doveadm_mail_command_t *cmd, - enum mail_storage_service_flags service_flags, - const char *const args[]) +doveadm_mail_all_users(struct doveadm_mail_cmd_context *ctx, + enum mail_storage_service_flags service_flags) { struct mail_storage_service_input input; struct mail_storage_service_ctx *storage_service; @@ -209,8 +252,8 @@ &user)) > 0) { input.username = user; T_BEGIN { - ret = doveadm_mail_next_user(cmd, storage_service, - &input, args, &error); + ret = doveadm_mail_next_user(ctx, storage_service, + &input, &error); if (ret < 0) i_error("%s", error); else if (ret == 0) @@ -243,6 +286,7 @@ { enum mail_storage_service_flags service_flags = MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT; + struct doveadm_mail_cmd_context *ctx; const char *username; bool all_users = FALSE; int c; @@ -272,14 +316,15 @@ cmd->name, argv[0]); } + ctx = cmd->init((const void *)argv); if (!all_users) { - doveadm_mail_single_user(cmd->cmd, username, service_flags, - (const void *)argv); + doveadm_mail_single_user(ctx, username, service_flags); } else { service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; - doveadm_mail_all_users(cmd->cmd, service_flags, - (const void *)argv); + doveadm_mail_all_users(ctx, service_flags); } + if (ctx->deinit != NULL) + ctx->deinit(ctx); } static bool
--- a/src/doveadm/doveadm-mail.h Fri Apr 30 18:01:08 2010 +0300 +++ b/src/doveadm/doveadm-mail.h Fri Apr 30 19:14:57 2010 +0300 @@ -4,12 +4,19 @@ #include "doveadm.h" struct mail_user; +struct doveadm_mail_cmd_context; -typedef void doveadm_mail_command_t(struct mail_user *mail_user, - const char *const args[]); +struct doveadm_mail_cmd_context { + pool_t pool; + + 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 { - doveadm_mail_command_t *cmd; + struct doveadm_mail_cmd_context * + (*init)(const char *const args[]); const char *name; const char *usage_args; }; @@ -32,10 +39,15 @@ struct mail_search_args * doveadm_mail_build_search_args(const char *const args[]); -void cmd_expunge(struct mail_user *user, const char *const args[]); -void cmd_search(struct mail_user *user, const char *const args[]); -void cmd_fetch(struct mail_user *user, const char *const args[]); -void cmd_altmove(struct mail_user *user, const char *const args[]); -void cmd_list(struct mail_user *user, const char *const args[]); +struct doveadm_mail_cmd_context * +doveadm_mail_cmd_init_size(size_t size); +#define doveadm_mail_cmd_init(type) \ + (type *)doveadm_mail_cmd_init_size(sizeof(type)) + +struct doveadm_mail_cmd_context *cmd_expunge(const char *const args[]); +struct doveadm_mail_cmd_context *cmd_search(const char *const args[]); +struct doveadm_mail_cmd_context *cmd_fetch(const char *const args[]); +struct doveadm_mail_cmd_context *cmd_altmove(const char *const args[]); +struct doveadm_mail_cmd_context *cmd_list(const char *const args[]); #endif
--- a/src/plugins/quota/doveadm-quota.c Fri Apr 30 18:01:08 2010 +0300 +++ b/src/plugins/quota/doveadm-quota.c Fri Apr 30 19:14:57 2010 +0300 @@ -39,7 +39,8 @@ } static void -cmd_quota_get(struct mail_user *user, const char *const args[] ATTR_UNUSED) +cmd_quota_get_run(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, + struct mail_user *user) { struct quota_user *quser = QUOTA_USER_CONTEXT(user); struct quota_root *const *root; @@ -48,8 +49,19 @@ cmd_quota_get_root(user, *root); } +static struct doveadm_mail_cmd_context * +cmd_quota_get(const char *const args[] ATTR_UNUSED) +{ + struct doveadm_mail_cmd_context *ctx; + + ctx = doveadm_mail_cmd_init(struct doveadm_mail_cmd_context); + ctx->run = cmd_quota_get_run; + return ctx; +} + static void -cmd_quota_recalc(struct mail_user *user, const char *const args[] ATTR_UNUSED) +cmd_quota_recalc_run(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, + struct mail_user *user) { struct quota_user *quser = QUOTA_USER_CONTEXT(user); struct quota_root *const *root; @@ -63,6 +75,16 @@ (void)(*root)->backend.v.update(*root, &trans); } +static struct doveadm_mail_cmd_context * +cmd_quota_recalc(const char *const args[] ATTR_UNUSED) +{ + struct doveadm_mail_cmd_context *ctx; + + ctx = doveadm_mail_cmd_init(struct doveadm_mail_cmd_context); + ctx->run = cmd_quota_recalc_run; + return ctx; +} + static struct doveadm_mail_cmd quota_commands[] = { { cmd_quota_get, "quota get", NULL }, { cmd_quota_recalc, "quota recalc", NULL }