doveadm-director.c revision 91770f85d9b2ac3e91b7aa74f57149412ae33c4c
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "lib.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "network.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "istream.h"
8338066be35c696b59fa9aefdc07042cb0797197Timo Sirainen#include "write-full.h"
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen#include "master-service.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "doveadm.h"
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen#include "doveadm-print.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include <stdio.h>
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include <stdlib.h>
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include <unistd.h>
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct director_context {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *socket_path;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct istream *input;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen};
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenextern struct doveadm_cmd doveadm_cmd_director[];
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainendirector_send(struct director_context *ctx, const char *data)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
8338066be35c696b59fa9aefdc07042cb0797197Timo Sirainen if (write_full(i_stream_get_fd(ctx->input), data, strlen(data)) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("write(%s) failed: %m", ctx->socket_path);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_connect(struct director_context *ctx)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen#define DIRECTOR_HANDSHAKE "VERSION\tdirector-doveadm\t1\t0\n"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *line;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen int fd;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
91770f85d9b2ac3e91b7aa74f57149412ae33c4cTimo Sirainen fd = doveadm_connect(ctx->socket_path);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen net_set_nonblock(fd, FALSE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx->input = i_stream_create_fd(fd, (size_t)-1, TRUE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_send(ctx, DIRECTOR_HANDSHAKE);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen line = i_stream_read_next_line(ctx->input);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (line == NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("%s disconnected", ctx->socket_path);
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen if (!version_string_verify(line, "director-doveadm", 1)) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("%s not a compatible director-doveadm socket",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx->socket_path);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_disconnect(struct director_context *ctx)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (ctx->input->stream_errno != 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("read(%s) failed: %m", ctx->socket_path);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_stream_destroy(&ctx->input);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct director_context *
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainencmd_director_init(int argc, char *argv[], unsigned int cmd_idx)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_context *ctx;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen int c;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx = t_new(struct director_context, 1);
1c7b846a17612b1fe7dcee797d0d8115201e58f4Timo Sirainen ctx->socket_path = t_strconcat(doveadm_settings->base_dir,
1c7b846a17612b1fe7dcee797d0d8115201e58f4Timo Sirainen "/director-admin", NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen while ((c = getopt(argc, argv, "a:")) > 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen switch (c) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen case 'a':
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx->socket_path = optarg;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen break;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen default:
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen help(&doveadm_cmd_director[cmd_idx]);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_connect(ctx);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return ctx;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainenstatic void
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainencmd_director_status_user(struct director_context *ctx, const char *user)
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen{
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen const char *line, *const *args;
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen unsigned int expires;
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen director_send(ctx, t_strdup_printf("USER-LOOKUP\t%s\n", user));
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen line = i_stream_read_next_line(ctx->input);
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen if (line == NULL) {
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen printf("Lookup failed\n");
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen return;
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen }
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen args = t_strsplit(line, "\t");
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen if (str_array_length(args) != 4 ||
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen str_to_uint(args[1], &expires) < 0) {
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen printf("Invalid reply from director\n");
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen return;
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen }
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen if (args[0][0] != '\0') {
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen printf("Current: %s (expires %s)\n",
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen args[0], unixdate2str(expires));
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen } else {
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen printf("Current: not assigned\n");
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen }
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen printf("Hashed: %s\n", args[2]);
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen printf("Initial config: %s\n", args[3]);
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen director_disconnect(ctx);
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen}
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void cmd_director_status(int argc, char *argv[])
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_context *ctx;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *line, *const *args;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx = cmd_director_init(argc, argv, 0);
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen if (argv[optind] != NULL) {
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen cmd_director_status_user(ctx, argv[optind]);
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen return;
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen }
b2024fa4e6ed39f9b5b6bb6c051f6d535fc0e011Timo Sirainen
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen doveadm_print_header_simple("mail server ip");
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen doveadm_print_header("vhosts", "vhosts",
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY);
4074caeff651a922131d53e2d8f83585d1b07433Timo Sirainen doveadm_print_header("users", "users",
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY);
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_send(ctx, "HOST-LIST\n");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (*line == '\0')
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen break;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen T_BEGIN {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen args = t_strsplit(line, "\t");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (str_array_length(args) >= 3) {
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen doveadm_print(args[0]);
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen doveadm_print(args[1]);
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen doveadm_print(args[2]);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } T_END;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_disconnect(ctx);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void cmd_director_add(int argc, char *argv[])
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_context *ctx;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ip_addr *ips;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i, ips_count, vhost_count = -1U;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ip_addr ip;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *host, *cmd, *line;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx = cmd_director_init(argc, argv, 0);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen host = argv[optind++];
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (host == NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen help(&doveadm_cmd_director[1]);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (argv[optind] != NULL) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (str_to_uint(argv[optind++], &vhost_count) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen help(&doveadm_cmd_director[1]);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (argv[optind] != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen help(&doveadm_cmd_director[1]);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (net_addr2ip(host, &ip) == 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ips = &ip;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ips_count = 1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } else {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (net_gethostbyname(host, &ips, &ips_count) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("gethostname(%s) failed: %m", host);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen cmd = vhost_count == -1U ?
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen t_strdup_printf("HOST-SET\t%s\n",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen net_ip2addr(&ips[i])) :
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen t_strdup_printf("HOST-SET\t%s\t%u\n",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen net_ip2addr(&ips[i]), vhost_count);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_send(ctx, cmd);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen line = i_stream_read_next_line(ctx->input);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (line == NULL || strcmp(line, "OK") != 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen fprintf(stderr, "%s: %s\n", net_ip2addr(&ips[i]),
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen line == NULL ? "failed" : line);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } else if (doveadm_verbose) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen printf("%s: OK\n", net_ip2addr(&ips[i]));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (i != ips_count)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("director add failed");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_disconnect(ctx);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void cmd_director_remove(int argc, char *argv[])
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct director_context *ctx;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ip_addr *ips;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i, ips_count;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ip_addr ip;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *host, *line;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ctx = cmd_director_init(argc, argv, 0);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen host = argv[optind++];
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (host == NULL || argv[optind] != NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen help(&doveadm_cmd_director[2]);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (net_addr2ip(host, &ip) == 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ips = &ip;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ips_count = 1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } else {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (net_gethostbyname(host, &ips, &ips_count) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("gethostname(%s) failed: %m", host);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_send(ctx,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen t_strdup_printf("HOST-REMOVE\t%s\n", net_ip2addr(&ip)));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen line = i_stream_read_next_line(ctx->input);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (line == NULL || strcmp(line, "OK") != 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen fprintf(stderr, "%s: %s\n", net_ip2addr(&ips[i]),
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen line == NULL ? "failed" :
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen (strcmp(line, "NOTFOUND") == 0 ?
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "doesn't exist" : line));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } else if (doveadm_verbose) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen printf("%s: removed\n", net_ip2addr(&ips[i]));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (i != ips_count)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("director remove failed");
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_disconnect(ctx);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainenstatic void cmd_director_flush_all(struct director_context *ctx)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen{
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen const char *line;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen director_send(ctx, "HOST-FLUSH\n");
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen line = i_stream_read_next_line(ctx->input);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen if (line == NULL)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen fprintf(stderr, "failed\n");
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen else if (strcmp(line, "OK") != 0)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen fprintf(stderr, "%s\n", line);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen else if (doveadm_verbose)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen printf("flushed\n");
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen director_disconnect(ctx);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen}
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainenstatic void cmd_director_flush(int argc, char *argv[])
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen{
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen struct director_context *ctx;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen struct ip_addr *ips;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen unsigned int i, ips_count;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen struct ip_addr ip;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen const char *host, *line;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen ctx = cmd_director_init(argc, argv, 0);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen host = argv[optind++];
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen if (host == NULL || argv[optind] != NULL)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen help(&doveadm_cmd_director[2]);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen if (strcmp(host, "all") == 0) {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen cmd_director_flush_all(ctx);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen return;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen }
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen if (net_addr2ip(host, &ip) == 0) {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen ips = &ip;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen ips_count = 1;
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen } else {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen if (net_gethostbyname(host, &ips, &ips_count) < 0)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen i_fatal("gethostname(%s) failed: %m", host);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen }
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen for (i = 0; i < ips_count; i++) {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen director_send(ctx,
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen t_strdup_printf("HOST-FLUSH\t%s\n", net_ip2addr(&ip)));
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen }
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen for (i = 0; i < ips_count; i++) {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen line = i_stream_read_next_line(ctx->input);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen if (line == NULL || strcmp(line, "OK") != 0) {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen fprintf(stderr, "%s: %s\n", net_ip2addr(&ips[i]),
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen line == NULL ? "failed" :
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen (strcmp(line, "NOTFOUND") == 0 ?
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen "doesn't exist" : line));
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen } else if (doveadm_verbose) {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen printf("%s: flushed\n", net_ip2addr(&ips[i]));
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen }
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen }
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen if (i != ips_count)
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen i_fatal("director flush failed");
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen director_disconnect(ctx);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen}
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct doveadm_cmd doveadm_cmd_director[] = {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen { cmd_director_status, "director status",
5f4a009a7763f62afe0245a9735931f95a89804dTimo Sirainen "[-a <director socket path>] [<user>]", NULL },
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen { cmd_director_add, "director add",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "[-a <director socket path>] <host> [<vhost count>]", NULL },
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen { cmd_director_remove, "director remove",
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen "[-a <director socket path>] <host>", NULL },
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen { cmd_director_flush, "director flush",
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen "[-a <director socket path>] <host>|all", NULL }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen};
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid doveadm_register_director_commands(void)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_director); i++)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen doveadm_register_cmd(&doveadm_cmd_director[i]);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}