doveadm-mail-iter.c revision 00b10a9ca50bca190e72a19aa6571ea612701d82
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen/* Copyright (c) 2010-2016 Dovecot authors, see the included COPYING file */
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen#include "lib.h"
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen#include "mail-storage.h"
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen#include "mail-namespace.h"
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen#include "mail-search.h"
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen#include "doveadm-mail.h"
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen#include "doveadm-mail-iter.h"
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenstruct doveadm_mail_iter {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct doveadm_mail_cmd_context *ctx;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mail_search_args *search_args;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mailbox *box;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mailbox_transaction_context *t;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mail_search_context *search_ctx;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen bool killed;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen};
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenint doveadm_mail_iter_init(struct doveadm_mail_cmd_context *ctx,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen const struct mailbox_info *info,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mail_search_args *search_args,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen enum mail_fetch_field wanted_fields,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen const char *const *wanted_headers,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen bool readonly,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct doveadm_mail_iter **iter_r)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct doveadm_mail_iter *iter;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mailbox_header_lookup_ctx *headers_ctx;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen const char *errstr;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen enum mail_error error;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen enum mailbox_flags readonly_flag =
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen readonly ? MAILBOX_FLAG_READONLY : 0;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter = i_new(struct doveadm_mail_iter, 1);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter->ctx = ctx;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter->box = mailbox_alloc(info->ns->list, info->vname,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen MAILBOX_FLAG_IGNORE_ACLS | readonly_flag);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter->search_args = search_args;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (mailbox_sync(iter->box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen errstr = mailbox_get_last_error(iter->box, &error);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (error == MAIL_ERROR_NOTFOUND) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen /* just ignore this mailbox */
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen *iter_r = iter;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return 0;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen i_error("Syncing mailbox %s failed: %s", info->vname, errstr);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen doveadm_mail_failed_mailbox(ctx, iter->box);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_free(&iter->box);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen i_free(iter);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return -1;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen headers_ctx = wanted_headers == NULL || wanted_headers[0] == NULL ?
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen NULL : mailbox_header_lookup_init(iter->box, wanted_headers);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mail_search_args_init(search_args, iter->box, FALSE, NULL);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter->t = mailbox_transaction_begin(iter->box, 0);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter->search_ctx = mailbox_search_init(iter->t, search_args, NULL,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen wanted_fields, headers_ctx);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen *iter_r = iter;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return 0;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenstatic int
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainendoveadm_mail_iter_deinit_transaction(struct doveadm_mail_iter *iter,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen bool commit)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen int ret = 0;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (iter->search_ctx != NULL) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (mailbox_search_deinit(&iter->search_ctx) < 0) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen i_error("Searching mailbox %s failed: %s",
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_get_vname(iter->box),
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_get_last_error(iter->box, NULL));
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen ret = -1;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (iter->t == NULL)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen ;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen else if (commit) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (mailbox_transaction_commit(&iter->t) < 0) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen i_error("Committing mailbox %s failed: %s",
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_get_vname(iter->box),
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_get_last_error(iter->box, NULL));
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen ret = -1;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen } else {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_transaction_rollback(&iter->t);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mail_search_args_deinit(iter->search_args);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return ret;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenstatic int
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainendoveadm_mail_iter_deinit_full(struct doveadm_mail_iter **_iter,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen bool sync, bool commit, bool keep_box)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct doveadm_mail_iter *iter = *_iter;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen int ret;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen *_iter = NULL;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen ret = doveadm_mail_iter_deinit_transaction(iter, commit);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (ret == 0 && sync) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen ret = mailbox_sync(iter->box, 0);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (ret < 0) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen i_error("Mailbox %s: Mailbox sync failed: %s",
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_get_vname(iter->box),
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_get_last_error(iter->box, NULL));
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (ret < 0)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen doveadm_mail_failed_mailbox(iter->ctx, iter->box);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen else if (iter->killed) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter->ctx->exit_code = EX_TEMPFAIL;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen ret = -1;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (!keep_box)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen mailbox_free(&iter->box);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen i_free(iter);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return ret;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenint doveadm_mail_iter_deinit(struct doveadm_mail_iter **_iter)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return doveadm_mail_iter_deinit_full(_iter, FALSE, TRUE, FALSE);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenint doveadm_mail_iter_deinit_sync(struct doveadm_mail_iter **_iter)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return doveadm_mail_iter_deinit_full(_iter, TRUE, TRUE, FALSE);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenint doveadm_mail_iter_deinit_keep_box(struct doveadm_mail_iter **iter,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mailbox **box_r)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen *box_r = (*iter)->box;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return doveadm_mail_iter_deinit_full(iter, FALSE, TRUE, TRUE);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenvoid doveadm_mail_iter_deinit_rollback(struct doveadm_mail_iter **_iter)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen (void)doveadm_mail_iter_deinit_full(_iter, FALSE, FALSE, FALSE);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenbool doveadm_mail_iter_next(struct doveadm_mail_iter *iter,
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen struct mail **mail_r)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (iter->search_ctx == NULL)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return FALSE;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen if (doveadm_is_killed()) {
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen iter->killed = TRUE;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return FALSE;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen }
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return mailbox_search_next(iter->search_ctx, mail_r);
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainenstruct mailbox *doveadm_mail_iter_get_mailbox(struct doveadm_mail_iter *iter)
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen{
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen return iter->box;
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen}
fb15bb48cf8be41cd94738c868b64608b4fda1adTimo Sirainen