doveadm-mail-index.c revision 61cf001f1944d92eb25f113ba4c08985d6e30d53
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2010-2017 Dovecot authors, see the included COPYING file */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "lib.h"
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen#include "str.h"
ff487c974815bdaa2d05a3b834f4c2c841f4cc34Timo Sirainen#include "strescape.h"
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen#include "net.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "write-full.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "mail-namespace.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "mail-storage.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "mail-search-build.h"
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen#include "mailbox-list-iter.h"
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen#include "doveadm-settings.h"
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen#include "doveadm-mail.h"
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen#include <stdio.h>
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen#define INDEXER_SOCKET_NAME "indexer"
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen#define INDEXER_HANDSHAKE "VERSION\tindexer\t1\t0\n"
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainenstruct index_cmd_context {
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen struct doveadm_mail_cmd_context ctx;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen int queue_fd;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen unsigned int max_recent_msgs;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen bool queue:1;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen bool have_wildcards:1;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen};
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainenstatic int cmd_index_box_precache(struct mailbox *box)
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen{
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen struct mailbox_status status;
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen struct mailbox_transaction_context *trans;
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen struct mail_search_args *search_args;
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen struct mail_search_context *ctx;
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen struct mail *mail;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct mailbox_metadata metadata;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen uint32_t seq;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen unsigned int counter = 0, max;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen int ret = 0;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen &metadata) < 0) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_error("Mailbox %s: Precache-fields lookup failed: %s",
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen mailbox_get_vname(box),
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen mailbox_get_last_internal_error(box, NULL));
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen if (mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ,
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen &status) < 0) {
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen i_error("Mailbox %s: Status lookup failed: %s",
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen mailbox_get_vname(box),
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen mailbox_get_last_internal_error(box, NULL));
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen return -1;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen seq = status.last_cached_seq + 1;
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen if (seq > status.messages) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (doveadm_verbose) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen i_info("%s: Cache is already up to date",
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen mailbox_get_vname(box));
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen return 0;
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (doveadm_verbose) {
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen i_info("%s: Caching mails seq=%u..%u",
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen mailbox_get_vname(box), seq, status.messages);
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen }
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC);
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen search_args = mail_search_build_init();
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen mail_search_build_add_seqset(search_args, seq, status.messages);
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen ctx = mailbox_search_init(trans, search_args, NULL,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen metadata.precache_fields, NULL);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen mail_search_args_unref(&search_args);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen max = status.messages - seq + 1;
88f73e2ed3e99417255c90890fa46e11e6378c9dTimo Sirainen while (mailbox_search_next(ctx, &mail)) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen mail_precache(mail);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (doveadm_verbose && ++counter % 100 == 0) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen printf("\r%u/%u", counter, max);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen fflush(stdout);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (doveadm_verbose)
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen printf("\r%u/%u\n", counter, max);
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen if (mailbox_search_deinit(&ctx) < 0) {
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen i_error("Mailbox %s: Mail search failed: %s",
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen mailbox_get_vname(box),
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen mailbox_get_last_internal_error(box, NULL));
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen ret = -1;
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen }
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen if (mailbox_transaction_commit(&trans) < 0) {
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen i_error("Mailbox %s: Transaction commit failed: %s",
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen mailbox_get_vname(box),
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen mailbox_get_last_internal_error(box, NULL));
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen ret = -1;
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return ret;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen}
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainenstatic int
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainencmd_index_box(struct index_cmd_context *ctx, const struct mailbox_info *info)
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen{
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen struct mailbox *box;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen struct mailbox_status status;
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen int ret = 0;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen box = mailbox_alloc(info->ns->list, info->vname,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen MAILBOX_FLAG_IGNORE_ACLS);
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen mailbox_set_reason(box, ctx->ctx.cmd->name);
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen if (ctx->max_recent_msgs != 0) {
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen /* index only if there aren't too many recent messages.
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen don't bother syncing the mailbox, that alone can take a
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen while with large maildirs. */
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen if (mailbox_open(box) < 0) {
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen i_error("Opening mailbox %s failed: %s", info->vname,
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen mailbox_get_last_internal_error(box, NULL));
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk doveadm_mail_failed_mailbox(&ctx->ctx, box);
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen mailbox_free(&box);
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen return -1;
d368bfd671ae6d04a69eb7f418521d49b8bbf77aTimo Sirainen }
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen mailbox_get_open_status(box, STATUS_RECENT, &status);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (status.recent > ctx->max_recent_msgs) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen mailbox_free(&box);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return 0;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen i_error("Syncing mailbox %s failed: %s", info->vname,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen mailbox_get_last_internal_error(box, NULL));
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen ret = -1;
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen } else {
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen if (cmd_index_box_precache(box) < 0) {
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen ret = -1;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen mailbox_free(&box);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return ret;
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen}
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainenstatic void index_queue_connect(struct index_cmd_context *ctx)
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen{
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen const char *path;
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen path = t_strconcat(doveadm_settings->base_dir,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen "/"INDEXER_SOCKET_NAME, NULL);
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen ctx->queue_fd = net_connect_unix(path);
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen if (ctx->queue_fd == -1)
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen i_fatal("net_connect_unix(%s) failed: %m", path);
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen if (write_full(ctx->queue_fd, INDEXER_HANDSHAKE,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen strlen(INDEXER_HANDSHAKE)) < 0)
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen i_fatal("write(indexer) failed: %m");
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen}
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainenstatic void cmd_index_queue(struct index_cmd_context *ctx,
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen struct mail_user *user, const char *mailbox)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen{
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (ctx->queue_fd == -1)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen index_queue_connect(ctx);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen i_assert(ctx->queue_fd != -1);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen T_BEGIN {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen string_t *str = t_str_new(256);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen str_append(str, "APPEND\t0\t");
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen str_append_tabescaped(str, user->username);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen str_append_c(str, '\t');
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen str_append_tabescaped(str, mailbox);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen str_printfa(str, "\t%u\n", ctx->max_recent_msgs);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (write_full(ctx->queue_fd, str_data(str), str_len(str)) < 0)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen i_fatal("write(indexer) failed: %m");
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen } T_END;
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen}
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainenstatic int
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainencmd_index_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen{
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
0727e38ac12efb8963a339daf56255e2be1f29fcTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES |
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS |
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen MAILBOX_LIST_ITER_STAR_WITHIN_NS;
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen const enum mail_namespace_type ns_mask = MAIL_NAMESPACE_TYPE_MASK_ALL;
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen struct mailbox_list_iterate_context *iter;
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen const struct mailbox_info *info;
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen unsigned int i;
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen int ret = 0;
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen
dd93aba1901a457346990f49c54a738947dc7128Timo Sirainen if (ctx->queue && !ctx->have_wildcards) {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen /* we can do this quickly without going through the mailboxes */
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen for (i = 0; _ctx->args[i] != NULL; i++)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen cmd_index_queue(ctx, user, _ctx->args[i]);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen return 0;
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen }
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen iter = mailbox_list_iter_init_namespaces(user->namespaces, _ctx->args,
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen ns_mask, iter_flags);
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen if ((info->flags & (MAILBOX_NOSELECT |
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainen MAILBOX_NONEXISTENT)) == 0) T_BEGIN {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (ctx->queue)
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen cmd_index_queue(ctx, user, info->vname);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen else {
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen if (cmd_index_box(ctx, info) < 0)
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainen ret = -1;
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen }
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen } T_END;
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainen }
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (mailbox_list_iter_deinit(&iter) < 0) {
e4d34f2fbee451219599d71505594df704093ce3Timo Sirainen i_error("Listing mailboxes failed: %s",
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen mailbox_list_get_last_internal_error(user->namespaces->list, NULL));
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen doveadm_mail_failed_error(_ctx, MAIL_ERROR_TEMP);
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen ret = -1;
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen }
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen return ret;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainenstatic void cmd_index_init(struct doveadm_mail_cmd_context *_ctx,
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen const char *const args[])
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen{
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen unsigned int i;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (args[0] == NULL)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen doveadm_mail_help_name("index");
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen for (i = 0; args[i] != NULL; i++) {
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen if (strchr(args[i], '*') != NULL ||
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen strchr(args[i], '%') != NULL) {
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen ctx->have_wildcards = TRUE;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen break;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen}
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic void cmd_index_deinit(struct doveadm_mail_cmd_context *_ctx)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen if (ctx->queue_fd != -1) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen net_disconnect(ctx->queue_fd);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen ctx->queue_fd = -1;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen}
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic bool
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainencmd_index_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen switch (c) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen case 'q':
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen ctx->queue = TRUE;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen break;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen case 'n':
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen if (str_to_uint(optarg, &ctx->max_recent_msgs) < 0) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_fatal_status(EX_USAGE,
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen "Invalid -n parameter number: %s", optarg);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen break;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen default:
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen return FALSE;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen return TRUE;
}
static struct doveadm_mail_cmd_context *cmd_index_alloc(void)
{
struct index_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct index_cmd_context);
ctx->queue_fd = -1;
ctx->ctx.getopt_args = "qn:";
ctx->ctx.v.parse_arg = cmd_index_parse_arg;
ctx->ctx.v.init = cmd_index_init;
ctx->ctx.v.deinit = cmd_index_deinit;
ctx->ctx.v.run = cmd_index_run;
return &ctx->ctx;
}
struct doveadm_cmd_ver2 doveadm_cmd_index_ver2 = {
.name = "index",
.usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-q] [-n <max recent>] <mailbox mask>",
.mail_cmd = cmd_index_alloc,
DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_MAIL_COMMON
DOVEADM_CMD_PARAM('q',"queue",CMD_PARAM_BOOL,0)
DOVEADM_CMD_PARAM('n',"max-recent",CMD_PARAM_STR,0)
DOVEADM_CMD_PARAM('\0',"mailbox-mask",CMD_PARAM_STR,CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAMS_END
};