doveadm-mail.c revision 5fb3f13537dffd15a31e997da133a721c0728af8
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "lib.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "array.h"
b87761f9bbef949f31dae297e619ac3f5e9c2b2eTimo Sirainen#include "lib-signals.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "ioloop.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "module-dir.h"
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz#include "master-service.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "mail-user.h"
de5f478d9e7ae7b8e58082e0b30b6ce1f034236aTimo Sirainen#include "mail-namespace.h"
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen#include "mail-storage.h"
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen#include "mail-storage-settings.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "mail-storage-service.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "doveadm.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "doveadm-settings.h"
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen#include "doveadm-mail.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <stdio.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <stdlib.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo SirainenARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic int killed_signo = 0;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainenstatic void
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainencmd_purge(struct mail_user *user, const char *const args[] ATTR_UNUSED)
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen{
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen struct mail_namespace *ns;
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ns->type != NAMESPACE_PRIVATE || ns->alias_for != NULL)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen continue;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen if (mail_storage_purge(ns->storage) < 0) {
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen i_error("Purging namespace '%s' failed: %s", ns->prefix,
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen mail_storage_get_last_error(ns->storage, NULL));
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen }
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen }
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen}
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
01aca4a521410be85e1f39e37c662435d052f48aAki Tuomistatic struct mailbox *
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainenmailbox_find_and_open(struct mail_user *user, const char *mailbox)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen{
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen struct mail_namespace *ns;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen struct mailbox *box;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen const char *orig_mailbox = mailbox;
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen ns = mail_namespace_find(user->namespaces, &mailbox);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen if (ns == NULL)
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen i_fatal("Can't find namespace for mailbox %s", mailbox);
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_KEEP_RECENT |
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen MAILBOX_FLAG_IGNORE_ACLS);
01aca4a521410be85e1f39e37c662435d052f48aAki Tuomi if (mailbox_open(box) < 0) {
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen i_fatal("Opening mailbox %s failed: %s", orig_mailbox,
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen mail_storage_get_last_error(mailbox_get_storage(box),
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen NULL));
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen }
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen return box;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen}
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainenstruct mailbox *
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainendoveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox)
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen{
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen struct mailbox *box;
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen
8a6afcd8a6d9ed69626add85a7b75105ee3cb6a1Timo Sirainen box = mailbox_find_and_open(user, mailbox);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen i_fatal("Syncing mailbox %s failed: %s", mailbox,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mail_storage_get_last_error(mailbox_get_storage(box),
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen NULL));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return box;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void cmd_force_resync(struct mail_user *user, const char *const args[])
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *mailbox = args[0];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_storage *storage;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mailbox *box;
c72cfe4a2bda39fff3b8a8bd64b31a7cc14d7d11Timo Sirainen
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen if (mailbox == NULL)
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen doveadm_mail_help_name("force-resync");
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
14189e0d0af45ddcb888d026bd8d7e4609912ec5Timo Sirainen box = mailbox_find_and_open(user, mailbox);
e564ff0581fc44b78badf8da36e68f9f7a27807eTimo Sirainen storage = mailbox_get_storage(box);
f9eee365367f37b1692c07db6c23d30243844aaaTimo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FORCE_RESYNC |
f7d018e7e0980044e3d537958126e44ef4c45056Timo Sirainen MAILBOX_SYNC_FLAG_FIX_INCONSISTENT) < 0) {
7cd055a212d44067e2d94452c05691d696c9f699Timo Sirainen i_fatal("Forcing a resync on mailbox %s failed: %s", mailbox,
8952d797eca36f997ec36569e783871b597a9216Timo Sirainen mail_storage_get_last_error(storage, NULL));
2599a77a28bde0653fa090802424469904d518eeTimo Sirainen }
07038d3a12a915e98f794566f56a0ed12e0653ebAki Tuomi mailbox_free(&box);
dd3d20d9b5821077164183a260af9bde0db3ff3fTimo Sirainen}
e8434aad92ea6ff1c915b708294dbd0c7ff5908dMichael M Slusarz
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic int
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendoveadm_mail_next_user(doveadm_mail_command_t *cmd,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_storage_service_ctx *storage_service,
f0e416aa42058e7ccc0dc6deec0d4f4a19ee6ebeTimo Sirainen const struct mail_storage_service_input *input,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *const args[], const char **error_r)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_storage_service_user *service_user;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_user *mail_user;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen const char *error;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen i_set_failure_prefix(t_strdup_printf("doveadm(%s): ", input->username));
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen ret = mail_storage_service_lookup(storage_service, input,
f9cf9852b0338910f1a710297374943d66fea480Timo Sirainen &service_user, &error);
ba4626cd5be3d225a7a89aa338d92b8fb411fd1cTimo Sirainen if (ret <= 0) {
2a24f3565c61cb429d1e428601f153ce53b8bae3Timo Sirainen if (ret < 0) {
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen *error_r = t_strdup_printf("User lookup failed: %s",
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen error);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen }
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen return ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = mail_storage_service_next(storage_service, service_user,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen &mail_user);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret < 0) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *error_r = "User init failed";
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mail_storage_service_user_free(&service_user);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cmd(mail_user, args);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mail_storage_service_user_free(&service_user);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mail_user_unref(&mail_user);
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen return 1;
4db61af2cfe2b206113bcc4b6153521679702bb4Timo Sirainen}
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainenstatic void
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendoveadm_mail_single_user(doveadm_mail_command_t *cmd, const char *username,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen enum mail_storage_service_flags service_flags,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *const args[])
61f39b0358a72ebc693d84ba5bac74489ee7df41Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_storage_service_ctx *storage_service;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_storage_service_input input;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *error;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen if (username == NULL)
caf029d36a826106e48b8682f15ea0fc01fdd8f4Timo Sirainen i_fatal("USER environment is missing and -u option not used");
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(&input, 0, sizeof(input));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen input.username = username;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen storage_service = mail_storage_service_init(master_service, NULL,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen service_flags);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = doveadm_mail_next_user(cmd, storage_service, &input,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen args, &error);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret < 0)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen i_fatal("%s", error);
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen else if (ret == 0)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen i_fatal("User no longer exists");
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen mail_storage_service_deinit(&storage_service);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen}
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen killed_signo = si->si_signo;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendoveadm_mail_all_users(doveadm_mail_command_t *cmd,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen enum mail_storage_service_flags service_flags,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *const args[])
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_storage_service_input input;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct mail_storage_service_ctx *storage_service;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen unsigned int user_idx, user_count, interval, n;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *user, *error;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(&input, 0, sizeof(input));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen input.service = "doveadm";
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen storage_service = mail_storage_service_init(master_service, NULL,
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen service_flags);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen lib_signals_set_handler(SIGINT, FALSE, sig_die, NULL);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen lib_signals_set_handler(SIGTERM, FALSE, sig_die, NULL);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen user_count = mail_storage_service_all_init(storage_service);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen n = user_count / 10000;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen for (interval = 10; n > 0 && interval < 1000; interval *= 10)
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen n /= 10;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen user_idx = 0;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen while ((ret = mail_storage_service_all_next(storage_service,
1128c114416bdc4df0b41d3e15429a1522e5cfe4Timo Sirainen &user)) > 0) {
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen input.username = user;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen T_BEGIN {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = doveadm_mail_next_user(cmd, storage_service,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen &input, args, &error);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret < 0)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen i_error("%s", error);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen else if (ret == 0)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen i_info("User no longer exists, skipping");
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } T_END;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret == -1)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (doveadm_verbose) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (++user_idx % interval == 0) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen printf("\r%d / %d", user_idx, user_count);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen fflush(stdout);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (killed_signo != 0) {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen i_warning("Killed with signal %d", killed_signo);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen ret = -1;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen break;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (doveadm_verbose)
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen printf("\n");
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen i_set_failure_prefix("doveadm: ");
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (ret < 0)
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen i_error("Failed to iterate through some users");
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen mail_storage_service_deinit(&storage_service);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendoveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen enum mail_storage_service_flags service_flags =
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *username;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen bool all_users = FALSE;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int c;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen if (doveadm_debug)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen username = getenv("USER");
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen while ((c = getopt(argc, argv, "Au:")) > 0) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen switch (c) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case 'A':
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen all_users = TRUE;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case 'u':
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen service_flags |=
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen username = optarg;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen break;
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen default:
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen doveadm_mail_help(cmd);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen }
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen }
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen argv += optind;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!all_users) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen doveadm_mail_single_user(cmd->cmd, username, service_flags,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (const void *)argv);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen doveadm_mail_all_users(cmd->cmd, service_flags,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (const void *)argv);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenbool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[])
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const struct doveadm_mail_cmd *cmd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen array_foreach(&doveadm_mail_cmds, cmd) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (strcmp(cmd->name, cmd_name) == 0) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen doveadm_mail_cmd(cmd, argc, argv);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return TRUE;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen return FALSE;
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen}
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainenvoid doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd)
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen{
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen /* for now we'll just assume that cmd will be permanently in memory */
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen array_append(&doveadm_mail_cmds, cmd, 1);
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen}
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainen
7c04ede0da5749691624a1fb962ac29cd0167050Timo Sirainenvoid doveadm_mail_usage(void)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const struct doveadm_mail_cmd *cmd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen array_foreach(&doveadm_mail_cmds, cmd) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen fprintf(stderr, USAGE_CMDNAME_FMT" [-u <user>|-A]", cmd->name);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (cmd->usage_args != NULL)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen fprintf(stderr, " %s", cmd->usage_args);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen fputc('\n', stderr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenvoid doveadm_mail_help(const struct doveadm_mail_cmd *cmd)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen fprintf(stderr, "doveadm %s [-u <user>|-A] %s\n", cmd->name,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen cmd->usage_args == NULL ? "" : cmd->usage_args);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen exit(0);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenvoid doveadm_mail_help_name(const char *cmd_name)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const struct doveadm_mail_cmd *cmd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen array_foreach(&doveadm_mail_cmds, cmd) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (strcmp(cmd->name, cmd_name) == 0)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen doveadm_mail_help(cmd);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen i_fatal("Missing help for command %s", cmd_name);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic struct doveadm_mail_cmd mail_commands[] = {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen { cmd_purge, "purge", NULL },
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen { cmd_force_resync, "force-resync", "<mailbox>" },
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen { cmd_fetch, "fetch", "<mailbox> <search query>" },
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen { cmd_altmove, "altmove", "<search query>" }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen};
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenvoid doveadm_mail_init(void)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct module_dir_load_settings mod_set;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen unsigned int i;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen i_array_init(&doveadm_mail_cmds, 32);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen for (i = 0; i < N_ELEMENTS(mail_commands); i++)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen doveadm_mail_register_cmd(&mail_commands[i]);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(&mod_set, 0, sizeof(mod_set));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mod_set.version = master_service_get_version_string(master_service);
1fb5e50695bbbc0da082e5a6f19f29d2bb2f6531Timo Sirainen mod_set.require_init_funcs = TRUE;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mod_set.debug = doveadm_debug;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* load all configured mail plugins */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen mail_storage_service_modules =
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen module_dir_load_missing(mail_storage_service_modules,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen doveadm_settings->mail_plugin_dir,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen doveadm_settings->mail_plugins,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen &mod_set);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenvoid doveadm_mail_deinit(void)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen array_free(&doveadm_mail_cmds);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen