aboutsummaryrefslogtreecommitdiffstats
path: root/doc/examples/daemon-dependencies/init.c
blob: b7182c63a15d80bc93eb4c130dae42b4a6d476d2 (plain) (blame)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <bus.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

#define t(stmt)  if (stmt) goto fail


static char msg[BUS_MEMORY_SIZE];
static int argc;
static char **argv;
static char arg[4098];


static void
start_daemons()
{
	int i;
	for (i = 1; i < argc; i++)
		if (fork() == 0)
			execl("./start-daemon", "./start-daemon", argv[i], NULL); 
}


static int
callback(const char *message, void *user_data)
{
	pid_t pid;
	char *arg2;
	char *arg3;
	if (!message) {
		pid = fork();
		t(pid == -1);
		if (pid == 0) {
			if (fork() == 0) {
				start_daemons();
			}
			exit(0);
		} else {
			(void) waitpid(pid, NULL, 0); /* Let's pretend everything will go swimmingly. */
		}
		return 1;
	}

	strncpy(msg, message, BUS_MEMORY_SIZE - 1);
	msg[BUS_MEMORY_SIZE - 1] = 0;

	pid = fork();
	t(pid == -1);

	if (pid == 0) {
		if (fork() == 0) {
			arg2 = strchr(msg, ' ');
			if (arg2 == NULL)
				exit(0);
			arg3 = strchr(++arg2, ' ');
			if (arg3 == NULL)
				exit(0);
			*arg3++ = 0;
			if (!strcmp(arg2, "require")) {
				execl("./start-daemon", "./start-daemon", arg3, NULL);
			} else if (!strcmp(arg2, "awaiting-started")) {
				execl("./test-daemon", "./test-daemon", arg3, "started", NULL);
			} else if (!strcmp(arg2, "awaiting-ready") || !strcmp(arg2, "awaiting")) {
				execl("./test-daemon", "./test-daemon", arg3, "ready", NULL);
			} else if (!strcmp(arg2, "started")) {
				sprintf(arg,
					"grep '^%s\\$' < \"${XDG_RUNTIME_DIR}/started-daemons\" >/dev/null || "
					"echo %s >> \"${XDG_RUNTIME_DIR}/started-daemons\"",
					arg3, arg3);
				execlp("sh", "sh", "-c", arg, NULL);
			} else if (!strcmp(arg2, "ready")) {
				sprintf(arg,
					"grep '^%s\\$' < \"${XDG_RUNTIME_DIR}/ready-daemons\" >/dev/null || "
					"echo %s >> \"${XDG_RUNTIME_DIR}/ready-daemons\"",
					arg3, arg3);
				execlp("sh", "sh", "-c", arg, NULL);
			}
		}
		exit(0);
	} else {
		(void) waitpid(pid, NULL, 0); /* Let's pretend everything will go swimmingly. */
	}

	return 1;
	(void) user_data;

fail:
	perror("init");
	return -1;
}


int
main(int argc_, char *argv_[])
{
	char *bus_address = NULL;
	bus_t bus;
	argv = argv_;
	argc = argc_;
	if (argc < 2) {
		fprintf(stderr, "USAGE: %s daemon...\n", *argv);
		return 1;
	}
	t(setenv("XDG_RUNTIME_DIR", "./run", 1));  /* Real init systems with not have the period. */
	system("mkdir -p -- \"${XDG_RUNTIME_DIR}\"");
	system("truncate -s 0 -- \"${XDG_RUNTIME_DIR}/started-daemons\"");
	system("truncate -s 0 -- \"${XDG_RUNTIME_DIR}/ready-daemons\"");
	t(bus_create(NULL, 1, &bus_address));
	fprintf(stderr, "\033[00;01;31mexport BUS_INIT=%s\033[00m\n", bus_address);
	fprintf(stderr, "\033[00;31mexport XDG_RUNTIME_DIR=./run\033[00m\n");
	t(setenv("BUS_INIT", bus_address, 1));
	t(bus_open(&bus, bus_address, BUS_RDONLY));
	t(bus_read(&bus, callback, NULL));
	bus_close(&bus);
	free(bus_address);
	return 0;

fail:
	perror("init");
	bus_close(&bus);
	free(bus_address);
	return 1;
}