doveadm-who.c revision c03f712279c54fc29368a914375a4c66855d253b
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2009-2014 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic unsigned int who_user_hash(const struct who_user *user)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return str_hash(user->username) + str_hash(user->service);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int who_user_cmp(const struct who_user *user1,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (strcmp(user1->username, user2->username) != 0)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (strcmp(user1->service, user2->service) != 0)
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainenwho_user_has_ip(const struct who_user *user, const struct ip_addr *ip)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int who_parse_line(const char *line, struct who_line *line_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *const *args = t_strsplit_tab(line);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *ident = args[0];
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen const char *p, *ip_str;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen ip_str = t_strdup_until(p, line_r->username++);
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainenstatic bool who_user_has_pid(struct who_user *user, pid_t pid)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic void who_aggregate_line(struct who_context *ctx,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen user = hash_table_lookup(ctx->users, &lookup_user);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen user->username = p_strdup(ctx->pool, line->username);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen user->service = p_strdup(ctx->pool, line->service);
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen if (line->ip.family != 0 && !who_user_has_ip(user, &line->ip))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid who_parse_args(struct who_context *ctx, char **args)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen if (net_parse_range(args[1], &net_ip, &net_bits) == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid who_lookup(struct who_context *ctx, who_callback_t *callback)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define ANVIL_CMD ANVIL_HANDSHAKE"CONNECT-DUMP\n"
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen input = i_stream_create_fd(fd, (size_t)-1, TRUE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("write(%s) failed: %m", ctx->anvil_path);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) {
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen i_fatal("read(%s) failed: %m", ctx->anvil_path);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainenstatic bool who_user_filter_match(const struct who_user *user,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!wildcard_match_icase(user->username, filter->username))
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainenstatic void who_print_user(const struct who_user *user)
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen doveadm_print(dec2str(user->connection_count));
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen doveadm_print_header("username", "username", 0);
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen while (hash_table_iterate(iter, ctx->users, &user, &user)) {
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen if (who_user_filter_match(user, &ctx->filter)) T_BEGIN {
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenbool who_line_filter_match(const struct who_line *line,
b7b9d4be2a1ff399026a5d6feeffd3a048f22be0Timo Sirainen if (!wildcard_match_icase(line->username, filter->username))
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen if (!net_is_in_network(&line->ip, &filter->net_ip,
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainenstatic void who_print_line(struct who_context *ctx,
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen unsigned int i;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (!who_line_filter_match(line, &ctx->filter))
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen for (i = 0; i < line->refcount; i++) T_BEGIN {
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen ctx.anvil_path = t_strconcat(doveadm_settings->base_dir, "/anvil", NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ctx.pool = pool_alloconly_create("who users", 10240);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen hash_table_create(&ctx.users, ctx.pool, 0, who_user_hash, who_user_cmp);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen "[-a <anvil socket path>] [-1] [<user mask>] [<ip/bits>]"