]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm index: Added -q option to do indexing via the new indexer service.
authorTimo Sirainen <tss@iki.fi>
Mon, 27 Jun 2011 20:03:00 +0000 (23:03 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 27 Jun 2011 20:03:00 +0000 (23:03 +0300)
src/doveadm/doveadm-mail-index.c

index d5c286c006a79bad0bbc3728c90ec9697b57397a..e7604065b22a61b2784ca7a2d7c442a446885cba 100644 (file)
@@ -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", "<mailbox>"
+       cmd_index_alloc, "index", "[-q] <mailbox>"
 };