summaryrefslogtreecommitdiffstats
path: root/src/ipc/main.c
blob: ebd4b228b0b79ffdab946f53b0dc1f2f4d4919d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "restrict-access.h"
#include "master-service.h"
#include "master-service-settings.h"
#include "ipc-group.h"
#include "ipc-connection.h"
#include "client.h"

static bool ipc_socket_is_client(const char *name)
{
	size_t len;

	if (strcmp(name, "ipc") == 0)
		return TRUE;

	len = strlen(name);
	if (len > 7 && strcmp(name + len - 7, "-client") == 0)
		return TRUE;
	return FALSE;
}

static void client_connected(struct master_service_connection *conn)
{
	master_service_client_connection_accept(conn);

	if (ipc_socket_is_client(conn->name))
		(void)client_create(conn->fd);
	else
		(void)ipc_connection_create(conn->listen_fd, conn->fd);
}

static void ipc_die(void)
{
	clients_destroy_all();
	ipc_groups_disconnect_all();
}

int main(int argc, char *argv[])
{
	const enum master_service_flags service_flags =
		/* This process likely won't need to send any stats. It's also
		   problematic because it's chrooted to empty directory, so it
		   can't reconnect to stats if it gets disconnected. So at
		   least for now disable connecting to stats entirely. */
		MASTER_SERVICE_FLAG_DONT_SEND_STATS |
		MASTER_SERVICE_FLAG_UPDATE_PROCTITLE;
	const char *error;

	master_service = master_service_init("ipc", service_flags,
					     &argc, &argv, "");
	if (master_getopt(master_service) > 0)
		return FATAL_DEFAULT;
	if (master_service_settings_read_simple(master_service,
						NULL, &error) < 0)
		i_fatal("Error reading configuration: %s", error);
	master_service_init_log(master_service);
	master_service_set_die_with_master(master_service, TRUE);
	master_service_set_die_callback(master_service, ipc_die);

	restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
	restrict_access_allow_coredumps(TRUE);
	ipc_groups_init();
	master_service_init_finish(master_service);

	master_service_run(master_service, client_connected);

	clients_destroy_all();
	ipc_groups_deinit();
	master_service_deinit(&master_service);
        return 0;
}