]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Changed mail command handler API.
authorTimo Sirainen <tss@iki.fi>
Fri, 30 Apr 2010 16:14:57 +0000 (19:14 +0300)
committerTimo Sirainen <tss@iki.fi>
Fri, 30 Apr 2010 16:14:57 +0000 (19:14 +0300)
This should help add some new future features.

--HG--
branch : HEAD

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

index 8d1ce0b8622db48e343949efd7cc47439d25cbb7..162981577992da99c3107a8392796dfe16b5d74a 100644 (file)
@@ -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 @@ static void ns_purge(struct mail_namespace *ns)
        }
 }
 
-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 @@ void cmd_altmove(struct mail_user *user, const char *const args[])
        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 @@ void cmd_altmove(struct mail_user *user, const char *const args[])
                        }
                        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 @@ void cmd_altmove(struct mail_user *user, const char *const args[])
                }
        }
 }
+
+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;
+}
index d19e31da7f3b0bac24b7484f86ef91cb46d3d328..97ca11d9bbea789568bd6a1831a85e7af3823e6e 100644 (file)
@@ -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 @@ expunge_search_args_is_msgset_ok(struct mail_search_arg *args)
        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;
+}
index ae179efeaead3c2f397865f3591519ba490803ba..b7242418a924f3cd3f87785e5a87b37aee1ba096 100644 (file)
@@ -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 @@ struct fetch_context {
        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 @@ static int fetch_mailbox(struct fetch_context *ctx)
        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 @@ static int fetch_mailbox_guid(struct fetch_context *ctx)
        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 @@ static int fetch_guid(struct fetch_context *ctx)
        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 @@ static int fetch_hdr(struct fetch_context *ctx)
        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 @@ static int fetch_body(struct fetch_context *ctx)
        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 @@ static int fetch_text(struct fetch_context *ctx)
        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 @@ static int fetch_size_physical(struct fetch_context *ctx)
        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 @@ static int fetch_size_virtual(struct fetch_context *ctx)
        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 @@ static int fetch_date_received(struct fetch_context *ctx)
        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 @@ static int fetch_date_sent(struct fetch_context *ctx)
        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 @@ static int fetch_date_saved(struct fetch_context *ctx)
 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 @@ static void print_fetch_fields(void)
        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 @@ static void parse_fetch_fields(struct fetch_context *ctx, const char *str)
        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 void cmd_fetch_mail(struct fetch_context *ctx)
 }
 
 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 @@ static bool search_args_have_unique_fetch(struct mail_search_args *args)
        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.output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
+       ctx = doveadm_mail_cmd_init(struct fetch_cmd_context);
+       ctx->ctx.run = cmd_fetch_run;
+       ctx->ctx.deinit = cmd_fetch_deinit;
 
-       ctx.hdr = str_new(default_pool, 512);
-       if (search_args_have_unique_fetch(ctx.search_args))
-               ctx.prefix = "";
+       parse_fetch_fields(ctx, fetch_fields);
+       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))
+               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;
 }
index 05f3484ee364e668cd11d4b670045e391f551ab0..8865ee829be2c33ca5cbd89f4e7ec95cce6747a3 100644 (file)
@@ -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;
+
+       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;
 
-       search_args = mail_search_build_init();
+       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(search_args, SEARCH_MAILBOX_GLOB);
-               arg->value.str = p_strdup(search_args->pool, args[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 = search_args->args;
+               struct mail_search_arg *subargs = ctx->search_args->args;
 
-               search_args->args = NULL;
-               arg = mail_search_build_add(search_args, SEARCH_OR);
+               ctx->search_args->args = NULL;
+               arg = mail_search_build_add(ctx->search_args, SEARCH_OR);
                arg->value.subargs = subargs;
        }
-
-       iter = doveadm_mail_list_iter_init(user, search_args, iter_flags);
-       while ((info = doveadm_mail_list_iter_next(iter)) != NULL) {
-               printf("%s\n", info->name);
-       }
-       doveadm_mail_list_iter_deinit(&iter);
+       return &ctx->ctx;
 }
index ad81f804d19f3704dd110f6622da69bde94b39dc..4b8b7666f71b6d30bd59cedf40ab9112c324cb00 100644 (file)
@@ -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 @@ cmd_search_box(const struct mailbox_info *info,
        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;
 
-       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);
+       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, search_args);
+               (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");
+
+       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;
+}
index 0a2f01cae24874d4e3167c409bb98dcd60ebb6d1..b5123299b24dae347f72cbf4ca48dc8560bf9497 100644 (file)
@@ -24,8 +24,23 @@ ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
 
 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 @@ cmd_purge(struct mail_user *user, const char *const args[] ATTR_UNUSED)
        }
 }
 
+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 @@ doveadm_mail_build_search_args(const char *const args[])
        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 @@ doveadm_mail_next_user(doveadm_mail_command_t *cmd,
                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 @@ doveadm_mail_single_user(doveadm_mail_command_t *cmd, const char *username,
 
        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 sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
 }
 
 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 @@ doveadm_mail_all_users(doveadm_mail_command_t *cmd,
                                                    &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 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
 {
        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 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
                        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
index 3bb8c0b162a1f8b9d1863c9b3e9b971985bdf4a0..d48e139791c071ba60d6d0aa1a4171d074acdca9 100644 (file)
@@ -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 @@ doveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox);
 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
index f1fa6e1dda2e77560e8a441ca0ee3b289a415001..46d53b0a2e1a4a087aaea864d6529c71d354dcab 100644 (file)
@@ -39,7 +39,8 @@ static void cmd_quota_get_root(struct mail_user *user, struct quota_root *root)
 }
 
 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(struct mail_user *user, const char *const args[] ATTR_UNUSED)
                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 @@ cmd_quota_recalc(struct mail_user *user, const char *const args[] ATTR_UNUSED)
                (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 }