]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Replace who_lookup() with iterator API
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 16 Dec 2021 02:48:40 +0000 (04:48 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 8 Feb 2022 09:48:24 +0000 (10:48 +0100)
src/doveadm/doveadm-kick.c
src/doveadm/doveadm-who.c
src/doveadm/doveadm-who.h

index a0b06f38af2e0dd243f446afc36efc9db4caecc6..6f0bb225760fc962252b5c3287ee05055800784d 100644 (file)
@@ -216,7 +216,12 @@ static void cmd_kick(struct doveadm_cmd_context *cctx)
        doveadm_print_formatted_set_format("%{result} ");
        doveadm_print_header_simple("result");
 
-       who_lookup(&ctx.who, kick_aggregate_line);
+       struct doveadm_who_iter *iter =
+               doveadm_who_iter_init(ctx.who.anvil_path);
+       struct who_line who_line;
+       while (doveadm_who_iter_next(iter, &who_line))
+               kick_aggregate_line(&ctx.who, &who_line);
+       doveadm_who_iter_deinit(&iter);
        kick_users(&ctx);
 
        hash_table_destroy(&ctx.pids);
index be45e7d318dfadcab113c43fbdfc45d78ce4db71..6c0551836d076731d4d4321cd8d6fa6c32a31356 100644 (file)
@@ -23,6 +23,11 @@ struct who_user {
        unsigned int connection_count;
 };
 
+struct doveadm_who_iter {
+       struct istream *input;
+       pool_t pool, line_pool;
+};
+
 static void who_user_ip(const struct who_user *user, struct ip_addr *ip_r)
 {
        if (array_count(&user->ips) == 0)
@@ -78,7 +83,8 @@ who_user_has_ip(const struct who_user *user, const struct ip_addr *ip)
        return FALSE;
 }
 
-static int who_parse_line(const char *line, struct who_line *line_r)
+static int who_parse_line(struct doveadm_who_iter *iter,
+                         const char *line, struct who_line *line_r)
 {
        const char *const *args = t_strsplit_tabescaped(line);
        i_zero(line_r);
@@ -87,10 +93,11 @@ static int who_parse_line(const char *line, struct who_line *line_r)
        if (str_array_length(args) < 6)
                return -1;
 
+       p_clear(iter->line_pool);
        if (str_to_pid(args[0], &line_r->pid) < 0)
                return -1;
-       line_r->username = args[1];
-       line_r->service = args[2];
+       line_r->username = p_strdup(iter->line_pool, args[1]);
+       line_r->service = p_strdup(iter->line_pool, args[2]);
        if (args[3][0] != '\0') {
                if (net_addr2ip(args[3], &line_r->ip) < 0)
                        return -1;
@@ -167,38 +174,64 @@ int who_parse_args(struct who_context *ctx, const char *const *masks)
        return 0;
 }
 
-void who_lookup(struct who_context *ctx, who_callback_t *callback)
+struct doveadm_who_iter *doveadm_who_iter_init(const char *anvil_path)
 {
 #define ANVIL_HANDSHAKE "VERSION\tanvil\t2\t0\n"
 #define ANVIL_CMD ANVIL_HANDSHAKE"CONNECT-DUMP\n"
-       struct istream *input;
+       struct doveadm_who_iter *iter;
        const char *line;
        int fd;
+       pool_t pool;
 
-       fd = doveadm_connect(ctx->anvil_path);
+       pool = pool_alloconly_create("doveadm who iter", 256);
+       iter = p_new(pool, struct doveadm_who_iter, 1);
+       iter->pool = pool;
+       iter->line_pool = pool_alloconly_create("doveadm who line", 256);
+
+       fd = doveadm_connect(anvil_path);
        net_set_nonblock(fd, FALSE);
        if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0)
-               i_fatal("write(%s) failed: %m", ctx->anvil_path);
+               i_fatal("write(%s) failed: %m", anvil_path);
+
+       iter->input = i_stream_create_fd_autoclose(&fd, SIZE_MAX);
+       i_stream_set_name(iter->input, anvil_path);
+       if ((line = i_stream_read_next_line(iter->input)) == NULL)
+               i_fatal("anvil didn't send header line");
+       return iter;
+}
+
+bool doveadm_who_iter_next(struct doveadm_who_iter *iter,
+                          struct who_line *who_line_r)
+{
+       const char *line;
+       int ret;
 
-       input = i_stream_create_fd_autoclose(&fd, SIZE_MAX);
-       while ((line = i_stream_read_next_line(input)) != NULL) {
+       while ((line = i_stream_read_next_line(iter->input)) != NULL) {
                if (*line == '\0')
                        break;
                T_BEGIN {
-                       struct who_line who_line;
-
-                       if (who_parse_line(line, &who_line) < 0)
-                               i_error("Invalid input: %s", line);
-                       else
-                               callback(ctx, &who_line);
+                       ret = who_parse_line(iter, line, who_line_r);
                } T_END;
+               if (ret < 0)
+                       i_error("Invalid input: %s", line);
+               else
+                       return TRUE;
        }
-       if (input->stream_errno != 0) {
-               i_fatal("read(%s) failed: %s", ctx->anvil_path,
-                       i_stream_get_error(input));
+       if (iter->input->stream_errno != 0) {
+               i_fatal("read(%s) failed: %s", i_stream_get_name(iter->input),
+                       i_stream_get_error(iter->input));
        }
+       return FALSE;
+}
+
+void doveadm_who_iter_deinit(struct doveadm_who_iter **_iter)
+{
+       struct doveadm_who_iter *iter = *_iter;
 
-       i_stream_destroy(&input);
+       *_iter = NULL;
+       i_stream_destroy(&iter->input);
+       pool_unref(&iter->line_pool);
+       pool_unref(&iter->pool);
 }
 
 static bool who_user_filter_match(const struct who_user *user,
@@ -327,8 +360,11 @@ static void cmd_who(struct doveadm_cmd_context *cctx)
        }
 
        doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
+       struct doveadm_who_iter *iter = doveadm_who_iter_init(ctx.anvil_path);
+       struct who_line who_line;
        if (!separate_connections) {
-               who_lookup(&ctx, who_aggregate_line);
+               while (doveadm_who_iter_next(iter, &who_line))
+                       who_aggregate_line(&ctx, &who_line);
                who_print(&ctx);
        } else {
                doveadm_print_header("username", "username",
@@ -337,8 +373,10 @@ static void cmd_who(struct doveadm_cmd_context *cctx)
                doveadm_print_header_simple("pid");
                doveadm_print_header_simple("ip");
                doveadm_print_header_simple("dest_ip");
-               who_lookup(&ctx, who_print_line);
+               while (doveadm_who_iter_next(iter, &who_line))
+                       who_print_line(&ctx, &who_line);
        }
+       doveadm_who_iter_deinit(&iter);
 
        hash_table_destroy(&ctx.users);
        pool_unref(&ctx.pool);
index 474d2039d1bf3cfd129b20958b0fc182bd2e6e31..51504d8f64e03ae288becc5c044d2edd78a80f7d 100644 (file)
@@ -32,9 +32,12 @@ typedef void who_callback_t(struct who_context *ctx,
 
 int who_parse_args(struct who_context *ctx, const char *const *masks);
 
-void who_lookup(struct who_context *ctx, who_callback_t *callback);
-
 bool who_line_filter_match(const struct who_line *line,
                           const struct who_filter *filter);
 
+struct doveadm_who_iter *doveadm_who_iter_init(const char *anvil_path);
+bool doveadm_who_iter_next(struct doveadm_who_iter *iter,
+                          struct who_line *who_line_r);
+void doveadm_who_iter_deinit(struct doveadm_who_iter **_iter);
+
 #endif /* DOVEADM_WHO_H */