service.c revision 617e13833c798435e2be425b99c27ecaad1b8393
/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "array.h"
#include "aqueue.h"
#include "hash.h"
#include "str.h"
#include "service.h"
#include "service-process.h"
#include "service-monitor.h"
#include <unistd.h>
#include <signal.h>
{
}
static struct service_listener *
enum service_listener_type type,
const struct file_listener_settings *set,
const char **error_r)
{
struct service_listener *l;
l->fd = -1;
return NULL;
return NULL;
return l;
}
static int
{
unsigned int ips_count;
int ret;
/* IPv4 any */
return 0;
}
/* IPv6 any */
return 0;
}
/* Return the first IP if there happens to be multiple. */
if (ret != 0) {
return -1;
}
if (ips_count < 1) {
return -1;
}
if (ips_count > 1) {
address);
return -1;
}
return 0;
}
static struct service_listener *
const struct inet_listener_settings *set,
const char **error_r)
{
struct service_listener *l;
l->type = SERVICE_LISTENER_INET;
l->fd = -1;
return NULL;
*error_r = "Port not given";
return NULL;
}
return NULL;
}
return l;
}
static struct service *
{
struct file_listener_settings *const *unix_listeners;
struct file_listener_settings *const *fifo_listeners;
struct inet_listener_settings *const *inet_listeners;
struct service_listener *l;
const char *const *tmp;
}
if (set->process_limit == 0) {
/* unlimited */
/* use default */
} else {
}
*error_r = "executable not given";
return NULL;
}
/* default gid to user's primary group */
return NULL;
return NULL;
}
error_r) < 0)
return NULL;
return NULL;
}
}
else {
}
return NULL;
}
/* set these later, so if something fails we don't have to worry about
closing them */
else {
unix_count = 0;
}
else {
fifo_count = 0;
}
else {
inet_count = 0;
}
*error_r = "Service must have unix listeners";
return NULL;
}
for (i = 0; i < unix_count; i++) {
unix_listeners[i], error_r);
if (l == NULL)
return NULL;
}
for (i = 0; i < fifo_count; i++) {
fifo_listeners[i], error_r);
if (l == NULL)
return NULL;
}
for (i = 0; i < inet_count; i++) {
error_r);
if (l == NULL)
return NULL;
}
return service;
}
static unsigned int pid_hash(const void *p)
{
return (unsigned int)*pid;
}
{
}
static struct service *
{
unsigned int i, count;
for (i = 0; i < count; i++) {
return services[i];
}
return NULL;
}
struct service_list *
const char *const *child_process_env, const char **error_r)
{
struct service_list *service_list;
struct service_settings *const *service_settings;
const char *error;
unsigned int i, count;
for (i = 0; i < count; i++) {
service_list, &error);
return NULL;
}
case SERVICE_TYPE_LOG:
*error_r = "Multiple log services specified";
return NULL;
}
break;
case SERVICE_TYPE_CONFIG:
*error_r = "Multiple config services specified";
return NULL;
}
break;
default:
break;
}
}
/* resolve service dependencies */
for (i = 0; i < count; i++) {
const char *dest_service =
services[i]->auth_dest_service =
"auth_dest_service doesn't exist: %s",
return NULL;
}
}
}
*error_r = "log service not specified";
return NULL;
}
*error_r = "config process not specified";
return NULL;
}
return service_list;
}
{
struct hash_iterate_context *iter;
continue;
}
}
}
{
struct hash_iterate_context *iter;
/* make sure we log if child processes died unexpectedly */
/* free all child process information */
}