doveadm-mail.c revision b8b085f7bc6f1c0367802a9f00062bbbd981690d
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "lib.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "array.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "lib-signals.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "ioloop.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "str.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "module-dir.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "wildcard-match.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "master-service.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "imap-utf7.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "mail-user.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "mail-namespace.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "mail-storage.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "mail-storage-settings.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "mail-storage-service.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "mail-search-build.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "mail-search-parser.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "doveadm.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "doveadm-settings.h"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include "doveadm-mail.h"
96283b546081e7ff709968378fca25cb44f1ab6cStéphane Graber
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include <stdio.h>
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield#include <stdlib.h>
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. WarfieldARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstruct doveadm_mail_cmd_module_register
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_cmd_module_register = { 0 };
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic int killed_signo = 0;
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfieldstruct doveadm_mail_cmd_context *
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfielddoveadm_mail_cmd_alloc_size(size_t size)
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield{
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield struct doveadm_mail_cmd_context *ctx;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield pool_t pool;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield i_assert(size >= sizeof(struct doveadm_mail_cmd_context));
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield
ec64264d78d4ed608553842ce9e1f07eeab2a032Veres Lajos pool = pool_alloconly_create("doveadm mail cmd", 1024);
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield ctx = p_malloc(pool, size);
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield ctx->pool = pool;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield ctx->dm_printf_last_lf = TRUE;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield return ctx;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield}
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfieldstatic void
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfieldcmd_purge_run(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED,
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield struct mail_user *user)
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield{
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield struct mail_namespace *ns;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield for (ns = user->namespaces; ns != NULL; ns = ns->next) {
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield if (ns->type != NAMESPACE_PRIVATE || ns->alias_for != NULL)
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield continue;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield if (mail_storage_purge(ns->storage) < 0) {
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield i_error("Purging namespace '%s' failed: %s", ns->prefix,
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield mail_storage_get_last_error(ns->storage, NULL));
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield }
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield }
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield}
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfieldstatic struct doveadm_mail_cmd_context *cmd_purge_alloc(void)
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield{
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield struct doveadm_mail_cmd_context *ctx;
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield ctx->v.run = cmd_purge_run;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return ctx;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic struct mailbox *
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldmailbox_find_and_open(struct mail_user *user, const char *mailbox)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct mail_namespace *ns;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct mailbox *box;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield string_t *str;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *orig_mailbox = mailbox;
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber
c63c04fcaf1c3a78c70500eae253d72fa9c8358aTAMUKI Shoichi str = t_str_new(128);
96283b546081e7ff709968378fca25cb44f1ab6cStéphane Graber if (imap_utf8_to_utf7(mailbox, str) < 0)
96283b546081e7ff709968378fca25cb44f1ab6cStéphane Graber i_fatal("Mailbox name not valid UTF-8: %s", mailbox);
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber mailbox = str_c(str);
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber ns = mail_namespace_find(user->namespaces, &mailbox);
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber if (ns == NULL)
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber i_fatal("Can't find namespace for mailbox %s", mailbox);
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_KEEP_RECENT |
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber MAILBOX_FLAG_IGNORE_ACLS);
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber if (mailbox_open(box) < 0) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_fatal("Opening mailbox %s failed: %s", orig_mailbox,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mail_storage_get_last_error(mailbox_get_storage(box),
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield NULL));
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return box;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstruct mailbox *
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfielddoveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct mailbox *box;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield box = mailbox_find_and_open(user, mailbox);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_fatal("Syncing mailbox %s failed: %s", mailbox,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mail_storage_get_last_error(mailbox_get_storage(box),
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield NULL));
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return box;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield}
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfieldstruct mail_search_args *
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfielddoveadm_mail_build_search_args(const char *const args[])
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield{
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield struct mail_search_parser *parser;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield struct mail_search_args *sargs;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *error;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield parser = mail_search_parser_init_cmdline(args);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield if (mail_search_build(mail_search_register_get_human(),
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield parser, "UTF-8", &sargs, &error) < 0)
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield i_fatal("%s", error);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield mail_search_parser_deinit(&parser);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield return sargs;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield}
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfieldstruct force_resync_cmd_context {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct doveadm_mail_cmd_context ctx;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield const char *mailbox;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield};
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic void cmd_force_resync_run(struct doveadm_mail_cmd_context *_ctx,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct mail_user *user)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct force_resync_cmd_context *ctx =
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield (struct force_resync_cmd_context *)_ctx;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield struct mail_storage *storage;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield struct mailbox *box;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield box = mailbox_find_and_open(user, ctx->mailbox);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield storage = mailbox_get_storage(box);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC |
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) < 0) {
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield i_fatal("Forcing a resync on mailbox %s failed: %s",
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx->mailbox,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mail_storage_get_last_error(storage, NULL));
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mailbox_free(&box);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic void cmd_force_resync_init(struct doveadm_mail_cmd_context *_ctx,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *const args[])
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct force_resync_cmd_context *ctx =
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield (struct force_resync_cmd_context *)_ctx;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *mailbox = args[0];
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (mailbox == NULL || args[1] != NULL)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_help_name("force-resync");
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx->mailbox = p_strdup(ctx->ctx.pool, mailbox);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic struct doveadm_mail_cmd_context *cmd_force_resync_alloc(void)
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct force_resync_cmd_context *ctx;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx = doveadm_mail_cmd_alloc(struct force_resync_cmd_context);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx->ctx.v.init = cmd_force_resync_init;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx->ctx.v.run = cmd_force_resync_run;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return &ctx->ctx;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic int
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfielddoveadm_mail_next_user(struct doveadm_mail_cmd_context *ctx,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const struct mail_storage_service_input *input,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char **error_r)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct mail_storage_service_user *service_user;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *error;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield int ret;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield i_set_failure_prefix(t_strdup_printf("doveadm(%s): ", input->username));
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield ret = mail_storage_service_lookup(ctx->storage_service, input,
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield &service_user, &error);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield if (ret <= 0) {
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield if (ret < 0) {
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield *error_r = t_strdup_printf("User lookup failed: %s",
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield error);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield }
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield return ret;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield }
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield ret = mail_storage_service_next(ctx->storage_service, service_user,
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield &ctx->cur_mail_user);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield if (ret < 0) {
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield *error_r = "User init failed";
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield mail_storage_service_user_free(&service_user);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield return ret;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield }
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield ctx->v.run(ctx, ctx->cur_mail_user);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield mail_user_unref(&ctx->cur_mail_user);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield mail_storage_service_user_free(&service_user);
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield return 1;
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield}
c6df5ca4603c630a7189cdb1653c96bd2808c7e5Michael H. Warfield
f5067ecbcc1e97052c33269b4afa6375073a91a1Michael H. Warfieldstatic void
f5067ecbcc1e97052c33269b4afa6375073a91a1Michael H. Warfielddoveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx,
f5067ecbcc1e97052c33269b4afa6375073a91a1Michael H. Warfield const char *username,
f5067ecbcc1e97052c33269b4afa6375073a91a1Michael H. Warfield enum mail_storage_service_flags service_flags)
f5067ecbcc1e97052c33269b4afa6375073a91a1Michael H. Warfield{
f5067ecbcc1e97052c33269b4afa6375073a91a1Michael H. Warfield struct mail_storage_service_input input;
f5067ecbcc1e97052c33269b4afa6375073a91a1Michael H. Warfield const char *error;
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield int ret;
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield if (username == NULL)
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield i_fatal("USER environment is missing and -u option not used");
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield memset(&input, 0, sizeof(input));
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield input.username = username;
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield ctx->storage_service = mail_storage_service_init(master_service, NULL,
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield service_flags);
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield if (hook_doveadm_mail_init != NULL)
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield hook_doveadm_mail_init(ctx);
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield ret = doveadm_mail_next_user(ctx, &input, &error);
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield if (ret < 0)
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield i_fatal("%s", error);
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield else if (ret == 0)
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield i_fatal("User no longer exists");
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield mail_storage_service_deinit(&ctx->storage_service);
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield}
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfieldstatic void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield{
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield killed_signo = si->si_signo;
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield}
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfieldstatic void
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfielddoveadm_mail_all_users(struct doveadm_mail_cmd_context *ctx,
99c2fb07d74c20d0eec38c05c4ac64e5782d8e7dMichael H. Warfield const char *wildcard_user,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield enum mail_storage_service_flags service_flags)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct mail_storage_service_input input;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield unsigned int user_idx, user_count, interval, n;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *user, *error;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield int ret;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
91c5c53f59262704538a7b8f9571d626e4e08011Kalman Olah
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield memset(&input, 0, sizeof(input));
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield input.service = "doveadm";
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx->storage_service = mail_storage_service_init(master_service, NULL,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield service_flags);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield lib_signals_set_handler(SIGINT, FALSE, sig_die, NULL);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield lib_signals_set_handler(SIGTERM, FALSE, sig_die, NULL);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (hook_doveadm_mail_init != NULL)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield hook_doveadm_mail_init(ctx);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield user_count = mail_storage_service_all_init(ctx->storage_service);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield n = user_count / 10000;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield for (interval = 10; n > 0 && interval < 1000; interval *= 10)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield n /= 10;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield user_idx = 0;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield while ((ret = ctx->v.get_next_user(ctx, &user)) > 0) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (wildcard_user != NULL) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (!wildcard_match_icase(user, wildcard_user))
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield continue;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield input.username = user;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield T_BEGIN {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ret = doveadm_mail_next_user(ctx, &input, &error);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (ret < 0)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_error("%s", error);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield else if (ret == 0)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_info("User no longer exists, skipping");
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield } T_END;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (ret == -1)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield break;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (doveadm_verbose) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (++user_idx % interval == 0) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield printf("\r%d / %d", user_idx, user_count);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield fflush(stdout);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (killed_signo != 0) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_warning("Killed with signal %d", killed_signo);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ret = -1;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield break;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (doveadm_verbose)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield printf("\n");
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes i_set_failure_prefix("doveadm: ");
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes if (ret < 0)
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes i_error("Failed to iterate through some users");
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes mail_storage_service_deinit(&ctx->storage_service);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic void
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfielddoveadm_mail_cmd_init_noop(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *const args[] ATTR_UNUSED)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic int
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfielddoveadm_mail_cmd_get_next_user(struct doveadm_mail_cmd_context *ctx,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char **username_r)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return mail_storage_service_all_next(ctx->storage_service, username_r);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic void
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfielddoveadm_mail_cmd_deinit_noop(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic void
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfielddoveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield enum mail_storage_service_flags service_flags =
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT;
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield struct doveadm_mail_cmd_context *ctx;
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield const char *getopt_args, *username, *wildcard_user;
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield int c;
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield if (doveadm_debug)
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield ctx = cmd->alloc();
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield if (ctx->v.init == NULL)
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield ctx->v.init = doveadm_mail_cmd_init_noop;
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield if (ctx->v.get_next_user == NULL)
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield ctx->v.get_next_user = doveadm_mail_cmd_get_next_user;
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield if (ctx->v.deinit == NULL)
1ecee40b7dcb933d2c9910f07ed26c6a55e18206Michael H. Warfield ctx->v.deinit = doveadm_mail_cmd_deinit_noop;
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes p_array_init(&ctx->module_contexts, ctx->pool, 5);
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes getopt_args = t_strconcat("Au:", ctx->getopt_args, NULL);
7edae51efcb3cb3a05e7fe850905dc836d120512Claudio Alarcon-Reyes username = getenv("USER");
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield wildcard_user = NULL;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield while ((c = getopt(argc, argv, getopt_args)) > 0) {
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield switch (c) {
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield case 'A':
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield ctx->iterate_all_users = TRUE;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield break;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield case 'u':
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield service_flags |=
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield username = optarg;
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield if (strchr(username, '*') != NULL ||
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield strchr(username, '?') != NULL)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield wildcard_user = username;
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield break;
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield default:
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield if (ctx->v.parse_arg == NULL ||
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield !ctx->v.parse_arg(ctx, c))
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield doveadm_mail_help(cmd);
826cde7c2100e1f4419a54b5c930c0854e01e87eMichael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield argv += optind;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (argv[0] != NULL && cmd->usage_args == NULL) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_fatal("doveadm %s: Unknown parameter: %s",
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield cmd->name, argv[0]);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx->v.init(ctx, (const void *)argv);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (!ctx->iterate_all_users && wildcard_user == NULL) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_single_user(ctx, username, service_flags);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield } else {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_all_users(ctx, wildcard_user, service_flags);
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield }
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield ctx->v.deinit(ctx);
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield}
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfieldvoid dm_printf(struct doveadm_mail_cmd_context *ctx, const char *format, ...)
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield{
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield va_list args;
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield va_start(args, format);
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield if (!ctx->iterate_all_users)
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield vprintf(format, args);
779b47fdca6975f70541fbc7c25a34393ec5c24bMichael H. Warfield else T_BEGIN {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *str = t_strdup_vprintf(format, args);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield bool prev_lf = ctx->dm_printf_last_lf;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield for (; *str != '\0'; str++) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (prev_lf)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield printf("%s: ", ctx->cur_mail_user->username);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield putchar(*str);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield prev_lf = *str == '\n';
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield ctx->dm_printf_last_lf = prev_lf;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield } T_END;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield va_end(args);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic bool
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfielddoveadm_mail_try_run_multi_word(const struct doveadm_mail_cmd *cmd,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *cmdname, int argc, char *argv[])
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield unsigned int len;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel if (argc < 2)
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel return FALSE;
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel len = strlen(argv[1]);
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel if (strncmp(cmdname, argv[1], len) != 0)
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel return FALSE;
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel if (cmdname[len] == ' ') {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield /* more args */
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return doveadm_mail_try_run_multi_word(cmd, cmdname + len + 1,
08754f305b580801ae800df32ace5dc7b9b191d9Michael H. Warfield argc - 1, argv + 1);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (cmdname[len] != '\0')
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return FALSE;
08754f305b580801ae800df32ace5dc7b9b191d9Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield /* match */
3a6ef65aa29206b2f2061fdb020c32118f6d74f2Harald Dunkel doveadm_mail_cmd(cmd, argc - 1, argv + 1);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return TRUE;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldbool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[])
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const struct doveadm_mail_cmd *cmd;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield unsigned int cmd_name_len;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_assert(argc > 0);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield cmd_name_len = strlen(cmd_name);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield array_foreach(&doveadm_mail_cmds, cmd) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (strcmp(cmd->name, cmd_name) == 0) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_cmd(cmd, argc, argv);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return TRUE;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield /* see if it matches a multi-word command */
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (strncmp(cmd->name, cmd_name, cmd_name_len) == 0 &&
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield cmd->name[cmd_name_len] == ' ') {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const char *subcmd = cmd->name + cmd_name_len + 1;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (doveadm_mail_try_run_multi_word(cmd, subcmd,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield argc, argv))
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return TRUE;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return FALSE;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield /* for now we'll just assume that cmd will be permanently in memory */
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield array_append(&doveadm_mail_cmds, cmd, 1);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid doveadm_mail_usage(string_t *out)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const struct doveadm_mail_cmd *cmd;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield array_foreach(&doveadm_mail_cmds, cmd) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield str_printfa(out, "%s\t[-u <user>|-A]", cmd->name);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (cmd->usage_args != NULL)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield str_printfa(out, " %s", cmd->usage_args);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield str_append_c(out, '\n');
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid doveadm_mail_help(const struct doveadm_mail_cmd *cmd)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield fprintf(stderr, "doveadm %s [-u <user>|-A] %s\n", cmd->name,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield cmd->usage_args == NULL ? "" : cmd->usage_args);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield exit(0);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid doveadm_mail_try_help_name(const char *cmd_name)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const struct doveadm_mail_cmd *cmd;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield array_foreach(&doveadm_mail_cmds, cmd) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (strcmp(cmd->name, cmd_name) == 0)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_help(cmd);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldbool doveadm_mail_has_subcommands(const char *cmd_name)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield const struct doveadm_mail_cmd *cmd;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield unsigned int len = strlen(cmd_name);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield array_foreach(&doveadm_mail_cmds, cmd) {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield if (strncmp(cmd->name, cmd_name, len) == 0 &&
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield cmd->name[len] == ' ')
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return TRUE;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield }
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield return FALSE;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid doveadm_mail_help_name(const char *cmd_name)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_try_help_name(cmd_name);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_fatal("Missing help for command %s", cmd_name);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic struct doveadm_mail_cmd cmd_force_resync = {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield cmd_force_resync_alloc, "force-resync", "<mailbox>"
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield};
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic struct doveadm_mail_cmd cmd_purge = {
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe cmd_purge_alloc, "purge", NULL
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield};
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldstatic struct doveadm_mail_cmd *mail_commands[] = {
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_force_resync,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_purge,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_expunge,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_search,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_fetch,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_altmove,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_mailbox_list,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_mailbox_create,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_mailbox_delete,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_mailbox_rename,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_mailbox_subscribe,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_mailbox_unsubscribe,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &cmd_mailbox_status
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield};
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid doveadm_mail_init(void)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield{
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield struct module_dir_load_settings mod_set;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield unsigned int i;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield i_array_init(&doveadm_mail_cmds, 32);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield for (i = 0; i < N_ELEMENTS(mail_commands); i++)
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_mail_register_cmd(mail_commands[i]);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield memset(&mod_set, 0, sizeof(mod_set));
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mod_set.version = master_service_get_version_string(master_service);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mod_set.require_init_funcs = TRUE;
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mod_set.debug = doveadm_debug;
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield /* load all configured mail plugins */
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield mail_storage_service_modules =
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield module_dir_load_missing(mail_storage_service_modules,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield doveadm_settings->mail_plugin_dir,
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield doveadm_settings->mail_plugins,
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield &mod_set);
08754f305b580801ae800df32ace5dc7b9b191d9Michael H. Warfield}
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfieldvoid doveadm_mail_deinit(void)
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield{
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield array_free(&doveadm_mail_cmds);
164105f6563d98b832f603e28e506dbabed22cf3Michael H. Warfield}
b4f7af7a520b23c873e404562ec518a576e63d4cMichael H. Warfield