/* Busyboxed by Denis Vlasenko <vda.linux@googlemail.com> */
/* TODO: depends on runit_lib.c - review and reduce/eliminate */

#include <sys/poll.h>
#include <sys/file.h>
#include "busybox.h"
#include "runit_lib.h"

#define MAXSERVICES 1000

static char *svdir;
static unsigned long dev;
static unsigned long ino;
static struct service {
	unsigned long dev;
	unsigned long ino;
	int pid;
	int isgone;
} *sv;
static int svnum;
static int check = 1;
static char *rplog;
static int rploglen;
static int logpipe[2];
static iopause_fd io[1];
static struct taia stamplog;
static int exitsoon;
static int pgrp;

#define usage() bb_show_usage()
static void fatal2_cannot(char *m1, char *m2)
{
	bb_perror_msg_and_die("%s: fatal: cannot %s%s", svdir, m1, m2);
	/* was exiting 100 */
}
static void warn3x(char *m1, char *m2, char *m3)
{
	bb_error_msg("%s: warning: %s%s%s", svdir, m1, m2, m3);
}
static void warn2_cannot(char *m1, char *m2)
{
	warn3x("cannot ", m1, m2);
}
static void warnx(char *m1)
{
	warn3x(m1, "", "");
}

static void s_term(int sig_no)
{
	exitsoon = 1;
}
static void s_hangup(int sig_no)
{
	exitsoon = 2;
}

static void runsv(int no, char *name)
{
	int pid = fork();

	if (pid == -1) {
		warn2_cannot("fork for ", name);
		return;
	}
	if (pid == 0) {
		/* child */
		char *prog[3];

		prog[0] = "runsv";
		prog[1] = name;
		prog[2] = 0;
		sig_uncatch(sig_hangup);
		sig_uncatch(sig_term);
		if (pgrp) setsid();
		execvp(prog[0], prog);
		//pathexec_run(*prog, prog, (char* const*)environ);
		fatal2_cannot("start runsv ", name);
	}
	sv[no].pid = pid;
}

static void runsvdir(void)
{
	DIR *dir;
	direntry *d;
	int i;
	struct stat s;

	dir = opendir(".");
	if (!dir) {
		warn2_cannot("open directory ", svdir);
		return;
	}
	for (i = 0; i < svnum; i++)
		sv[i].isgone = 1;
	errno = 0;
	while ((d = readdir(dir))) {
		if (d->d_name[0] == '.') continue;
		if (stat(d->d_name, &s) == -1) {
			warn2_cannot("stat ", d->d_name);
			errno = 0;
			continue;
		}
		if (!S_ISDIR(s.st_mode)) continue;
		for (i = 0; i < svnum; i++) {
			if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev)) {
				sv[i].isgone = 0;
				if (!sv[i].pid)
					runsv(i, d->d_name);
				break;
			}
		}
		if (i == svnum) {
			/* new service */
			struct service *svnew = realloc(sv, (i+1) * sizeof(*sv));
			if (!svnew) {
				warn3x("cannot start runsv ", d->d_name,
						" too many services");
				continue;
			}
			sv = svnew;
			svnum++;
			memset(&sv[i], 0, sizeof(sv[i]));
			sv[i].ino = s.st_ino;
			sv[i].dev = s.st_dev;
			//sv[i].pid = 0;
			//sv[i].isgone = 0;
			runsv(i, d->d_name);
			check = 1;
		}
	}
	if (errno) {
		warn2_cannot("read directory ", svdir);
		closedir(dir);
		check = 1;
		return;
	}
	closedir(dir);

	/* SIGTERM removed runsv's */
	for (i = 0; i < svnum; i++) {
		if (!sv[i].isgone)
			continue;
		if (sv[i].pid)
			kill(sv[i].pid, SIGTERM);
		sv[i] = sv[--svnum];
		check = 1;
	}
}

static int setup_log(void)
{
	rploglen = strlen(rplog);
	if (rploglen < 7) {
		warnx("log must have at least seven characters");
		return 0;
	}
	if (pipe(logpipe) == -1) {
		warnx("cannot create pipe for log");
		return -1;
	}
	coe(logpipe[1]);
	coe(logpipe[0]);
	ndelay_on(logpipe[0]);
	ndelay_on(logpipe[1]);
	if (fd_copy(2, logpipe[1]) == -1) {
		warnx("cannot set filedescriptor for log");
		return -1;
	}
	io[0].fd = logpipe[0];
	io[0].events = IOPAUSE_READ;
	taia_now(&stamplog);
	return 1;
}

int runsvdir_main(int argc, char **argv)
{
	struct stat s;
	time_t mtime = 0;
	int wstat;
	int curdir;
	int pid;
	struct taia deadline;
	struct taia now;
	struct taia stampcheck;
	char ch;
	int i;

	argv++;
	if (!argv || !*argv) usage();
	if (**argv == '-') {
		switch (*(*argv + 1)) {
		case 'P': pgrp = 1;
		case '-': ++argv;
		}
		if (!argv || !*argv) usage();
	}

	sig_catch(sig_term, s_term);
	sig_catch(sig_hangup, s_hangup);
	svdir = *argv++;
	if (argv && *argv) {
		rplog = *argv;
		if (setup_log() != 1) {
			rplog = 0;
			warnx("log service disabled");
		}
	}
	curdir = open_read(".");
	if (curdir == -1)
		fatal2_cannot("open current directory", "");
	coe(curdir);

	taia_now(&stampcheck);

	for (;;) {
		/* collect children */
		for (;;) {
			pid = wait_nohang(&wstat);
			if (pid <= 0) break;
			for (i = 0; i < svnum; i++) {
				if (pid == sv[i].pid) {
					/* runsv has gone */
					sv[i].pid = 0;
					check = 1;
					break;
				}
			}
		}

		taia_now(&now);
		if (now.sec.x < (stampcheck.sec.x - 3)) {
			/* time warp */
			warnx("time warp: resetting time stamp");
			taia_now(&stampcheck);
			taia_now(&now);
			if (rplog) taia_now(&stamplog);
		}
		if (taia_less(&now, &stampcheck) == 0) {
			/* wait at least a second */
			taia_uint(&deadline, 1);
			taia_add(&stampcheck, &now, &deadline);

			if (stat(svdir, &s) != -1) {
				if (check || s.st_mtime != mtime
				 || s.st_ino != ino || s.st_dev != dev
				) {
					/* svdir modified */
					if (chdir(svdir) != -1) {
						mtime = s.st_mtime;
						dev = s.st_dev;
						ino = s.st_ino;
						check = 0;
						if (now.sec.x <= (4611686018427387914ULL + (uint64_t)mtime))
							sleep(1);
						runsvdir();
						while (fchdir(curdir) == -1) {
							warn2_cannot("change directory, pausing", "");
							sleep(5);
						}
					} else
						warn2_cannot("change directory to ", svdir);
				}
			} else
				warn2_cannot("stat ", svdir);
		}

		if (rplog) {
			if (taia_less(&now, &stamplog) == 0) {
				write(logpipe[1], ".", 1);
				taia_uint(&deadline, 900);
				taia_add(&stamplog, &now, &deadline);
			}
		}
		taia_uint(&deadline, check ? 1 : 5);
		taia_add(&deadline, &now, &deadline);

		sig_block(sig_child);
		if (rplog)
			iopause(io, 1, &deadline, &now);
		else
			iopause(0, 0, &deadline, &now);
		sig_unblock(sig_child);

		if (rplog && (io[0].revents | IOPAUSE_READ))
			while (read(logpipe[0], &ch, 1) > 0)
				if (ch) {
					for (i = 6; i < rploglen; i++)
						rplog[i-1] = rplog[i];
					rplog[rploglen-1] = ch;
				}

		switch (exitsoon) {
		case 1:
			_exit(0);
		case 2:
			for (i = 0; i < svnum; i++)
				if (sv[i].pid)
					kill(sv[i].pid, SIGTERM);
			_exit(111);
		}
	}
	/* not reached */
	return 0;
}
