/**
 * angel process for lighttpd 
 *
 * the purpose is the run as root all the time and handle:
 * - restart on crash
 * - spawn on HUP to allow graceful restart
 * - ...
 *
 * it has to stay safe and small to be trustable
 */

#include <sys/wait.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>

#define BINPATH SBIN_DIR"/lighttpd"

static siginfo_t last_sigterm_info;
static siginfo_t last_sighup_info;

static volatile sig_atomic_t start_process    = 1;
static volatile sig_atomic_t graceful_restart = 0;
static volatile pid_t pid = -1;

static void sigaction_handler(int sig, siginfo_t *si, void *context) {
	int exitcode;

	switch (sig) {
	case SIGINT: 
	case SIGTERM:
		memcpy(&last_sigterm_info, si, sizeof(*si));

		/** forward the sig to the child */
		kill(pid, sig);
		break;
	case SIGHUP: /** do a graceful restart */
		memcpy(&last_sighup_info, si, sizeof(*si));

		/** do a graceful shutdown on the main process and start a new child */
		kill(pid, SIGINT);

		usleep(5 * 1000); /** wait 5 microsec */
		
		start_process = 1;
		break;
	case SIGCHLD:
		/** a child died, de-combie it */
		wait(&exitcode);
		break;
	}
}

int main(int argc, char **argv) {
	int is_shutdown = 0;
	struct sigaction act;

	/**
	 * we are running as root BEWARE
	 */

	memset(&act, 0, sizeof(act));
	act.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &act, NULL);
	sigaction(SIGUSR1, &act, NULL);

	act.sa_sigaction = sigaction_handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO;

	sigaction(SIGINT,  &act, NULL);
	sigaction(SIGTERM, &act, NULL);
	sigaction(SIGHUP,  &act, NULL);
	sigaction(SIGALRM, &act, NULL);
	sigaction(SIGCHLD, &act, NULL);

	/* check that the compiled in path has the right user,
	 *
	 * BEWARE: there is a race between the check here and the exec later
	 */

	while (!is_shutdown) {
		int exitcode = 0;

		if (start_process) {
			pid = fork();

			if (0 == pid) {
				/* i'm the child */

				argv[0] = BINPATH;

				execvp(BINPATH, argv);

				exit(1);
			} else if (-1 == pid) {
				/** error */

				return -1;
			}

			/* I'm the angel */
			start_process = 0;
		}
	       
		if ((pid_t)-1 == waitpid(pid, &exitcode, 0)) {
			switch (errno) {
			case EINTR:
				/* someone sent a signal ... 
				 * do we have to shutdown or restart the process */
				break;
			case ECHILD:
				/** 
				 * make sure we are not in a race between the signal handler
				 * and the process restart */
				if (!start_process) is_shutdown = 1;
				break;
			default:
				break;
			}
		} else {
			/** process went away */

			if (WIFEXITED(exitcode)) {
				/** normal exit */

				is_shutdown = 1;

				fprintf(stderr, "%s.%d: child (pid=%d) exited normally with exitcode: %d\n", 
						__FILE__, __LINE__,
						pid,
						WEXITSTATUS(exitcode));

			} else if (WIFSIGNALED(exitcode)) {
				/** got a signal */

				fprintf(stderr, "%s.%d: child (pid=%d) exited unexpectedly with signal %d, restarting\n", 
						__FILE__, __LINE__,
						pid,
						WTERMSIG(exitcode));

				start_process = 1;
			}
		}
	}

	return 0;
}

