doveadm-mail-index.c revision 643a81fff9003cba13deb49a565a3c8171da524d
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen/* Copyright (c) 2010-2011 Dovecot authors, see the included COPYING file */
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "lib.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "mail-namespace.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "mail-storage.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "mail-search-build.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen#include "doveadm-mail.h"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenenum cache_mask {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_HDR = 0x01,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_BODY = 0x02,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_RECEIVED_DATE = 0x04,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_SAVE_DATE = 0x08,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_VIRTUAL_SIZE = 0x10,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_PHYSICAL_SIZE = 0x20,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_POP3_UIDL = 0x40,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen CACHE_GUID = 0x80
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen};
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic bool fts_is_enabled = FALSE;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic enum cache_mask cache_fields_get(const struct mailbox_status *status)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const char *const *cache_fields;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen unsigned int i, count;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen enum cache_mask cache = 0;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache_fields = array_get(status->cache_fields, &count);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen for (i = 0; i < count; i++) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (strncmp(cache_fields[i], "hdr.", 4) == 0 ||
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen strcmp(cache_fields[i], "date.sent") == 0 ||
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen strcmp(cache_fields[i], "imap.envelope") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_HDR;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(cache_fields[i], "mime.parts") == 0 ||
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen strcmp(cache_fields[i], "imap.body") == 0 ||
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen strcmp(cache_fields[i], "imap.bodystructure") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_BODY;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(cache_fields[i], "date.received") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_RECEIVED_DATE;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(cache_fields[i], "date.save") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_SAVE_DATE;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(cache_fields[i], "size.virtual") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_VIRTUAL_SIZE;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(cache_fields[i], "size.physical") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_PHYSICAL_SIZE;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(cache_fields[i], "pop3.uidl") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_POP3_UIDL;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (strcmp(cache_fields[i], "guid") == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache |= CACHE_GUID;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen else if (doveadm_debug) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen i_debug("Ignoring unknown cache field: %s",
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache_fields[i]);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return cache;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic int cache_add(struct mailbox *box, const struct mailbox_status *status,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen enum cache_mask cache)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox_transaction_context *trans;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mail *mail;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen uint32_t seq;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen time_t date;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen uoff_t size;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const char *str;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (doveadm_debug) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen i_debug("%s: Nothing in mailbox cache, skipping",
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_get_vname(box));
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return 0;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen /* find the first message we need to index */
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen trans = mailbox_transaction_begin(box, 0);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail = mail_alloc(trans, 0, NULL);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen for (seq = status->messages; seq > 0; seq--) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_set_seq(mail, seq);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (mail_is_cached(mail))
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen break;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen seq++;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (doveadm_debug) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (seq > status->messages) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen i_debug("%s: Cache is already up to date",
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_get_vname(box));
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen } else {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen i_debug("%s: Caching mails seq=%u..%u cache=0x%x",
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_get_vname(box),
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen seq, status->messages, cache);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen for (; seq <= status->messages; seq++) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_set_seq(mail, seq);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((cache & (CACHE_HDR | CACHE_BODY)) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_parse(mail, (cache & CACHE_BODY) != 0);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((cache & CACHE_RECEIVED_DATE) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)mail_get_received_date(mail, &date);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((cache & CACHE_SAVE_DATE) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)mail_get_save_date(mail, &date);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((cache & CACHE_VIRTUAL_SIZE) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)mail_get_virtual_size(mail, &size);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((cache & CACHE_PHYSICAL_SIZE) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)mail_get_physical_size(mail, &size);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((cache & CACHE_POP3_UIDL) != 0) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)mail_get_special(mail, MAIL_FETCH_UIDL_BACKEND,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen &str);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if ((cache & CACHE_GUID) != 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)mail_get_special(mail, MAIL_FETCH_GUID, &str);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_free(&mail);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (mailbox_transaction_commit(&trans) < 0) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen i_error("Commiting mailbox %s failed: %s",
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_get_vname(box),
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_storage_get_last_error(mailbox_get_storage(box), NULL));
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return -1;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return 0;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic int fts_update(struct mailbox *box, const struct mailbox_status *status)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox_transaction_context *t;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mail_search_args *search_args;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mail_search_arg *arg;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mail_search_context *ctx;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mail *mail;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen int ret;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (!fts_is_enabled)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return 0;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen /* a bit kludgy way to trigger the full text search update:
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen search for a string in the last message */
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen t = mailbox_transaction_begin(box, 0);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen search_args = mail_search_build_init();
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen search_args->charset = "UTF-8";
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_search_build_add_seqset(search_args,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen status->messages, status->messages);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen arg = mail_search_build_add(search_args, SEARCH_BODY_FAST);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen arg->value.str = "xyzzy";
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx = mailbox_search_init(t, search_args, NULL);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_search_args_unref(&search_args);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail = mail_alloc(t, 0, NULL);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen while (mailbox_search_next(ctx, mail)) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_free(&mail);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (mailbox_search_deinit(&ctx) < 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ret = -1;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)mailbox_transaction_commit(&t);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return ret;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic int
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainencmd_index_box(const struct mailbox_info *info)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox *box;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox_status status;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const char *storage_name;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen enum cache_mask cache;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen int ret = 0;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen storage_name = mail_namespace_get_storage_name(info->ns, info->name);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen box = mailbox_alloc(info->ns->list, storage_name,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_FLAG_KEEP_RECENT |
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_FLAG_IGNORE_ACLS);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen i_error("Syncing mailbox %s failed: %s", info->name,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mail_storage_get_last_error(mailbox_get_storage(box), NULL));
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_free(&box);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return -1;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_get_status(box, STATUS_MESSAGES | STATUS_CACHE_FIELDS, &status);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cache = cache_fields_get(&status);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ret = cache_add(box, &status, cache);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (fts_update(box, &status) < 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ret = -1;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen mailbox_free(&box);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return ret;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic void
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainencmd_index_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_LIST_ITER_RAW_LIST |
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_LIST_ITER_NO_AUTO_INBOX |
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS |
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen MAILBOX_LIST_ITER_STAR_WITHIN_NS;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const enum namespace_type ns_mask =
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen NAMESPACE_PRIVATE | NAMESPACE_SHARED | NAMESPACE_PUBLIC;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct mailbox_list_iterate_context *iter;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const struct mailbox_info *info;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (mail_user_plugin_getenv(user, "fts") != NULL) T_BEGIN {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const char *const *plugins;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen plugins = t_strsplit(user->set->mail_plugins, " ");
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen for (; *plugins != NULL; plugins++) {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (strncmp(*plugins, "fts", 3) == 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen fts_is_enabled = TRUE;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen } T_END;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo 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 {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen (void)cmd_index_box(info);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen } T_END;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen }
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (mailbox_list_iter_deinit(&iter) < 0)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen i_error("Listing mailboxes failed");
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic void cmd_index_init(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED,
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen const char *const args[])
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen if (args[0] == NULL)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen doveadm_mail_help_name("index");
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstatic struct doveadm_mail_cmd_context *cmd_index_alloc(void)
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen{
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen struct doveadm_mail_cmd_context *ctx;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx->v.init = cmd_index_init;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen ctx->v.run = cmd_index_run;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen return ctx;
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen}
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainenstruct doveadm_mail_cmd cmd_index = {
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen cmd_index_alloc, "index", "<mailbox>"
643a81fff9003cba13deb49a565a3c8171da524dTimo Sirainen};