From: Timo Sirainen Date: Thu, 20 May 2010 10:37:15 +0000 (+0200) Subject: doveadm director status user: Show more ways of what user's potential hosts are. X-Git-Tag: 2.0.beta6~177 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=edd318d5866ac3fbc6e8df28fb24a4dfef93c884;p=thirdparty%2Fdovecot%2Fcore.git doveadm director status user: Show more ways of what user's potential hosts are. --HG-- branch : HEAD --- diff --git a/src/director/director.c b/src/director/director.c index b9dd4251b0..d938e9da94 100644 --- a/src/director/director.c +++ b/src/director/director.c @@ -208,6 +208,7 @@ void director_deinit(struct director **_dir) user_directory_deinit(&dir->users); mail_hosts_deinit(&dir->mail_hosts); + mail_hosts_deinit(&dir->orig_config_hosts); if (dir->to_request != NULL) timeout_remove(&dir->to_request); array_foreach(&dir->dir_hosts, hostp) diff --git a/src/director/director.h b/src/director/director.h index 59a5033d79..fcfd19960f 100644 --- a/src/director/director.h +++ b/src/director/director.h @@ -30,7 +30,11 @@ struct director { struct director_host *self_host; struct director_connection *left, *right; + /* current mail hosts */ struct mail_host_list *mail_hosts; + /* original mail hosts configured in config file. + this is used only for doveadm lookups */ + struct mail_host_list *orig_config_hosts; /* temporary user -> host associations */ struct user_directory *users; diff --git a/src/director/doveadm-connection.c b/src/director/doveadm-connection.c index 75fadbea0c..28f8d7e52a 100644 --- a/src/director/doveadm-connection.c +++ b/src/director/doveadm-connection.c @@ -120,16 +120,37 @@ static bool doveadm_cmd_user_lookup(struct doveadm_connection *conn, const char *line) { struct user *user; - unsigned int hash; + struct mail_host *host; + unsigned int username_hash; + string_t *str = t_str_new(256); + + username_hash = user_directory_get_username_hash(line); - hash = user_directory_get_username_hash(line); - user = user_directory_lookup(conn->dir->users, hash); + /* get user's current host */ + user = user_directory_lookup(conn->dir->users, username_hash); if (user == NULL) - o_stream_send_str(conn->output, "NOTFOUND\n"); + str_append(str, "\t0"); else { - o_stream_send_str(conn->output, t_strconcat( - net_ip2addr(&user->host->ip), "\n", NULL)); + str_printfa(str, "%s\t%u", net_ip2addr(&user->host->ip), + user->timestamp + + conn->dir->set->director_user_expire); } + + /* get host if it wasn't in user directory */ + host = mail_host_get_by_hash(conn->dir->mail_hosts, username_hash); + if (host == NULL) + str_append(str, "\t"); + else + str_printfa(str, "\t%s", net_ip2addr(&host->ip)); + + /* get host with default configuration */ + host = mail_host_get_by_hash(conn->dir->orig_config_hosts, + username_hash); + if (host == NULL) + str_append(str, "\t"); + else + str_printfa(str, "\t%s\n", net_ip2addr(&host->ip)); + o_stream_send(conn->output, str_data(str), str_len(str)); return TRUE; } diff --git a/src/director/mail-host.c b/src/director/mail-host.c index 521fd31401..b61cb656c5 100644 --- a/src/director/mail-host.c +++ b/src/director/mail-host.c @@ -195,3 +195,26 @@ void mail_hosts_deinit(struct mail_host_list **_list) array_free(&list->vhosts); i_free(list); } + +static struct mail_host *mail_host_dup(const struct mail_host *src) +{ + struct mail_host *dest; + + dest = i_new(struct mail_host, 1); + *dest = *src; + return dest; +} + +struct mail_host_list *mail_hosts_dup(const struct mail_host_list *src) +{ + struct mail_host_list *dest; + struct mail_host *const *hostp, *dest_host; + + dest = mail_hosts_init(); + array_foreach(&src->hosts, hostp) { + dest_host = mail_host_dup(*hostp); + array_append(&dest->hosts, &dest_host, 1); + } + mail_hosts_sort(dest); + return dest; +} diff --git a/src/director/mail-host.h b/src/director/mail-host.h index 84395f929b..073cb7493e 100644 --- a/src/director/mail-host.h +++ b/src/director/mail-host.h @@ -32,4 +32,6 @@ const ARRAY_TYPE(mail_host) *mail_hosts_get(struct mail_host_list *list); struct mail_host_list *mail_hosts_init(void); void mail_hosts_deinit(struct mail_host_list **list); +struct mail_host_list *mail_hosts_dup(const struct mail_host_list *src); + #endif diff --git a/src/director/main.c b/src/director/main.c index efba776ed6..099ef8d1ee 100644 --- a/src/director/main.c +++ b/src/director/main.c @@ -145,6 +145,7 @@ static void main_init(void) if (mail_hosts_parse_and_add(director->mail_hosts, set->director_mail_servers) < 0) i_fatal("Invalid value for director_mail_servers setting"); + director->orig_config_hosts = mail_hosts_dup(director->mail_hosts); director_connect(director); } diff --git a/src/doveadm/doveadm-director.c b/src/doveadm/doveadm-director.c index 8d27edadfe..988e3746e6 100644 --- a/src/doveadm/doveadm-director.c +++ b/src/doveadm/doveadm-director.c @@ -80,7 +80,8 @@ cmd_director_init(int argc, char *argv[], unsigned int cmd_idx) static void cmd_director_status_user(struct director_context *ctx, const char *user) { - const char *line; + const char *line, *const *args; + unsigned int expires; director_send(ctx, t_strdup_printf("USER-LOOKUP\t%s\n", user)); line = i_stream_read_next_line(ctx->input); @@ -89,10 +90,21 @@ cmd_director_status_user(struct director_context *ctx, const char *user) return; } - if (strcmp(line, "NOTFOUND") == 0) - printf("User not assigned to any server\n"); - else - printf("%s\n", line); + args = t_strsplit(line, "\t"); + if (str_array_length(args) != 4 || + str_to_uint(args[1], &expires) < 0) { + printf("Invalid reply from director\n"); + return; + } + + if (args[0][0] != '\0') { + printf("Current: %s (expires %s)\n", + args[0], unixdate2str(expires)); + } else { + printf("Current: not assigned\n"); + } + printf("Hashed: %s\n", args[2]); + printf("Initial config: %s\n", args[3]); director_disconnect(ctx); }