doveadm-mail.c revision 2e57fc359c4520bb6ddba32095475e5f518c4066
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "lib.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "array.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "lib-signals.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "ioloop.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "module-dir.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "wildcard-match.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "master-service.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-user.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-namespace.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-storage.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-storage-settings.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-storage-service.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-search-build.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-search-parser.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "doveadm.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "doveadm-settings.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "doveadm-mail.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include <stdio.h>
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include <stdlib.h>
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan BoschARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid (*hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstruct doveadm_mail_cmd_module_register
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch doveadm_mail_cmd_module_register = { 0 };
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic int killed_signo = 0;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstruct doveadm_mail_cmd_context *
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_cmd_alloc_size(size_t size)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct doveadm_mail_cmd_context *ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch pool_t pool;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_assert(size >= sizeof(struct doveadm_mail_cmd_context));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch pool = pool_alloconly_create("doveadm mail cmd", 1024);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx = p_malloc(pool, size);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->pool = pool;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschcmd_purge_run(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_user *user)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_namespace *ns;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch for (ns = user->namespaces; ns != NULL; ns = ns->next) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ns->type != NAMESPACE_PRIVATE || ns->alias_for != NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch continue;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (mail_storage_purge(ns->storage) < 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_error("Purging namespace '%s' failed: %s", ns->prefix,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_get_last_error(ns->storage, NULL));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic struct doveadm_mail_cmd_context *cmd_purge_alloc(void)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct doveadm_mail_cmd_context *ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->v.run = cmd_purge_run;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic struct mailbox *
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschmailbox_find_and_open(struct mail_user *user, const char *mailbox)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_namespace *ns;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mailbox *box;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *orig_mailbox = mailbox;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ns = mail_namespace_find(user->namespaces, &mailbox);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ns == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("Can't find namespace for mailbox %s", mailbox);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_KEEP_RECENT |
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch MAILBOX_FLAG_IGNORE_ACLS);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (mailbox_open(box) < 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("Opening mailbox %s failed: %s", orig_mailbox,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_get_last_error(mailbox_get_storage(box),
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch NULL));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return box;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstruct mailbox *
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mailbox *box;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch box = mailbox_find_and_open(user, mailbox);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("Syncing mailbox %s failed: %s", mailbox,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_get_last_error(mailbox_get_storage(box),
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch NULL));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return box;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstruct mail_search_args *
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_build_search_args(const char *const args[])
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_search_parser *parser;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_search_args *sargs;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *error;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch parser = mail_search_parser_init_cmdline(args);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (mail_search_build(mail_search_register_get_human(),
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch parser, "UTF-8", &sargs, &error) < 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("%s", error);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_search_parser_deinit(&parser);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return sargs;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstruct force_resync_cmd_context {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct doveadm_mail_cmd_context ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *mailbox;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch};
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void cmd_force_resync_run(struct doveadm_mail_cmd_context *_ctx,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_user *user)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct force_resync_cmd_context *ctx =
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch (struct force_resync_cmd_context *)_ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_storage *storage;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mailbox *box;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch box = mailbox_find_and_open(user, ctx->mailbox);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch storage = mailbox_get_storage(box);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC |
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) < 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("Forcing a resync on mailbox %s failed: %s",
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->mailbox,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_get_last_error(storage, NULL));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mailbox_free(&box);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void cmd_force_resync_init(struct doveadm_mail_cmd_context *_ctx,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *const args[])
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct force_resync_cmd_context *ctx =
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch (struct force_resync_cmd_context *)_ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *mailbox = args[0];
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (mailbox == NULL || args[1] != NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch doveadm_mail_help_name("force-resync");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->mailbox = p_strdup(ctx->ctx.pool, mailbox);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic struct doveadm_mail_cmd_context *cmd_force_resync_alloc(void)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct force_resync_cmd_context *ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx = doveadm_mail_cmd_alloc(struct force_resync_cmd_context);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->ctx.v.init = cmd_force_resync_init;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->ctx.v.run = cmd_force_resync_run;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return &ctx->ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic int
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_next_user(struct doveadm_mail_cmd_context *ctx,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const struct mail_storage_service_input *input,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char **error_r)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_storage_service_user *service_user;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_user *mail_user;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *error;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch int ret;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_set_failure_prefix(t_strdup_printf("doveadm(%s): ", input->username));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ret = mail_storage_service_lookup(ctx->storage_service, input,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch &service_user, &error);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ret <= 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ret < 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch *error_r = t_strdup_printf("User lookup failed: %s",
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch error);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return ret;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ret = mail_storage_service_next(ctx->storage_service, service_user,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch &mail_user);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ret < 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch *error_r = "User init failed";
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_service_user_free(&service_user);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return ret;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->v.run(ctx, mail_user);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_user_unref(&mail_user);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_service_user_free(&service_user);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return 1;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *username,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch enum mail_storage_service_flags service_flags)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_storage_service_input input;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *error;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch int ret;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (username == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("USER environment is missing and -u option not used");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch memset(&input, 0, sizeof(input));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch input.username = username;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->storage_service = mail_storage_service_init(master_service, NULL,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch service_flags);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (hook_doveadm_mail_init != NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch hook_doveadm_mail_init(ctx);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ret = doveadm_mail_next_user(ctx, &input, &error);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ret < 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("%s", error);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch else if (ret == 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("User no longer exists");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_service_deinit(&ctx->storage_service);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch killed_signo = si->si_signo;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_all_users(struct doveadm_mail_cmd_context *ctx,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *wildcard_user,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch enum mail_storage_service_flags service_flags)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mail_storage_service_input input;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch unsigned int user_idx, user_count, interval, n;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *user, *error;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch int ret;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch memset(&input, 0, sizeof(input));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch input.service = "doveadm";
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->storage_service = mail_storage_service_init(master_service, NULL,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch service_flags);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch lib_signals_set_handler(SIGINT, FALSE, sig_die, NULL);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch lib_signals_set_handler(SIGTERM, FALSE, sig_die, NULL);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (hook_doveadm_mail_init != NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch hook_doveadm_mail_init(ctx);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch user_count = mail_storage_service_all_init(ctx->storage_service);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch n = user_count / 10000;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch for (interval = 10; n > 0 && interval < 1000; interval *= 10)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch n /= 10;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch user_idx = 0;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch while ((ret = ctx->v.get_next_user(ctx, &user)) > 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (wildcard_user != NULL) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (!wildcard_match_icase(user, wildcard_user))
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch continue;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch input.username = user;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch T_BEGIN {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ret = doveadm_mail_next_user(ctx, &input, &error);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ret < 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_error("%s", error);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch else if (ret == 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_info("User no longer exists, skipping");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch } T_END;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ret == -1)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch break;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (doveadm_verbose) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (++user_idx % interval == 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch printf("\r%d / %d", user_idx, user_count);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch fflush(stdout);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (killed_signo != 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_warning("Killed with signal %d", killed_signo);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ret = -1;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch break;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (doveadm_verbose)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch printf("\n");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_set_failure_prefix("doveadm: ");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ret < 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_error("Failed to iterate through some users");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_service_deinit(&ctx->storage_service);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_cmd_init_noop(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *const args[] ATTR_UNUSED)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic int
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_cmd_get_next_user(struct doveadm_mail_cmd_context *ctx,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char **username_r)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return mail_storage_service_all_next(ctx->storage_service, username_r);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_cmd_deinit_noop(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch enum mail_storage_service_flags service_flags =
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct doveadm_mail_cmd_context *ctx;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *getopt_args, *username, *wildcard_user;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch bool all_users = FALSE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch int c;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (doveadm_debug)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx = cmd->alloc();
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ctx->v.init == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->v.init = doveadm_mail_cmd_init_noop;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ctx->v.get_next_user == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->v.get_next_user = doveadm_mail_cmd_get_next_user;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ctx->v.deinit == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->v.deinit = doveadm_mail_cmd_deinit_noop;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch p_array_init(&ctx->module_contexts, ctx->pool, 5);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch getopt_args = t_strconcat("Au:", ctx->getopt_args, NULL);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch username = getenv("USER");
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch wildcard_user = NULL;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch while ((c = getopt(argc, argv, getopt_args)) > 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch switch (c) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch case 'A':
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch all_users = TRUE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch break;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch case 'u':
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch service_flags |=
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch username = optarg;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (strchr(username, '*') != NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch wildcard_user = username;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch break;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch default:
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (ctx->v.parse_arg == NULL ||
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch !ctx->v.parse_arg(ctx, c))
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch doveadm_mail_help(cmd);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch argv += optind;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (argv[0] != NULL && cmd->usage_args == NULL) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_fatal("doveadm %s: Unknown parameter: %s",
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cmd->name, argv[0]);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->v.init(ctx, (const void *)argv);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (!all_users && wildcard_user == NULL) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch doveadm_mail_single_user(ctx, username, service_flags);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch } else {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch doveadm_mail_all_users(ctx, wildcard_user, service_flags);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch ctx->v.deinit(ctx);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic bool
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschdoveadm_mail_try_run_multi_word(const struct doveadm_mail_cmd *cmd,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *cmdname, int argc, char *argv[])
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch unsigned int len;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (argc < 2)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return FALSE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch len = strlen(argv[1]);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (strncmp(cmdname, argv[1], len) != 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return FALSE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (cmdname[len] == ' ') {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch /* more args */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return doveadm_mail_try_run_multi_word(cmd, cmdname + len + 1,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch argc - 1, argv + 1);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (cmdname[len] != '\0')
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return FALSE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch /* match */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch doveadm_mail_cmd(cmd, argc - 1, argv + 1);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return TRUE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschbool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[])
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const struct doveadm_mail_cmd *cmd;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch unsigned int cmd_name_len;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_assert(argc > 0);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cmd_name_len = strlen(cmd_name);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch array_foreach(&doveadm_mail_cmds, cmd) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (strcmp(cmd->name, cmd_name) == 0) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch doveadm_mail_cmd(cmd, argc, argv);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return TRUE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch /* see if it matches a multi-word command */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (strncmp(cmd->name, cmd_name, cmd_name_len) == 0 &&
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cmd->name[cmd_name_len] == ' ') {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *subcmd = cmd->name + cmd_name_len + 1;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (doveadm_mail_try_run_multi_word(cmd, subcmd,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch argc, argv))
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return TRUE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return FALSE;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch /* for now we'll just assume that cmd will be permanently in memory */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch array_append(&doveadm_mail_cmds, cmd, 1);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid doveadm_mail_usage(void)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const struct doveadm_mail_cmd *cmd;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch array_foreach(&doveadm_mail_cmds, cmd) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch fprintf(stderr, USAGE_CMDNAME_FMT" [-u <user>|-A]", cmd->name);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (cmd->usage_args != NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch fprintf(stderr, " %s", cmd->usage_args);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch fputc('\n', stderr);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid doveadm_mail_help(const struct doveadm_mail_cmd *cmd)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch fprintf(stderr, "doveadm %s [-u <user>|-A] %s\n", cmd->name,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cmd->usage_args == NULL ? "" : cmd->usage_args);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch exit(0);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid doveadm_mail_try_help_name(const char *cmd_name)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const struct doveadm_mail_cmd *cmd;
array_foreach(&doveadm_mail_cmds, cmd) {
if (strcmp(cmd->name, cmd_name) == 0)
doveadm_mail_help(cmd);
}
}
void doveadm_mail_help_name(const char *cmd_name)
{
doveadm_mail_try_help_name(cmd_name);
i_fatal("Missing help for command %s", cmd_name);
}
static struct doveadm_mail_cmd cmd_force_resync = {
cmd_force_resync_alloc, "force-resync", "<mailbox>"
};
static struct doveadm_mail_cmd cmd_purge = {
cmd_purge_alloc, "purge", NULL
};
static struct doveadm_mail_cmd *mail_commands[] = {
&cmd_force_resync,
&cmd_purge,
&cmd_expunge,
&cmd_search,
&cmd_fetch,
&cmd_altmove,
&cmd_mailbox_list,
&cmd_mailbox_create,
&cmd_mailbox_delete,
&cmd_mailbox_rename,
&cmd_mailbox_subscribe,
&cmd_mailbox_unsubscribe
};
void doveadm_mail_init(void)
{
struct module_dir_load_settings mod_set;
unsigned int i;
i_array_init(&doveadm_mail_cmds, 32);
for (i = 0; i < N_ELEMENTS(mail_commands); i++)
doveadm_mail_register_cmd(mail_commands[i]);
memset(&mod_set, 0, sizeof(mod_set));
mod_set.version = master_service_get_version_string(master_service);
mod_set.require_init_funcs = TRUE;
mod_set.debug = doveadm_debug;
/* load all configured mail plugins */
mail_storage_service_modules =
module_dir_load_missing(mail_storage_service_modules,
doveadm_settings->mail_plugin_dir,
doveadm_settings->mail_plugins,
&mod_set);
}
void doveadm_mail_deinit(void)
{
array_free(&doveadm_mail_cmds);
}