doveadm-mail-index.c revision 8c072aac2949d0c840162d1a1d334e8367fd2993
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2010-2013 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "strescape.h"
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen#include "net.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "write-full.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-namespace.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-search-build.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mailbox-list-iter.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "doveadm-settings.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "doveadm-mail.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7888a9d2008eab9985096c46e1da9ee985c22a2aTimo Sirainen#include <stdio.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen#define INDEXER_SOCKET_NAME "indexer"
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen#define INDEXER_HANDSHAKE "VERSION\tindexer\t1\t0\n"
213b139965e8bde6c8aff02ffd9fd39a74c887a9Timo Sirainen
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainenstruct index_cmd_context {
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen struct doveadm_mail_cmd_context ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int queue_fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int max_recent_msgs;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int queue:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int have_wildcards:1;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen};
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainenstatic int cmd_index_box_precache(struct mailbox *box)
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen{
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen struct mailbox_status status;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen struct mailbox_transaction_context *trans;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen struct mail_search_args *search_args;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen struct mail_search_context *ctx;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen struct mail *mail;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen struct mailbox_metadata metadata;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen uint32_t seq;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen unsigned int counter = 0, max;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen int ret = 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen &metadata) < 0 ||
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ,
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen &status) < 0)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return -1;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen seq = status.last_cached_seq + 1;
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen if (seq > status.messages) {
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen if (doveadm_verbose) {
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen i_info("%s: Cache is already up to date",
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen mailbox_get_vname(box));
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen }
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen return 0;
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen }
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen if (doveadm_verbose) {
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen i_info("%s: Caching mails seq=%u..%u",
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen mailbox_get_vname(box), seq, status.messages);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen search_args = mail_search_build_init();
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen mail_search_build_add_seqset(search_args, seq, status.messages);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ctx = mailbox_search_init(trans, search_args, NULL,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen metadata.precache_fields, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_search_args_unref(&search_args);
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen max = status.messages - seq + 1;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen while (mailbox_search_next(ctx, &mail)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_precache(mail);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (doveadm_verbose && ++counter % 100 == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen printf("\r%u/%u", counter, max);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fflush(stdout);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (doveadm_verbose)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen printf("\r%u/%u\n", counter, max);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen if (mailbox_search_deinit(&ctx) < 0)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen ret = -1;
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen if (mailbox_transaction_commit(&trans) < 0)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen ret = -1;
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen return ret;
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen}
0d658231054332c3f4c04aab0422af649de89a8cTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic int
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainencmd_index_box(struct index_cmd_context *ctx, const struct mailbox_info *info)
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mailbox *box;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mailbox_status status;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen int ret = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen box = mailbox_alloc(info->ns->list, info->vname,
f2786c07cbd4a7a0a6a46c3e06dc4545aaf2f278Timo Sirainen MAILBOX_FLAG_IGNORE_ACLS);
0d658231054332c3f4c04aab0422af649de89a8cTimo Sirainen if (ctx->max_recent_msgs != 0) {
0d658231054332c3f4c04aab0422af649de89a8cTimo Sirainen /* index only if there aren't too many recent messages.
0d658231054332c3f4c04aab0422af649de89a8cTimo Sirainen don't bother syncing the mailbox, that alone can take a
0d658231054332c3f4c04aab0422af649de89a8cTimo Sirainen while with large maildirs. */
0d658231054332c3f4c04aab0422af649de89a8cTimo Sirainen if (mailbox_open(box) < 0) {
f2786c07cbd4a7a0a6a46c3e06dc4545aaf2f278Timo Sirainen i_error("Opening mailbox %s failed: %s", info->vname,
0d658231054332c3f4c04aab0422af649de89a8cTimo Sirainen mail_storage_get_last_error(mailbox_get_storage(box), NULL));
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen mailbox_free(&box);
9df8c9225140d9d1df5ddf4c6c9da61662ae6c44Timo Sirainen return -1;
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen }
f2786c07cbd4a7a0a6a46c3e06dc4545aaf2f278Timo Sirainen
9df8c9225140d9d1df5ddf4c6c9da61662ae6c44Timo Sirainen mailbox_get_open_status(box, STATUS_RECENT, &status);
9df8c9225140d9d1df5ddf4c6c9da61662ae6c44Timo Sirainen if (status.recent > ctx->max_recent_msgs) {
9df8c9225140d9d1df5ddf4c6c9da61662ae6c44Timo Sirainen mailbox_free(&box);
9df8c9225140d9d1df5ddf4c6c9da61662ae6c44Timo Sirainen return 0;
9df8c9225140d9d1df5ddf4c6c9da61662ae6c44Timo Sirainen }
40ef82c46f6652412b068ebcdac7c3e74840a284Timo Sirainen }
9df8c9225140d9d1df5ddf4c6c9da61662ae6c44Timo Sirainen
40ef82c46f6652412b068ebcdac7c3e74840a284Timo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen i_error("Syncing mailbox %s failed: %s", info->vname,
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen mail_storage_get_last_error(mailbox_get_storage(box), NULL));
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen ret = -1;
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen } else {
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen if (cmd_index_box_precache(box) < 0) {
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, box);
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen ret = -1;
8eeafcb306872435f3171e6acf5a9937aec3a175Timo Sirainen }
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainen }
a4d209d480d453566d331e870b8d0c99af7716c8Timo Sirainen mailbox_free(&box);
a4d209d480d453566d331e870b8d0c99af7716c8Timo Sirainen return ret;
a4d209d480d453566d331e870b8d0c99af7716c8Timo Sirainen}
a4d209d480d453566d331e870b8d0c99af7716c8Timo Sirainen
993e6c2caaae971dd3c34913a42d854e3b623261Timo Sirainenstatic void index_queue_connect(struct index_cmd_context *ctx)
a4d209d480d453566d331e870b8d0c99af7716c8Timo Sirainen{
a4d209d480d453566d331e870b8d0c99af7716c8Timo Sirainen const char *path;
a4d209d480d453566d331e870b8d0c99af7716c8Timo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen path = t_strconcat(doveadm_settings->base_dir,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen "/"INDEXER_SOCKET_NAME, NULL);
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen ctx->queue_fd = net_connect_unix(path);
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen if (ctx->queue_fd == -1)
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen i_fatal("net_connect_unix(%s) failed: %m", path);
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen if (write_full(ctx->queue_fd, INDEXER_HANDSHAKE,
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen strlen(INDEXER_HANDSHAKE)) < 0)
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen i_fatal("write(indexer) failed: %m");
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen}
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainenstatic void cmd_index_queue(struct index_cmd_context *ctx,
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen struct mail_user *user, const char *mailbox)
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen{
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen if (ctx->queue_fd == -1)
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen index_queue_connect(ctx);
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen T_BEGIN {
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen string_t *str = t_str_new(256);
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen str_append(str, "APPEND\t0\t");
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen str_append_tabescaped(str, user->username);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen str_append_c(str, '\t');
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen str_append_tabescaped(str, mailbox);
ccb77e2f63626ec46e5745ef4f38baa8e8e504fcTimo Sirainen str_printfa(str, "\t%u\n", ctx->max_recent_msgs);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if (write_full(ctx->queue_fd, str_data(str), str_len(str)) < 0)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen i_fatal("write(indexer) failed: %m");
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen } T_END;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen}
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenstatic int
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainencmd_index_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen{
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES |
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS |
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen MAILBOX_LIST_ITER_STAR_WITHIN_NS;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen const enum mail_namespace_type ns_mask = MAIL_NAMESPACE_TYPE_MASK_ALL;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen struct mailbox_list_iterate_context *iter;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen const struct mailbox_info *info;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen unsigned int i;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen int ret = 0;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (ctx->queue && !ctx->have_wildcards) {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* we can do this quickly without going through the mailboxes */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen for (i = 0; _ctx->args[i] != NULL; i++)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen cmd_index_queue(ctx, user, _ctx->args[i]);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen return 0;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen iter = mailbox_list_iter_init_namespaces(user->namespaces, _ctx->args,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ns_mask, iter_flags);
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
e376e08040b5f21ff79a15ae728d2532a34207f6Timo Sirainen if ((info->flags & (MAILBOX_NOSELECT |
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAILBOX_NONEXISTENT)) == 0) T_BEGIN {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (ctx->queue)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen cmd_index_queue(ctx, user, info->vname);
c21c33a8c98972c45349066fc76ac9e2c05013c1Timo Sirainen else {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (cmd_index_box(ctx, info) < 0)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ret = -1;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen } T_END;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (mailbox_list_iter_deinit(&iter) < 0) {
c21c33a8c98972c45349066fc76ac9e2c05013c1Timo Sirainen i_error("Listing mailboxes failed");
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen doveadm_mail_failed_error(_ctx, MAIL_ERROR_TEMP);
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen ret = -1;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen }
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen return ret;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen}
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainenstatic void cmd_index_init(struct doveadm_mail_cmd_context *_ctx,
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen const char *const args[])
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen{
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen unsigned int i;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen if (args[0] == NULL)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen doveadm_mail_help_name("index");
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen for (i = 0; args[i] != NULL; i++) {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (strchr(args[i], '*') != NULL ||
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen strchr(args[i], '%') != NULL) {
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen ctx->have_wildcards = TRUE;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen break;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen }
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen }
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen}
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainenstatic void cmd_index_deinit(struct doveadm_mail_cmd_context *_ctx)
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen{
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen if (ctx->queue_fd != -1) {
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen net_disconnect(ctx->queue_fd);
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen ctx->queue_fd = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen
f2786c07cbd4a7a0a6a46c3e06dc4545aaf2f278Timo Sirainenstatic bool
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainencmd_index_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen{
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen switch (c) {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen case 'q':
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ctx->queue = TRUE;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen break;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen case 'n':
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (str_to_uint(optarg, &ctx->max_recent_msgs) < 0) {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen i_fatal_status(EX_USAGE,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen "Invalid -n parameter number: %s", optarg);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen break;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen default:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen return TRUE;
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen}
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainenstatic struct doveadm_mail_cmd_context *cmd_index_alloc(void)
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen{
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen struct index_cmd_context *ctx;
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen ctx = doveadm_mail_cmd_alloc(struct index_cmd_context);
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen ctx->queue_fd = -1;
7471f28b16b81f9af413c879b3efb16eeafd2bd9Timo Sirainen ctx->ctx.getopt_args = "qn:";
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen ctx->ctx.v.parse_arg = cmd_index_parse_arg;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen ctx->ctx.v.init = cmd_index_init;
527ed64bc924b4a13b570a8450f8be3efdf71879Timo Sirainen ctx->ctx.v.deinit = cmd_index_deinit;
1cf72a848805fcf014b01c9d3665b6a157846a21Timo Sirainen ctx->ctx.v.run = cmd_index_run;
688f0fdfb7ca946e38ae34459b0ca30b71c8457cTimo Sirainen return &ctx->ctx;
688f0fdfb7ca946e38ae34459b0ca30b71c8457cTimo Sirainen}
688f0fdfb7ca946e38ae34459b0ca30b71c8457cTimo Sirainen
688f0fdfb7ca946e38ae34459b0ca30b71c8457cTimo Sirainenstruct doveadm_mail_cmd cmd_index = {
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen cmd_index_alloc, "index", "[-q] [-n <max recent>] <mailbox mask>"
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen};
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen