doveadm-mail-index.c revision bf7dc750b95039981c0e9d728f313d50cf38a156
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2010-2017 Dovecot authors, see the included COPYING file */
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "lib.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "str.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "strescape.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "net.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "write-full.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "mail-namespace.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "mail-storage.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "mail-search-build.h"
a8fe899601735459641edae975c0fa08be8482e2Timo Sirainen#include "mailbox-list-iter.h"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#include "doveadm-settings.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "doveadm-mail.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen#include <stdio.h>
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#define INDEXER_SOCKET_NAME "indexer"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen#define INDEXER_HANDSHAKE "VERSION\tindexer\t1\t0\n"
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstruct index_cmd_context {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct doveadm_mail_cmd_context ctx;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen int queue_fd;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen unsigned int max_recent_msgs;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool queue:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_wildcards:1;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen};
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenstatic int cmd_index_box_precache(struct mailbox *box)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mailbox_status status;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mailbox_transaction_context *trans;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mail_search_args *search_args;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mail_search_context *ctx;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mail *mail;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mailbox_metadata metadata;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen uint32_t seq;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen unsigned int counter = 0, max;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen int ret = 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS,
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen &metadata) < 0) {
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen i_error("Mailbox %s: Precache-fields lookup failed: %s",
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen }
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen if (mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ,
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen &status) < 0) {
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen i_error("Mailbox %s: Status lookup failed: %s",
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return -1;
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen seq = status.last_cached_seq + 1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (seq > status.messages) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (doveadm_verbose) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen i_info("%s: Cache is already up to date",
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_get_vname(box));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (doveadm_verbose) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen i_info("%s: Caching mails seq=%u..%u",
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_get_vname(box), seq, status.messages);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen search_args = mail_search_build_init();
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mail_search_build_add_seqset(search_args, seq, status.messages);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ctx = mailbox_search_init(trans, search_args, NULL,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen metadata.precache_fields, NULL);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mail_search_args_unref(&search_args);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen max = status.messages - seq + 1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen while (mailbox_search_next(ctx, &mail)) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mail_precache(mail);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (doveadm_verbose && ++counter % 100 == 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen printf("\r%u/%u", counter, max);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen fflush(stdout);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (doveadm_verbose)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen printf("\r%u/%u\n", counter, max);
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen if (mailbox_search_deinit(&ctx) < 0) {
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen i_error("Mailbox %s: Mail search failed: %s",
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ret = -1;
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen }
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen if (mailbox_transaction_commit(&trans) < 0) {
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen i_error("Mailbox %s: Transaction commit failed: %s",
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_vname(box),
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ret = -1;
6a262c9bd8f57cf1e57112e0522dbdab28ae8c29Timo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return ret;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic int
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainencmd_index_box(struct index_cmd_context *ctx, const struct mailbox_info *info)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox *box;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen struct mailbox_status status;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen int ret = 0;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen box = mailbox_alloc(info->ns->list, info->vname,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_FLAG_IGNORE_ACLS);
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen if (ctx->max_recent_msgs != 0) {
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen /* index only if there aren't too many recent messages.
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen don't bother syncing the mailbox, that alone can take a
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen while with large maildirs. */
ecf44c74416ffa4e7c331e49a1e283be6b1aa668Timo Sirainen if (mailbox_open(box) < 0) {
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen i_error("Opening mailbox %s failed: %s", info->vname,
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen mailbox_free(&box);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return -1;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen }
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen mailbox_get_open_status(box, STATUS_RECENT, &status);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (status.recent > ctx->max_recent_msgs) {
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen mailbox_free(&box);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return 0;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen }
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen i_error("Syncing mailbox %s failed: %s", info->vname,
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(box, NULL));
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ret = -1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen } else {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (cmd_index_box_precache(box) < 0) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_free(&box);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return ret;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainenstatic void index_queue_connect(struct index_cmd_context *ctx)
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen{
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen const char *path;
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen path = t_strconcat(doveadm_settings->base_dir,
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen "/"INDEXER_SOCKET_NAME, NULL);
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen ctx->queue_fd = net_connect_unix(path);
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen if (ctx->queue_fd == -1)
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen i_fatal("net_connect_unix(%s) failed: %m", path);
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen if (write_full(ctx->queue_fd, INDEXER_HANDSHAKE,
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen strlen(INDEXER_HANDSHAKE)) < 0)
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen i_fatal("write(indexer) failed: %m");
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen}
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstatic void cmd_index_queue(struct index_cmd_context *ctx,
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct mail_user *user, const char *mailbox)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen{
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen if (ctx->queue_fd == -1)
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen index_queue_connect(ctx);
adea69875046ece77dc36abd3f88a241a3f17ad9Timo Sirainen i_assert(ctx->queue_fd != -1);
0950aed81d1e9618264e6aa4d214d89e005ec8d6Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen T_BEGIN {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen string_t *str = t_str_new(256);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen str_append(str, "APPEND\t0\t");
d03a871a77f8ec36f48f5fea98d810e51b186fdbTimo Sirainen str_append_tabescaped(str, user->username);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen str_append_c(str, '\t');
d03a871a77f8ec36f48f5fea98d810e51b186fdbTimo Sirainen str_append_tabescaped(str, mailbox);
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen str_printfa(str, "\t%u\n", ctx->max_recent_msgs);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (write_full(ctx->queue_fd, str_data(str), str_len(str)) < 0)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen i_fatal("write(indexer) failed: %m");
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen } T_END;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen}
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainenstatic int
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainencmd_index_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
737561538a2dcdcda948a1da2830a612d8263a23Timo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES |
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS |
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_LIST_ITER_STAR_WITHIN_NS;
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen const enum mail_namespace_type ns_mask = MAIL_NAMESPACE_TYPE_MASK_ALL;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox_list_iterate_context *iter;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const struct mailbox_info *info;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen unsigned int i;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen int ret = 0;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (ctx->queue && !ctx->have_wildcards) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen /* we can do this quickly without going through the mailboxes */
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen for (i = 0; _ctx->args[i] != NULL; i++)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen cmd_index_queue(ctx, user, _ctx->args[i]);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return 0;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen iter = mailbox_list_iter_init_namespaces(user->namespaces, _ctx->args,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ns_mask, iter_flags);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((info->flags & (MAILBOX_NOSELECT |
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_NONEXISTENT)) == 0) T_BEGIN {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (ctx->queue)
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen cmd_index_queue(ctx, user, info->vname);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen else {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (cmd_index_box(ctx, info) < 0)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen } T_END;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (mailbox_list_iter_deinit(&iter) < 0) {
ded274d94e795765b1d2e76da2ea74b22fbcd1d5Timo Sirainen i_error("Listing mailboxes failed: %s",
d4847b921058734e0668bc7690465c91523d9ec0Martti Rannanjärvi mailbox_list_get_last_internal_error(user->namespaces->list, NULL));
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen doveadm_mail_failed_error(_ctx, MAIL_ERROR_TEMP);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen }
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return ret;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstatic void cmd_index_init(struct doveadm_mail_cmd_context *_ctx,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const char *const args[])
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen unsigned int i;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (args[0] == NULL)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_mail_help_name("index");
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen for (i = 0; args[i] != NULL; i++) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (strchr(args[i], '*') != NULL ||
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen strchr(args[i], '%') != NULL) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->have_wildcards = TRUE;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen break;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen}
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstatic void cmd_index_deinit(struct doveadm_mail_cmd_context *_ctx)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen if (ctx->queue_fd != -1) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen net_disconnect(ctx->queue_fd);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->queue_fd = -1;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen}
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainenstatic bool
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainencmd_index_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen switch (c) {
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen case 'q':
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->queue = TRUE;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen break;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen case 'n':
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (str_to_uint(optarg, &ctx->max_recent_msgs) < 0) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen i_fatal_status(EX_USAGE,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen "Invalid -n parameter number: %s", optarg);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen }
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen break;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen default:
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen return FALSE;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen }
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen return TRUE;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic struct doveadm_mail_cmd_context *cmd_index_alloc(void)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen struct index_cmd_context *ctx;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx = doveadm_mail_cmd_alloc(struct index_cmd_context);
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->queue_fd = -1;
fcaf124d4a727424a338cccfd4274c2393818cd3Timo Sirainen ctx->ctx.getopt_args = "qn:";
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->ctx.v.parse_arg = cmd_index_parse_arg;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->ctx.v.init = cmd_index_init;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->ctx.v.deinit = cmd_index_deinit;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen ctx->ctx.v.run = cmd_index_run;
6c00502d4ece417ead501db8f0ee3e8287ba4459Timo Sirainen return &ctx->ctx;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
71f4549303dc1691382748a096c2ada9d2a1a9feAki Tuomistruct doveadm_cmd_ver2 doveadm_cmd_index_ver2 = {
71f4549303dc1691382748a096c2ada9d2a1a9feAki Tuomi .name = "index",
c45a841bee3f42ec6524b8f62c3fd457115c3f97Timo Sirainen .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-q] [-n <max recent>] <mailbox mask>",
71f4549303dc1691382748a096c2ada9d2a1a9feAki Tuomi .mail_cmd = cmd_index_alloc,
71f4549303dc1691382748a096c2ada9d2a1a9feAki TuomiDOVEADM_CMD_PARAMS_START
71f4549303dc1691382748a096c2ada9d2a1a9feAki TuomiDOVEADM_CMD_MAIL_COMMON
71f4549303dc1691382748a096c2ada9d2a1a9feAki TuomiDOVEADM_CMD_PARAM('q',"queue",CMD_PARAM_BOOL,0)
fed9f797a9d7647f78eeec3fcea91972ed45bbbeAki TuomiDOVEADM_CMD_PARAM('n',"max-recent",CMD_PARAM_STR,0)
71f4549303dc1691382748a096c2ada9d2a1a9feAki TuomiDOVEADM_CMD_PARAM('\0',"mailbox-mask",CMD_PARAM_STR,CMD_PARAM_FLAG_POSITIONAL)
71f4549303dc1691382748a096c2ada9d2a1a9feAki TuomiDOVEADM_CMD_PARAMS_END
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen};