From: Timo Sirainen Date: Mon, 27 Jun 2011 20:03:00 +0000 (+0300) Subject: doveadm index: Added -q option to do indexing via the new indexer service. X-Git-Tag: 2.1.alpha1~238 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c00502d4ece417ead501db8f0ee3e8287ba4459;p=thirdparty%2Fdovecot%2Fcore.git doveadm index: Added -q option to do indexing via the new indexer service. --- diff --git a/src/doveadm/doveadm-mail-index.c b/src/doveadm/doveadm-mail-index.c index d5c286c006..e7604065b2 100644 --- a/src/doveadm/doveadm-mail-index.c +++ b/src/doveadm/doveadm-mail-index.c @@ -1,11 +1,27 @@ /* Copyright (c) 2010-2011 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "str.h" +#include "strescape.h" +#include "network.h" +#include "write-full.h" #include "mail-namespace.h" #include "mail-storage.h" #include "mail-search-build.h" +#include "doveadm-settings.h" #include "doveadm-mail.h" +#define INDEXER_SOCKET_NAME "indexer" +#define INDEXER_HANDSHAKE "VERSION\tindexer\t1\t0\n" + +struct index_cmd_context { + struct doveadm_mail_cmd_context ctx; + + int queue_fd; + unsigned int queue:1; + unsigned int have_wildcards:1; +}; + static int cmd_index_box(const struct mailbox_info *info) { @@ -27,9 +43,26 @@ cmd_index_box(const struct mailbox_info *info) return ret; } +static void cmd_index_queue(struct index_cmd_context *ctx, + struct mail_user *user, const char *mailbox) +{ + T_BEGIN { + string_t *str = t_str_new(256); + + str_append(str, "APPEND\t0\t"); + str_tabescape_write(str, user->username); + str_append_c(str, '\t'); + str_tabescape_write(str, mailbox); + str_append_c(str, '\n'); + if (write_full(ctx->queue_fd, str_data(str), str_len(str)) < 0) + i_fatal("write(indexer) failed: %m"); + } T_END; +} + static void -cmd_index_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user) +cmd_index_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { + struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx; const enum mailbox_list_iter_flags iter_flags = MAILBOX_LIST_ITER_RAW_LIST | MAILBOX_LIST_ITER_NO_AUTO_BOXES | @@ -39,36 +72,98 @@ cmd_index_run(struct doveadm_mail_cmd_context *ctx, struct mail_user *user) NAMESPACE_PRIVATE | NAMESPACE_SHARED | NAMESPACE_PUBLIC; struct mailbox_list_iterate_context *iter; const struct mailbox_info *info; + unsigned int i; + + if (ctx->queue && !ctx->have_wildcards) { + /* we can do this quickly without going through the mailboxes */ + for (i = 0; _ctx->args[i] != NULL; i++) + cmd_index_queue(ctx, user, _ctx->args[i]); + return; + } - iter = mailbox_list_iter_init_namespaces(user->namespaces, ctx->args, + iter = mailbox_list_iter_init_namespaces(user->namespaces, _ctx->args, ns_mask, iter_flags); while ((info = mailbox_list_iter_next(iter)) != NULL) { if ((info->flags & (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) == 0) T_BEGIN { - (void)cmd_index_box(info); + if (ctx->queue) + cmd_index_queue(ctx, user, info->name); + else + (void)cmd_index_box(info); } T_END; } if (mailbox_list_iter_deinit(&iter) < 0) i_error("Listing mailboxes failed"); } -static void cmd_index_init(struct doveadm_mail_cmd_context *ctx ATTR_UNUSED, +static void cmd_index_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { + struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx; + const char *path; + unsigned int i; + if (args[0] == NULL) doveadm_mail_help_name("index"); + for (i = 0; args[i] != NULL; i++) { + if (strchr(args[i], '*') != NULL || + strchr(args[i], '%') != NULL) { + ctx->have_wildcards = TRUE; + break; + } + } + + if (ctx->queue) { + path = t_strconcat(doveadm_settings->base_dir, + "/"INDEXER_SOCKET_NAME, NULL); + ctx->queue_fd = net_connect_unix(path); + if (ctx->queue_fd == -1) + i_fatal("net_connect_unix(%s) failed: %m", path); + if (write_full(ctx->queue_fd, INDEXER_HANDSHAKE, + strlen(INDEXER_HANDSHAKE)) < 0) + i_fatal("write(indexer) failed: %m"); + } +} + +static void cmd_index_deinit(struct doveadm_mail_cmd_context *_ctx) +{ + struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx; + + if (ctx->queue_fd != -1) { + net_disconnect(ctx->queue_fd); + ctx->queue_fd = -1; + } +} + +static bool +cmd_index_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c) +{ + struct index_cmd_context *ctx = (struct index_cmd_context *)_ctx; + + switch (c) { + case 'q': + ctx->queue = TRUE; + break; + default: + return FALSE; + } + return TRUE; } static struct doveadm_mail_cmd_context *cmd_index_alloc(void) { - struct doveadm_mail_cmd_context *ctx; + struct index_cmd_context *ctx; - ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context); - ctx->v.init = cmd_index_init; - ctx->v.run = cmd_index_run; - return ctx; + ctx = doveadm_mail_cmd_alloc(struct index_cmd_context); + ctx->queue_fd = -1; + ctx->ctx.getopt_args = "q"; + 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_mail_cmd cmd_index = { - cmd_index_alloc, "index", "" + cmd_index_alloc, "index", "[-q] " };