bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen#include "lib.h"
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen#include "array.h"
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen#include "mail-index.h"
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen#include "mail-storage.h"
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen#include "mail-search.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "doveadm-mailbox-list-iter.h"
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen#include "doveadm-mail-iter.h"
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen#include "doveadm-mail.h"
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainenstruct expunge_cmd_context {
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen struct doveadm_mail_cmd_context ctx;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen bool delete_empty_mailbox;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen};
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenstatic int
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainencmd_expunge_box(struct doveadm_mail_cmd_context *_ctx,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen const struct mailbox_info *info,
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen struct mail_search_args *search_args)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen{
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen struct expunge_cmd_context *ctx = (struct expunge_cmd_context *)_ctx;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen struct doveadm_mail_iter *iter;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen struct mailbox *box;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen struct mail *mail;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen enum mail_error error;
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen int ret = 0;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
00b10a9ca50bca190e72a19aa6571ea612701d82Aki Tuomi if (doveadm_mail_iter_init(_ctx, info, search_args, 0, NULL, FALSE,
c57ba1788a6598993a9625bbf26a4fedca23815eTimo Sirainen &iter) < 0)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return -1;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen while (doveadm_mail_iter_next(iter, &mail)) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (doveadm_debug) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen i_debug("expunge: box=%s uid=%u",
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen info->vname, mail->uid);
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen mail_expunge(mail);
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen if (doveadm_mail_iter_deinit_keep_box(&iter, &box) < 0)
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen ret = -1;
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen else if (mailbox_sync(box, 0) < 0) {
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen i_error("Syncing mailbox '%s' failed: %s",
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen doveadm_mail_failed_mailbox(_ctx, box);
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen ret = -1;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen }
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen if (ctx->delete_empty_mailbox && ret == 0) {
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen if (mailbox_delete_empty(box) < 0) {
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen error = mailbox_get_last_mail_error(box);
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen if (error != MAIL_ERROR_EXISTS) {
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen i_error("Deleting mailbox '%s' failed: %s",
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen doveadm_mail_failed_mailbox(_ctx, box);
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen ret = -1;
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen }
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen } else {
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen if (mailbox_set_subscribed(box, FALSE) < 0) {
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen i_error("Unsubscribing mailbox '%s' failed: %s",
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen doveadm_mail_failed_mailbox(_ctx, box);
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen ret = -1;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen }
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen }
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen }
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen mailbox_free(&box);
12224fcf2de6724c89f63c0f9ee857f28a270df5Timo Sirainen return ret;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen}
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenstatic bool
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenexpunge_search_args_is_mailbox_ok(struct mail_search_arg *args);
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenstatic bool
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenexpunge_search_args_is_mailbox_or_ok(struct mail_search_arg *args)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen{
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen struct mail_search_arg *arg;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen for (arg = args; arg != NULL; arg = arg->next) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen switch (arg->type) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_OR:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (!expunge_search_args_is_mailbox_or_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_SUB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_INTHREAD:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (!expunge_search_args_is_mailbox_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX:
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen case SEARCH_MAILBOX_GUID:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX_GLOB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen default:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen}
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenstatic bool
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenexpunge_search_args_is_mailbox_ok(struct mail_search_arg *args)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen{
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen struct mail_search_arg *arg;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen bool have_or = FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen /* a) we find one mailbox here in the SUB block */
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen for (arg = args; arg != NULL; arg = arg->next) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen switch (arg->type) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX:
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen case SEARCH_MAILBOX_GUID:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX_GLOB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_OR:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen have_or = TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_SUB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_INTHREAD:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (expunge_search_args_is_mailbox_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen default:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen /* b) there is at least one OR block, and all of the ORs must have
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen mailbox */
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (!have_or)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen for (arg = args; arg != NULL; arg = arg->next) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (arg->type == SEARCH_OR &&
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen !expunge_search_args_is_mailbox_or_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen}
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenstatic bool
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenexpunge_search_args_is_msgset_ok(struct mail_search_arg *args);
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenstatic bool
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenexpunge_search_args_is_msgset_or_ok(struct mail_search_arg *args)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen{
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen struct mail_search_arg *arg;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen /* we're done if all OR branches contain something else besides
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen MAILBOXes */
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen for (arg = args; arg != NULL; arg = arg->next) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen switch (arg->type) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX:
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen case SEARCH_MAILBOX_GUID:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX_GLOB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_OR:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (!expunge_search_args_is_msgset_or_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_SUB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (!expunge_search_args_is_msgset_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen default:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen}
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenstatic bool
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainenexpunge_search_args_is_msgset_ok(struct mail_search_arg *args)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen{
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen struct mail_search_arg *arg;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen /* all args can't be just MAILBOXes */
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen for (arg = args; arg != NULL; arg = arg->next) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen switch (arg->type) {
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX:
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen case SEARCH_MAILBOX_GUID:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_MAILBOX_GLOB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_OR:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen /* if each OR branch has something else than just
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen MAILBOXes, we're ok */
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (expunge_search_args_is_msgset_or_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen case SEARCH_SUB:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen if (expunge_search_args_is_msgset_ok(arg->value.subargs))
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen break;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen default:
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return TRUE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen }
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen return FALSE;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen}
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainenstatic int
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainencmd_expunge_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user)
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen{
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
b3126bef7460052415eea07b300d02c8eb07c1d7Timo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES |
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen struct doveadm_mailbox_list_iter *iter;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen const struct mailbox_info *info;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen int ret = 0;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen iter = doveadm_mailbox_list_iter_init(ctx, user, ctx->search_args,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen iter_flags);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (cmd_expunge_box(ctx, info, ctx->search_args) < 0)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen } T_END;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (doveadm_mailbox_list_iter_deinit(&iter) < 0)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return ret;
4eecd3e2aadb20768a60f701e329b4345d04430cTimo Sirainen}
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainenvoid expunge_search_args_check(struct mail_search_args *args, const char *cmd)
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen{
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen if (!expunge_search_args_is_mailbox_ok(args->args)) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen i_fatal_status(EX_USAGE,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen "%s: To avoid accidents, search query "
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen "must contain MAILBOX in all search branches", cmd);
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen }
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen if (!expunge_search_args_is_msgset_ok(args->args)) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen i_fatal_status(EX_USAGE,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen "%s: To avoid accidents, each branch in search query "
50d16f6fefefb19e41a01400ac11a2adb4d8c231Timo Sirainen "must contain something else besides MAILBOX "
50d16f6fefefb19e41a01400ac11a2adb4d8c231Timo Sirainen "(e.g. just add \"all\" if you want everything)", cmd);
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen }
6971937a6f3e93844dbd43bdbe903628e21a9422Timo Sirainen mail_search_args_simplify(args);
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen}
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainenstatic void cmd_expunge_init(struct doveadm_mail_cmd_context *ctx,
23878bd03d1de531e3261a25598beec621351910Timo Sirainen const char *const args[])
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen{
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen if (args[0] == NULL)
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen doveadm_mail_help_name("expunge");
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen ctx->search_args = doveadm_mail_build_search_args(args);
b932ee7fbbec6e79b777dcc7ba613b9e99f8337bTimo Sirainen expunge_search_args_check(ctx->search_args, "expunge");
23878bd03d1de531e3261a25598beec621351910Timo Sirainen}
23878bd03d1de531e3261a25598beec621351910Timo Sirainen
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainenstatic bool cmd_expunge_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen{
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen struct expunge_cmd_context *ctx = (struct expunge_cmd_context *)_ctx;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen switch (c) {
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen case 'd':
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen ctx->delete_empty_mailbox = TRUE;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen break;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen default:
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen return FALSE;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen }
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen return TRUE;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen}
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen
23878bd03d1de531e3261a25598beec621351910Timo Sirainenstatic struct doveadm_mail_cmd_context *cmd_expunge_alloc(void)
23878bd03d1de531e3261a25598beec621351910Timo Sirainen{
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen struct expunge_cmd_context *ctx;
23878bd03d1de531e3261a25598beec621351910Timo Sirainen
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen ctx = doveadm_mail_cmd_alloc(struct expunge_cmd_context);
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen ctx->ctx.getopt_args = "d";
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen ctx->ctx.v.parse_arg = cmd_expunge_parse_arg;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen ctx->ctx.v.init = cmd_expunge_init;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen ctx->ctx.v.run = cmd_expunge_run;
1a3f9d72e15fb931edf58f104fb7ff12d238f051Timo Sirainen return &ctx->ctx;
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen}
23878bd03d1de531e3261a25598beec621351910Timo Sirainen
977f08d645b1779527c0938bbb848b61064839c3Aki Tuomistruct doveadm_cmd_ver2 doveadm_cmd_expunge_ver2 = {
977f08d645b1779527c0938bbb848b61064839c3Aki Tuomi .name = "expunge",
977f08d645b1779527c0938bbb848b61064839c3Aki Tuomi .mail_cmd = cmd_expunge_alloc,
977f08d645b1779527c0938bbb848b61064839c3Aki Tuomi .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX "[-m] <search query>",
977f08d645b1779527c0938bbb848b61064839c3Aki TuomiDOVEADM_CMD_PARAMS_START
977f08d645b1779527c0938bbb848b61064839c3Aki TuomiDOVEADM_CMD_MAIL_COMMON
977f08d645b1779527c0938bbb848b61064839c3Aki TuomiDOVEADM_CMD_PARAM('d', "delete-empty-mailbox", CMD_PARAM_BOOL, 0)
977f08d645b1779527c0938bbb848b61064839c3Aki TuomiDOVEADM_CMD_PARAM('\0', "query", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
977f08d645b1779527c0938bbb848b61064839c3Aki TuomiDOVEADM_CMD_PARAMS_END
23878bd03d1de531e3261a25598beec621351910Timo Sirainen};