master.c revision 61e87c7e1e53a1fdd3680c7b1addd187282e1327
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
#include "hash.h"
#include "ioloop.h"
#include "network.h"
#include "fdpass.h"
#include "istream.h"
#include "env-util.h"
#include "write-full.h"
#include "master.h"
#include "client-common.h"
#include <unistd.h>
static int master_fd;
static struct hash_table *master_requests;
static unsigned int master_tag_counter;
static unsigned int master_pos;
static char master_buf[sizeof(struct master_login_reply)];
{
/* this means we have to start listening again.
we've reached maximum number of login processes. */
return;
}
client->master_tag = 0;
/* NOTE: client may be destroyed now */
}
{
struct master_login_request req;
}
{
client->master_tag = 0;
}
{
struct master_login_request req;
return;
/* sending -1 as fd does the notification */
i_fatal("fd_send(-1) failed: %m");
}
void master_close(void)
{
return;
i_fatal("close(master) failed: %m");
master_fd = -1;
closing_down = TRUE;
main_unref();
/* may call this function again through main_unref() */
}
static void master_exec(int fd)
{
switch (fork()) {
case -1:
i_fatal("fork() failed: %m");
case 0:
if (setsid() < 0)
i_fatal("setsid() failed: %m");
env_put("DOVECOT_INETD=1");
SBINDIR"/dovecot");
default:
}
}
static void master_read_env(int fd)
{
const char *line;
env_clean();
/* read environment variable lines until empty line comes */
do {
switch (i_stream_read(input)) {
case -1:
i_fatal("EOF while reading environment from master");
case -2:
i_fatal("Too large environment line from master");
}
*line != '\0')
}
int master_connect(const char *group_name)
{
int i, fd = -1;
if (fd != -1)
break;
if (errno == ECONNREFUSED) {
i_fatal("Can't connect to master UNIX socket %s: %m",
path);
}
/* need to create it */
if (fd != -1) {
fd = -1;
} else if (errno != EADDRINUSE) {
}
}
if (fd == -1)
if (group_name[0] == '\0')
i_fatal("No login group name set");
/* group_name length is now guaranteed to be in range of 1..255 so we
can send <length byte><name> */
i_fatal("write_full(master_fd) failed: %m");
return fd;
}
{
int ret;
sizeof(master_buf) - master_pos);
if (ret < 0) {
/* master died, kill all clients logging in */
master_close();
return;
}
master_pos += ret;
if (master_pos < sizeof(master_buf))
return;
/* reply is now read */
master_pos = 0;
}
void master_init(int fd)
{
main_ref();
master_pos = 0;
}
void master_deinit(void)
{
}