From: Timo Sirainen Date: Thu, 13 May 2010 09:05:56 +0000 (+0200) Subject: doveadm mailbox *: Added -7 and -8 parameters to translate between mUTF7/UTF-8 mailbo... X-Git-Tag: 2.0.beta6~235 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e09c7dc961cb9cab04ec7cc79215c2f6318fbde0;p=thirdparty%2Fdovecot%2Fcore.git doveadm mailbox *: Added -7 and -8 parameters to translate between mUTF7/UTF-8 mailbox names. --HG-- branch : HEAD --- diff --git a/src/doveadm/doveadm-mail-mailbox.c b/src/doveadm/doveadm-mail-mailbox.c index c7772dd66b..8395cf516d 100644 --- a/src/doveadm/doveadm-mail-mailbox.c +++ b/src/doveadm/doveadm-mail-mailbox.c @@ -2,6 +2,8 @@ #include "lib.h" #include "array.h" +#include "str.h" +#include "imap-utf7.h" #include "mail-namespace.h" #include "mail-storage.h" #include "mail-search-build.h" @@ -10,21 +12,101 @@ #include -struct mailbox_cmd_context { +struct doveadm_mailbox_cmd_context { struct doveadm_mail_cmd_context ctx; + bool mutf7; +}; + +struct mailbox_cmd_context { + struct doveadm_mailbox_cmd_context ctx; ARRAY_TYPE(const_string) mailboxes; }; struct rename_cmd_context { - struct doveadm_mail_cmd_context ctx; + struct doveadm_mailbox_cmd_context ctx; const char *oldname, *newname; }; struct list_cmd_context { - struct doveadm_mail_cmd_context ctx; + struct doveadm_mailbox_cmd_context ctx; struct mail_search_args *search_args; }; +static const char *const * +doveadm_mailbox_args_to_mutf7(const char *const args[]) +{ + ARRAY_TYPE(const_string) dest; + string_t *str; + const char *mutf7; + unsigned int i; + + str = t_str_new(128); + t_array_init(&dest, 8); + for (i = 0; args[i] != NULL; i++) { + str_truncate(str, 0); + if (imap_utf8_to_utf7(args[i], str) < 0) + i_fatal("Mailbox name not valid UTF-8: %s", args[i]); + mutf7 = t_strdup(str_c(str)); + array_append(&dest, &mutf7, 1); + } + (void)array_append_space(&dest); + return array_idx(&dest, 0); +} + +static void +doveadm_mailbox_args_validate_mutf7(const char *const *args) +{ + string_t *str = t_str_new(128); + unsigned int i; + + for (i = 0; args[i] != NULL; i++) { + if (imap_utf7_to_utf8(args[i], str) < 0) + i_fatal("Mailbox name not valid mUTF-7: %s", args[i]); + str_truncate(str, 0); + } +} + +static bool cmd_mailbox_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) +{ + struct doveadm_mailbox_cmd_context *ctx = + (struct doveadm_mailbox_cmd_context *)_ctx; + + switch (c) { + case '7': + ctx->mutf7 = TRUE; + break; + case '8': + ctx->mutf7 = FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +#define doveadm_mailbox_cmd_alloc(type) \ + (type *)doveadm_mailbox_cmd_alloc_size(sizeof(type)) +static struct doveadm_mail_cmd_context * +doveadm_mailbox_cmd_alloc_size(size_t size) +{ + struct doveadm_mail_cmd_context *ctx; + + ctx = doveadm_mail_cmd_alloc_size(size); + ctx->getopt_args = "78"; + ctx->parse_arg = cmd_mailbox_parse_arg; + return ctx; +} + +static void +doveadm_mailbox_translate_args(struct doveadm_mailbox_cmd_context *ctx, + const char *const *args[]) +{ + if (!ctx->mutf7) + *args = doveadm_mailbox_args_to_mutf7(*args); + else + doveadm_mailbox_args_validate_mutf7(*args); +} + static void cmd_mailbox_list_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) @@ -37,10 +119,15 @@ cmd_mailbox_list_run(struct doveadm_mail_cmd_context *_ctx, MAILBOX_LIST_ITER_RETURN_NO_FLAGS; struct doveadm_mail_list_iter *iter; const struct mailbox_info *info; + string_t *str = t_str_new(256); 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); + str_truncate(str, 0); + if (ctx->ctx.mutf7 || imap_utf7_to_utf8(info->name, str) < 0) + printf("%s\n", info->name); + else + printf("%s\n", str_c(str)); } doveadm_mail_list_iter_deinit(&iter); } @@ -52,6 +139,7 @@ static void cmd_mailbox_list_init(struct doveadm_mail_cmd_context *_ctx, struct mail_search_arg *arg; unsigned int i; + doveadm_mailbox_translate_args(&ctx->ctx, &args); ctx->search_args = mail_search_build_init(); for (i = 0; args[i] != NULL; i++) { arg = mail_search_build_add(ctx->search_args, @@ -71,10 +159,10 @@ static struct doveadm_mail_cmd_context *cmd_mailbox_list_alloc(void) { struct list_cmd_context *ctx; - ctx = doveadm_mail_cmd_alloc(struct list_cmd_context); - ctx->ctx.init = cmd_mailbox_list_init; - ctx->ctx.run = cmd_mailbox_list_run; - return &ctx->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; + return &ctx->ctx.ctx; } static void @@ -121,9 +209,10 @@ static void cmd_mailbox_create_init(struct doveadm_mail_cmd_context *_ctx, if (args[0] == NULL) doveadm_mail_help_name("mailbox create"); + doveadm_mailbox_translate_args(&ctx->ctx, &args); for (i = 0; args[i] != NULL; i++) { - name = p_strdup(ctx->ctx.pool, args[i]); + name = p_strdup(ctx->ctx.ctx.pool, args[i]); array_append(&ctx->mailboxes, &name, 1); } } @@ -132,11 +221,11 @@ static struct doveadm_mail_cmd_context *cmd_mailbox_create_alloc(void) { struct mailbox_cmd_context *ctx; - ctx = doveadm_mail_cmd_alloc(struct mailbox_cmd_context); - ctx->ctx.init = cmd_mailbox_create_init; - ctx->ctx.run = cmd_mailbox_create_run; - p_array_init(&ctx->mailboxes, ctx->ctx.pool, 16); - return &ctx->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; + p_array_init(&ctx->mailboxes, ctx->ctx.ctx.pool, 16); + return &ctx->ctx.ctx; } static void @@ -175,9 +264,10 @@ static void cmd_mailbox_delete_init(struct doveadm_mail_cmd_context *_ctx, if (args[0] == NULL) doveadm_mail_help_name("mailbox delete"); + doveadm_mailbox_translate_args(&ctx->ctx, &args); for (i = 0; args[i] != NULL; i++) { - name = p_strdup(ctx->ctx.pool, args[i]); + name = p_strdup(ctx->ctx.ctx.pool, args[i]); array_append(&ctx->mailboxes, &name, 1); } } @@ -186,11 +276,11 @@ static struct doveadm_mail_cmd_context *cmd_mailbox_delete_alloc(void) { struct mailbox_cmd_context *ctx; - ctx = doveadm_mail_cmd_alloc(struct mailbox_cmd_context); - ctx->ctx.init = cmd_mailbox_delete_init; - ctx->ctx.run = cmd_mailbox_delete_run; - p_array_init(&ctx->mailboxes, ctx->ctx.pool, 16); - return &ctx->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; + p_array_init(&ctx->mailboxes, ctx->ctx.ctx.pool, 16); + return &ctx->ctx.ctx; } static void @@ -229,19 +319,20 @@ static void cmd_mailbox_rename_init(struct doveadm_mail_cmd_context *_ctx, if (str_array_length(args) != 2) doveadm_mail_help_name("mailbox rename"); + doveadm_mailbox_translate_args(&ctx->ctx, &args); - ctx->oldname = p_strdup(ctx->ctx.pool, args[0]); - ctx->newname = p_strdup(ctx->ctx.pool, args[1]); + ctx->oldname = p_strdup(ctx->ctx.ctx.pool, args[0]); + ctx->newname = p_strdup(ctx->ctx.ctx.pool, args[1]); } static struct doveadm_mail_cmd_context *cmd_mailbox_rename_alloc(void) { struct rename_cmd_context *ctx; - ctx = doveadm_mail_cmd_alloc(struct rename_cmd_context); - ctx->ctx.init = cmd_mailbox_rename_init; - ctx->ctx.run = cmd_mailbox_rename_run; - return &ctx->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; + return &ctx->ctx.ctx; } struct doveadm_mail_cmd cmd_mailbox_list = { diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index 6e5e8b9ef6..c041182337 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -294,7 +294,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; + const char *getopt_args, *username; bool all_users = FALSE; int c; @@ -302,8 +302,9 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[]) service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; ctx = cmd->alloc(); + getopt_args = t_strconcat("Au:", ctx->getopt_args, NULL); username = getenv("USER"); - while ((c = getopt(argc, argv, "Au:")) > 0) { + while ((c = getopt(argc, argv, getopt_args)) > 0) { switch (c) { case 'A': all_users = TRUE; @@ -314,7 +315,8 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[]) username = optarg; break; default: - doveadm_mail_help(cmd); + if (ctx->parse_arg == NULL || !ctx->parse_arg(ctx, c)) + doveadm_mail_help(cmd); } } argv += optind; diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h index 9421d6a022..29893d555e 100644 --- a/src/doveadm/doveadm-mail.h +++ b/src/doveadm/doveadm-mail.h @@ -8,7 +8,9 @@ struct doveadm_mail_cmd_context; struct doveadm_mail_cmd_context { pool_t pool; + const char *getopt_args; + bool (*parse_arg)(struct doveadm_mail_cmd_context *ctx,int c); void (*init)(struct doveadm_mail_cmd_context *ctx, const char *const args[]); void (*run)(struct doveadm_mail_cmd_context *ctx,