}
}
+static void master_service_init_socket_listeners(struct master_service *service)
+{
+ unsigned int i;
+ const char *value;
+ bool have_ssl_sockets = FALSE;
+
+ if (service->socket_count == 0)
+ return;
+
+ service->listeners =
+ i_new(struct master_service_listener, service->socket_count);
+
+ for (i = 0; i < service->socket_count; i++) {
+ struct master_service_listener *l = &service->listeners[i];
+
+ l->service = service;
+ l->fd = MASTER_LISTEN_FD_FIRST + i;
+
+ value = getenv(t_strdup_printf("SOCKET%u_SETTINGS", i));
+ if (value != NULL) {
+ const char *const *settings =
+ t_strsplit_tabescaped(value);
+
+ if (*settings != NULL) {
+ l->name = i_strdup_empty(*settings);
+ settings++;
+ }
+ while (*settings != NULL) {
+ if (strcmp(*settings, "ssl") == 0) {
+ l->ssl = TRUE;
+ have_ssl_sockets = TRUE;
+ }
+ settings++;
+ }
+ }
+ }
+ service->want_ssl_settings = have_ssl_sockets ||
+ (service->flags & MASTER_SERVICE_FLAG_USE_SSL_SETTINGS) != 0;
+}
+
struct master_service *
master_service_init(const char *name, enum master_service_flags flags,
int *argc, char **argv[], const char *getopt_str)
{
struct master_service *service;
- const char *value;
unsigned int count;
+ const char *value;
i_assert(name != NULL);
} else {
service->version_string = PACKAGE_VERSION;
}
+
+ /* listener configuration */
value = getenv("SOCKET_COUNT");
if (value != NULL)
service->socket_count = atoi(value);
- value = getenv("SSL_SOCKET_COUNT");
- if (value != NULL)
- service->ssl_socket_count = atoi(value);
- value = getenv("SOCKET_NAMES");
- if (value != NULL) {
- service->listener_names =
- p_strsplit_tabescaped(default_pool, value);
- service->listener_names_count =
- str_array_length((void *)service->listener_names);
- }
- service->want_ssl_settings = service->ssl_socket_count > 0 ||
- (flags & MASTER_SERVICE_FLAG_USE_SSL_SETTINGS) != 0;
+ T_BEGIN {
+ master_service_init_socket_listeners(service);
+ } T_END;
/* set up some kind of logging until we know exactly how and where
we want to log */
i_assert(listen_fd >= MASTER_LISTEN_FD_FIRST);
i = listen_fd - MASTER_LISTEN_FD_FIRST;
- return i < service->listener_names_count ?
- service->listener_names[i] : "";
+ i_assert(i < service->socket_count);
+ return service->listeners[i].name != NULL ?
+ service->listeners[i].name : "";
}
void master_service_set_avail_overflow_callback(struct master_service *service,
void master_service_deinit(struct master_service **_service)
{
struct master_service *service = *_service;
+ unsigned int i;
*_service = NULL;
lib_atexit_run();
io_loop_destroy(&service->ioloop);
- if (service->listener_names != NULL)
- p_strsplit_free(default_pool, service->listener_names);
+ for (i = 0; i < service->socket_count; i++)
+ i_free(service->listeners[i].name);
i_free(service->listeners);
i_free(service->getopt_str);
i_free(service->name);
master_service_client_connection_callback(service, &conn);
}
-static void io_listeners_init(struct master_service *service)
-{
- unsigned int i;
-
- if (service->socket_count == 0)
- return;
-
- service->listeners =
- i_new(struct master_service_listener, service->socket_count);
-
- for (i = 0; i < service->socket_count; i++) {
- struct master_service_listener *l = &service->listeners[i];
-
- l->service = service;
- l->fd = MASTER_LISTEN_FD_FIRST + i;
- l->name = i < service->listener_names_count ?
- service->listener_names[i] : "";
-
- if (i >= service->socket_count - service->ssl_socket_count)
- l->ssl = TRUE;
- }
-}
-
void master_service_io_listeners_add(struct master_service *service)
{
unsigned int i;
if (service->stopping)
return;
- if (service->listeners == NULL)
- io_listeners_init(service);
-
for (i = 0; i < service->socket_count; i++) {
struct master_service_listener *l = &service->listeners[i];
{
unsigned int i;
- if (service->listeners != NULL) {
- for (i = 0; i < service->socket_count; i++) {
- if (service->listeners[i].io != NULL)
- io_remove(&service->listeners[i].io);
- }
+ for (i = 0; i < service->socket_count; i++) {
+ if (service->listeners[i].io != NULL)
+ io_remove(&service->listeners[i].io);
}
}
{
unsigned int i;
- if (service->listeners != NULL) {
- for (i = 0; i < service->socket_count; i++) {
- if (service->listeners[i].io != NULL &&
- service->listeners[i].ssl)
- io_remove(&service->listeners[i].io);
- }
+ for (i = 0; i < service->socket_count; i++) {
+ if (service->listeners[i].io != NULL &&
+ service->listeners[i].ssl)
+ io_remove(&service->listeners[i].io);
}
}
{
unsigned int i;
- if (service->listeners != NULL) {
- /* close via listeners. some fds might be pipes that are
- currently handled as clients. we don't want to close them. */
- for (i = 0; i < service->socket_count; i++) {
- if (service->listeners[i].fd != -1) {
- if (close(service->listeners[i].fd) < 0) {
- i_error("close(listener %d) failed: %m",
- service->listeners[i].fd);
- }
- service->listeners[i].fd = -1;
+ /* close via listeners. some fds might be pipes that are
+ currently handled as clients. we don't want to close them. */
+ for (i = 0; i < service->socket_count; i++) {
+ if (service->listeners[i].fd != -1) {
+ if (close(service->listeners[i].fd) < 0) {
+ i_error("close(listener %d) failed: %m",
+ service->listeners[i].fd);
}
- }
- } else {
- for (i = 0; i < service->socket_count; i++) {
- int fd = MASTER_LISTEN_FD_FIRST + i;
-
- if (close(fd) < 0)
- i_error("close(listener %d) failed: %m", fd);
+ service->listeners[i].fd = -1;
}
}
}
{
struct service_listener *const *listeners;
ARRAY_TYPE(dup2) dups;
- string_t *listener_names;
+ string_t *listener_settings;
int fd = MASTER_LISTEN_FD_FIRST;
- unsigned int i, count, socket_listener_count, ssl_socket_count;
+ unsigned int i, count, socket_listener_count;
/* stdin/stdout is already redirected to /dev/null. Other master fds
should have been opened with fd_close_on_exec() so we don't have to
socket_listener_count = 0;
listeners = array_get(&service->listeners, &count);
t_array_init(&dups, count + 10);
- listener_names = t_str_new(256);
switch (service->type) {
case SERVICE_TYPE_LOG:
break;
}
- /* anvil/log fds have no names */
- for (i = MASTER_LISTEN_FD_FIRST; i < (unsigned int)fd; i++)
- str_append_c(listener_names, '\t');
-
- /* first add non-ssl listeners */
+ /* add listeners */
+ listener_settings = t_str_new(256);
for (i = 0; i < count; i++) {
- if (listeners[i]->fd != -1 &&
- (listeners[i]->type != SERVICE_LISTENER_INET ||
- !listeners[i]->set.inetset.set->ssl)) {
- str_append_tabescaped(listener_names, listeners[i]->name);
- str_append_c(listener_names, '\t');
- dup2_append(&dups, listeners[i]->fd, fd++);
- socket_listener_count++;
- }
- }
- /* then ssl-listeners */
- ssl_socket_count = 0;
- for (i = 0; i < count; i++) {
- if (listeners[i]->fd != -1 &&
- listeners[i]->type == SERVICE_LISTENER_INET &&
- listeners[i]->set.inetset.set->ssl) {
- str_append_tabescaped(listener_names, listeners[i]->name);
- str_append_c(listener_names, '\t');
+ if (listeners[i]->fd != -1) {
+ str_truncate(listener_settings, 0);
+ str_append_tabescaped(listener_settings, listeners[i]->name);
+
+ if (listeners[i]->type == SERVICE_LISTENER_INET) {
+ if (listeners[i]->set.inetset.set->ssl)
+ str_append(listener_settings, "\tssl");
+ }
+
dup2_append(&dups, listeners[i]->fd, fd++);
+
+ env_put(t_strdup_printf("SOCKET%d_SETTINGS=%s",
+ socket_listener_count, str_c(listener_settings)));
socket_listener_count++;
- ssl_socket_count++;
}
}
i_assert(fd == MASTER_LISTEN_FD_FIRST + (int)socket_listener_count);
env_put(t_strdup_printf("SOCKET_COUNT=%d", socket_listener_count));
- env_put(t_strdup_printf("SSL_SOCKET_COUNT=%d", ssl_socket_count));
- env_put(t_strdup_printf("SOCKET_NAMES=%s", str_c(listener_names)));
}
static void