Le 18 févr. 2013 à 17:41, Axel Luttgens a écrit :
Le 18 févr. 2013 à 10:28, Axel Luttgens a écrit :
[...]
It seems it could be easily back ported to 2.1.x. I'll try and report back here.
Hello Timo,
Please find hereafter a proposal based on 2.1.14. [...]
Oops... big mistake wrt getenv(); sorry. I also noticed that I inadvertently backported a new behavior (i_error in 2.2 vs i_fatal in 2.1.14). Axel --- src/lib/hostpid.c.original 2013-02-18 12:46:25.000000000 +0100 +++ src/lib/hostpid.c 2013-02-19 12:40:47.000000000 +0100 @@ -3,9 +3,12 @@ #include "lib.h" #include "hostpid.h" +#include <stdlib.h> #include <unistd.h> #include <netdb.h> +#define HOSTNAME_DISALLOWED_CHARS "/\r\n\t" + const char *my_hostname = NULL; const char *my_pid = NULL; @@ -14,14 +17,26 @@ void hostpid_init(void) { static char hostname[256], pid[MAX_INT_STRLEN]; + + const char * name; - if (gethostname(hostname, sizeof(hostname)-1) == -1) - i_strocpy(hostname, "unknown", sizeof(hostname)); - hostname[sizeof(hostname)-1] = '\0'; - my_hostname = hostname; + /* Children should find MY_HOSTNAME_ENV set by master process. */ + /* Only master process should have to call gethostname() once. */ + name = getenv(MY_HOSTNAME_ENV); + if (name == NULL) { + if (gethostname(hostname, sizeof(hostname)-1) < 0) + i_fatal("gethostname() failed: %m"); + hostname[sizeof(hostname)-1] = '\0'; + my_hostname = hostname; + } + else{ + i_strocpy(hostname, name, sizeof(hostname)); + my_hostname = hostname; + } - if (strchr(hostname, '/') != NULL) - i_fatal("Invalid system hostname: %s", hostname); + if (my_hostname[0] == '\0' || + strcspn(my_hostname, HOSTNAME_DISALLOWED_CHARS) != strlen(my_hostname)) + i_fatal("Invalid system hostname: '%s'", my_hostname); /* allow calling hostpid_init() multiple times to reset hostname */ i_free_and_null(my_domain); @@ -35,12 +50,17 @@ struct hostent *hent; const char *name; + /* Children should find MY_HOSTDOMAIN_ENV set by master process. */ + /* Only master process should have to call gethostbyname() once. */ if (my_domain == NULL) { - hent = gethostbyname(my_hostname); - name = hent != NULL ? hent->h_name : NULL; + name = getenv(MY_HOSTDOMAIN_ENV); if (name == NULL) { - /* failed, use just the hostname */ - name = my_hostname; + hent = gethostbyname(my_hostname); + name = hent != NULL ? hent->h_name : NULL; + if (name == NULL) { + /* failed, use just the hostname */ + name = my_hostname; + } } my_domain = i_strdup(name); } --- src/lib/hostpid.h.original 2013-02-18 13:13:44.000000000 +0100 +++ src/lib/hostpid.h 2013-02-18 13:21:24.000000000 +0100 @@ -11,5 +11,10 @@ hostname. */ const char *my_hostdomain(void); +/* When set, these environments override above my_hostname and static my_domain. */ +/* Master process normally sets these to child processes. */ +#define MY_HOSTNAME_ENV "DOVECOT_HOSTNAME" +#define MY_HOSTDOMAIN_ENV "DOVECOT_HOSTDOMAIN" + #endif --- src/master/service-process.c.original 2013-02-18 13:24:23.000000000 +0100 +++ src/master/service-process.c 2013-02-18 13:39:15.000000000 +0100 @@ -234,6 +234,8 @@ service->set->service_count)); } env_put(t_strdup_printf(MASTER_UID_ENV"=%u", uid)); + env_put(t_strdup_printf(MY_HOSTNAME_ENV"=%s", my_hostname)); + env_put(t_strdup_printf(MY_HOSTDOMAIN_ENV"=%s", my_hostdomain())); if (!service->set->master_set->version_ignore) env_put(MASTER_DOVECOT_VERSION_ENV"="PACKAGE_VERSION);