From: Timo Sirainen Date: Thu, 16 Dec 2021 02:48:40 +0000 (+0200) Subject: doveadm: Replace who_lookup() with iterator API X-Git-Tag: 2.4.0~4512 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae69ca607d5d31bd39c903f4383de19d4a6acf18;p=thirdparty%2Fdovecot%2Fcore.git doveadm: Replace who_lookup() with iterator API --- diff --git a/src/doveadm/doveadm-kick.c b/src/doveadm/doveadm-kick.c index a0b06f38af..6f0bb22576 100644 --- a/src/doveadm/doveadm-kick.c +++ b/src/doveadm/doveadm-kick.c @@ -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); diff --git a/src/doveadm/doveadm-who.c b/src/doveadm/doveadm-who.c index be45e7d318..6c0551836d 100644 --- a/src/doveadm/doveadm-who.c +++ b/src/doveadm/doveadm-who.c @@ -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); diff --git a/src/doveadm/doveadm-who.h b/src/doveadm/doveadm-who.h index 474d2039d1..51504d8f64 100644 --- a/src/doveadm/doveadm-who.h +++ b/src/doveadm/doveadm-who.h @@ -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 */