doveadm-who.c revision bbd2991d36c5d1d5e34eb274d1e52f0f799e2ee4
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen struct hash_table *users; /* username -> who_user */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainentypedef void who_callback_t(struct who_context *ctx,
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainenstatic unsigned int who_user_hash(const void *p)
312d3129573fc63ba0d39105b68daccfab9f0c8fTimo Sirainen return str_hash(user->username) + str_hash(user->service);
312d3129573fc63ba0d39105b68daccfab9f0c8fTimo Sirainenstatic int who_user_cmp(const void *p1, const void *p2)
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen const struct who_user *user1 = p1, *user2 = p2;
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen if (strcmp(user1->username, user2->username) != 0)
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen if (strcmp(user1->service, user2->service) != 0)
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainenwho_user_has_ip(const struct who_user *user, const struct ip_addr *ip)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic void who_parse_line(const char *line, struct who_line *line_r)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen const char *const *args = t_strsplit(line, "\t");
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen const char *ident = args[0];
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen const char *p, *ip_str;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen ip_str = t_strdup_until(p, line_r->username++);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic void who_aggregate_line(struct who_context *ctx,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user = hash_table_lookup(ctx->users, &lookup_user);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user->username = p_strdup(ctx->pool, line->username);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen user->service = p_strdup(ctx->pool, line->service);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (line->ip.family != 0 && !who_user_has_ip(user, &line->ip))
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenstatic void who_lookup(struct who_context *ctx, who_callback_t *callback)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen#define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n"
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen#define ANVIL_CMD ANVIL_HANDSHAKE"CONNECT-DUMP\n"
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen i_fatal("net_connect_unix(%s) failed: %m", ctx->anvil_path);
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen input = i_stream_create_fd(fd, (size_t)-1, TRUE);
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0)
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen i_fatal("write(%s) failed: %m", ctx->anvil_path);
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) {
c5383a0ed56a188a7d5efaaa4c6f8243af432d65Timo Sirainen i_fatal("read(%s) failed: %m", ctx->anvil_path);
40eb305d9b12cf48400fe3806a8a15ad6d372952Timo Sirainenstatic bool who_user_filter_match(const struct who_user *user,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (strstr(user->username, filter->username) == NULL)
if (!ret)
return FALSE;
return TRUE;
if (first)
} T_END;
if (first)
} T_END;
return FALSE;
return FALSE;
return TRUE;
} T_END;
unsigned int net_bits;
usage();
usage();
argv++;
if (!separate_connections) {