#include "unixd.h"
#include "ap_mpm.h"
#include "apr_thread_proc.h"
#include "apr_strings.h"
#include "apr_queue.h"
#include "apr_global_mutex.h"
#include "apr_support.h"
#include "fcgid_pm.h"
#include "fcgid_pm_main.h"
#include "fcgid_conf.h"
#include "fcgid_proctbl.h"
#include "fcgid_spawn_ctl.h"
#include <unistd.h>
static apr_status_t create_process_manager(server_rec * main_server,
										   apr_pool_t * configpool);

static int g_wakeup_timeout = 3;
static apr_proc_t *g_process_manager = NULL;
static apr_file_t *g_pm_read_pipe = NULL;
static apr_file_t *g_pm_write_pipe = NULL;
static apr_file_t *g_ap_write_pipe = NULL;
static apr_file_t *g_ap_read_pipe = NULL;
static apr_global_mutex_t *g_pipelock = NULL;
char g_pipelock_name[L_tmpnam];

static int volatile g_caughtSigTerm = 0;
static pid_t g_pm_pid;
static void signal_handler(int signo)
{
	/* Sanity check, Make sure I am not the subprocess. A subprocess may
	   get signale after fork() and before execve() */
	if (getpid() != g_pm_pid) {
		exit(0);
		return;
	}

	if ((signo == SIGTERM) || (signo == SIGUSR1) || (signo == SIGHUP)) {
		g_caughtSigTerm = 1;
		/* Tell the world it's time to die */
		proctable_get_globalshare()->must_exit = 1;
	}
}

static apr_status_t init_signal(server_rec * main_server)
{
	struct sigaction sa;

	/* Setup handlers */
	sa.sa_handler = signal_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;

	if (sigaction(SIGTERM, &sa, NULL) < 0) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
					 "mod_fcgid: Can't install SIGTERM handler");
		return APR_EGENERAL;
	}

	/* Httpd restart */
	if (sigaction(SIGHUP, &sa, NULL) < 0) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
					 "mod_fcgid: Can't install SIGHUP handler");
		return APR_EGENERAL;
	}

	/* Httpd graceful restart */
	if (sigaction(SIGUSR1, &sa, NULL) < 0) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
					 "mod_fcgid: Can't install SIGUSR1 handler");
		return APR_EGENERAL;
	}

	/* Ignore SIGPIPE */
	sa.sa_handler = SIG_IGN;
	if (sigaction(SIGPIPE, &sa, NULL) < 0) {
		ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
					 "mod_fcgid: Can't install SIGPIPE handler");
		return APR_EGENERAL;
	}

	return APR_SUCCESS;
}

static void fcgid_maint(int reason, void *data, apr_wait_t status)
{
	apr_proc_t *proc = data;
	int mpm_state;

	switch (reason) {
	case APR_OC_REASON_DEATH:
		apr_proc_other_child_unregister(data);
		if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state) == APR_SUCCESS
			&& mpm_state != AP_MPMQ_STOPPING) {
			ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
						 "mod_fcgid: fcgid process manager died, restarting the server");

			/* HACK: I can't just call create_process_manager() to
			   restart a process manager, because it will use the dirty
			   share memory, I have to kill myself a SIGHUP, to make
			   a clean restart */
			if (kill(getpid(), SIGHUP) < 0) {
				ap_log_error(APLOG_MARK, APLOG_EMERG,
							 apr_get_os_error(), NULL,
							 "mod_fcgid: can' kill myself a signal SIGHUP");
				exit(0);
			}
		}
		break;
	case APR_OC_REASON_RESTART:
		apr_proc_other_child_unregister(data);
		break;
	case APR_OC_REASON_LOST:
		apr_proc_other_child_unregister(data);
		/* It hack here too, a note above */
		if (kill(getpid(), SIGHUP) < 0) {
			ap_log_error(APLOG_MARK, APLOG_EMERG,
						 apr_get_os_error(), NULL,
						 "mod_fcgid: can' kill myself a signal SIGHUP");
			exit(0);
		}
		break;
	case APR_OC_REASON_UNREGISTER:
		/* I don't think it's going to happen */
		kill(proc->pid, SIGHUP);
		break;
	}
}
static int set_group_privs(void)
{
	if (!geteuid()) {
		const char *name;


		/* Get username if passed as a uid */
		if (unixd_config.user_name[0] == '#') {
			struct passwd *ent;

			uid_t uid = atoi(&unixd_config.user_name[1]);

			if ((ent = getpwuid(uid)) == NULL) {
				ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
							 "getpwuid: couldn't determine user name from uid %u, "
							 "you probably need to modify the User directive",
							 (unsigned) uid);
				return -1;
			}
			name = ent->pw_name;
		}

		else
			name = unixd_config.user_name;

#if !defined(OS2) && !defined(TPF)
		/* OS/2 and TPF don't support groups. */

		/*
		 * Set the GID before initgroups(), since on some platforms
		 * setgid() is known to zap the group list.
		 */
		if (setgid(unixd_config.group_id) == -1) {
			ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
						 "setgid: unable to set group id to Group %u",
						 (unsigned) unixd_config.group_id);
			return -1;
		}

		/* Reset `groups' attributes. */
		if (initgroups(name, unixd_config.group_id) == -1) {
			ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
						 "initgroups: unable to set groups for User %s "
						 "and Group %u", name,
						 (unsigned) unixd_config.group_id);
			return -1;
		}
#endif							/* !defined(OS2) && !defined(TPF) */
	}
	return 0;
}


/* Base on unixd_setup_child() */
static int suexec_setup_child(void)
{
	if (set_group_privs()) {
		exit(-1);
	}

	/* Only try to switch if we're running as root */
	if (!geteuid() && (seteuid(unixd_config.user_id) == -1)) {
		ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
					 "setuid: unable to change to uid: %ld",
					 (long) unixd_config.user_id);
		exit(-1);
	}
	return 0;
}

static apr_status_t
create_process_manager(server_rec * main_server, apr_pool_t * configpool)
{
	apr_status_t rv;

	g_process_manager =
		(apr_proc_t *) apr_pcalloc(configpool, sizeof(*g_process_manager));
	rv = apr_proc_fork(g_process_manager, configpool);
	if (rv == APR_INCHILD) {
		/* I am the child */
		g_pm_pid = getpid();
		ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
					 "mod_fcgid: Process manager %d started", getpid());

		if ((rv = init_signal(main_server)) != APR_SUCCESS) {
			ap_log_error(APLOG_MARK, LOG_EMERG, rv, main_server,
						 "mod_fcgid: can't intall signal handler, exit now");
			exit(1);
		}

		/* if running as root, switch to configured user */
		if (unixd_config.suexec_enabled) {
			if (getuid() != 0) {
				ap_log_error(APLOG_MARK, LOG_EMERG, rv, main_server,
							 "mod_fcgid: current user is not root while suexec is enabled, exit now");
				exit(1);
			}
			suexec_setup_child();
		} else
			unixd_setup_child();
		apr_file_pipe_timeout_set(g_pm_read_pipe,
								  apr_time_from_sec(g_wakeup_timeout));
		apr_file_close(g_ap_write_pipe);
		apr_file_close(g_ap_read_pipe);

		/* Initialize spawn controler */
		spawn_control_init(main_server, configpool);

		pm_main(main_server, configpool);

		ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
					 "mod_fcgid: Process manager %d stopped", getpid());
		exit(0);
	} else if (rv != APR_INPARENT) {
		ap_log_error(APLOG_MARK, APLOG_EMERG, errno, main_server,
					 "mod_fcgid: Create process manager error");
		exit(1);
	}

	/* I am the parent
	   I will send the stop signal in procmgr_stop_procmgr() */
	apr_pool_note_subprocess(configpool, g_process_manager,
							 APR_KILL_ONLY_ONCE);
	apr_proc_other_child_register(g_process_manager, fcgid_maint,
								  g_process_manager, NULL, configpool);

	return APR_SUCCESS;
}

apr_status_t
procmgr_child_init(server_rec * main_server, apr_pool_t * configpool)
{
	apr_status_t rv;

	if ((rv = apr_global_mutex_child_init(&g_pipelock,
										  g_pipelock_name,
										  main_server->process->pconf)) !=
		APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
					 "mod_fcgid: apr_global_mutex_child_init error for pipe mutex");
		exit(1);
	}

	return APR_SUCCESS;
}

apr_status_t
procmgr_post_config(server_rec * main_server, apr_pool_t * configpool)
{
	apr_status_t rv;
	apr_finfo_t finfo;
	int error_scan_interval, busy_scan_interval, idle_scan_interval;

	/* Calculate procmgr_peek_cmd wake up interval */
	error_scan_interval = get_error_scan_interval(main_server);
	busy_scan_interval = get_busy_scan_interval(main_server);
	idle_scan_interval = get_idle_scan_interval(main_server);
	g_wakeup_timeout = fcgid_min(error_scan_interval, busy_scan_interval);
	g_wakeup_timeout = fcgid_min(idle_scan_interval, g_wakeup_timeout);
	if (g_wakeup_timeout == 0)
		g_wakeup_timeout = 1;	/* Make it reasonable */

	rv = apr_stat(&finfo, get_socketpath(main_server), APR_FINFO_USER,
				  configpool);
	if (rv != APR_SUCCESS || !(finfo.valid & APR_FINFO_USER)
		|| finfo.user != unixd_config.user_id) {
		/* Make dir for unix domain socket */
		if ((rv = apr_dir_make_recursive(get_socketpath(main_server),
										 APR_UREAD | APR_UWRITE |
										 APR_UEXECUTE,
										 configpool)) != APR_SUCCESS
			|| chown(get_socketpath(main_server), unixd_config.user_id,
					 -1) < 0) {
			ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
						 "mod_fcgid: Can't create unix socket dir");
			exit(1);
		}
	}

	/* Create pipes to communicate between process manager and apache */
	if ((rv = apr_file_pipe_create(&g_pm_read_pipe, &g_ap_write_pipe,
								   configpool)) != APR_SUCCESS
		|| (rv = apr_file_pipe_create(&g_ap_read_pipe, &g_pm_write_pipe,
									  configpool))) {
		ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
					 "mod_fcgid: Can't create pipe between PM and stub");
		return rv;
	}

	/* Create mutex for pipe reading and writing */
	if ((rv =
		 apr_global_mutex_create(&g_pipelock, tmpnam(g_pipelock_name),
								 APR_LOCK_DEFAULT,
								 main_server->process->pconf)) !=
		APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
					 "mod_fcgid: Can't create global pipe mutex");
		exit(1);
	}
	if ((rv = unixd_set_global_mutex_perms(g_pipelock)) != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
					 "mod_fcgid: Can't set global pipe mutex perms");
		exit(1);
	}

	/* Create process manager process */
	return create_process_manager(main_server, configpool);
}

void procmgr_init_spawn_cmd(fcgid_command * command, request_rec * r,
							const char *argv0, dev_t deviceid,
							apr_ino_t inode, apr_size_t share_grp_id)
{
	server_rec *main_server = r->server;
	ap_unix_identity_t *ugid;
	apr_table_t *initenv;
	const apr_array_header_t *initenv_arr;
	const apr_table_entry_t *initenv_entry;
	fcgid_wrapper_conf *wrapperconf;
	int i;

	memset(command, 0, sizeof(*command));

	/* suEXEC check */
	if ((ugid = ap_run_get_suexec_identity(r))) {
		command->uid = ugid->uid;
		command->gid = ugid->gid;
		command->userdir = ugid->userdir;
	} else {
		command->uid = (uid_t) - 1;
		command->gid = (gid_t) - 1;
		command->userdir = 0;
	}

	/* Environment variables */
	initenv = get_default_env_vars(r);
	if (initenv) {
		initenv_arr = apr_table_elts(initenv);
		initenv_entry = (apr_table_entry_t *) initenv_arr->elts;
		if (initenv_arr->nelts > INITENV_CNT)
			ap_log_error(APLOG_MARK, LOG_WARNING, 0, main_server,
						 "mod_fcgid: too much environment variables, Please increase INITENV_CNT in fcgid_pm.h and recompile module mod_fcgid");

		for (i = 0; i < initenv_arr->nelts && i < INITENV_CNT; ++i) {
			if (initenv_entry[i].key == NULL
				|| initenv_entry[i].key[0] == '\0')
				break;
			strncpy(command->initenv_key[i], initenv_entry[i].key,
					INITENV_KEY_LEN);
			command->initenv_key[i][INITENV_KEY_LEN - 1] = '\0';
			strncpy(command->initenv_val[i], initenv_entry[i].val,
					INITENV_VAL_LEN);
			command->initenv_val[i][INITENV_VAL_LEN - 1] = '\0';
		}
	}

	strncpy(command->cgipath, argv0, _POSIX_PATH_MAX);
	command->cgipath[_POSIX_PATH_MAX - 1] = '\0';
	command->deviceid = deviceid;
	command->inode = inode;
	command->share_grp_id = share_grp_id;
	command->virtualhost = r->server->server_hostname;

	/* Update fcgid_command with wrapper info */
	command->wrapperpath[0] = '\0';
	if ((wrapperconf = get_wrapper_info(argv0, r))) {
		strncpy(command->wrapperpath, wrapperconf->args, _POSIX_PATH_MAX);
		command->wrapperpath[_POSIX_PATH_MAX - 1] = '\0';
		command->deviceid = wrapperconf->deviceid;
		command->inode = wrapperconf->inode;
		command->share_grp_id = wrapperconf->share_group_id;
	}
}

apr_status_t procmgr_post_spawn_cmd(fcgid_command * command,
									request_rec * r)
{
	apr_status_t rv;
	char notifybyte;
	apr_size_t nbytes = sizeof(*command);
	server_rec *main_server = r->server;

	/* Sanity check first */
	if (g_caughtSigTerm || !g_ap_write_pipe)
		return APR_SUCCESS;

	/* Get the global mutex before posting the request */
	if ((rv = apr_global_mutex_lock(g_pipelock)) != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
					 "mod_fcgid: can't get pipe mutex");
		exit(0);
	}

	if ((rv =
		 apr_file_write_full(g_ap_write_pipe, command, nbytes,
							 NULL)) != APR_SUCCESS) {
		/* Just print some error log and fall through */
		ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
					 "mod_fcgid: can't write spawn command");
	} else {
		/* Wait the finish notify while send the request successfully */
		nbytes = sizeof(notifybyte);
		if ((rv =
			 apr_file_read(g_ap_read_pipe, &notifybyte,
						   &nbytes)) != APR_SUCCESS) {
			ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
						 "mod_fcgid: can't get notify from process manager");
		}
	}

	/* Release the lock */
	if ((rv = apr_global_mutex_unlock(g_pipelock)) != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
					 "mod_fcgid: can't release pipe mutex");
		exit(0);
	}

	return APR_SUCCESS;
}

apr_status_t procmgr_finish_notify(server_rec * main_server)
{
	apr_status_t rv;
	char notifybyte = 'p';
	apr_size_t nbytes = sizeof(notifybyte);

	if ((rv =
		 apr_file_write(g_pm_write_pipe, &notifybyte,
						&nbytes)) != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
					 "mod_fcgid: can't send notify from process manager");
	}

	return rv;
}

#define FOR_READ 1
apr_status_t procmgr_peek_cmd(fcgid_command * command,
							  server_rec * main_server)
{
	apr_status_t rv;

	/* Sanity check */
	if (!g_pm_read_pipe)
		return APR_EPIPE;

	/* Wait for next command */
	rv = apr_wait_for_io_or_timeout(g_pm_read_pipe, NULL, FOR_READ);

	/* Log any unexpect result */
	if (rv != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(rv)) {
		ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
					 "mod_fcgid: wait io error while getting message from pipe");
		return rv;
	}

	/* Timeout */
	if (rv != APR_SUCCESS)
		return rv;

	return apr_file_read_full(g_pm_read_pipe, command, sizeof(*command),
							  NULL);
}

int procmgr_must_exit()
{
	return g_caughtSigTerm;
}

apr_status_t procmgr_stop_procmgr(void *server)
{
	return APR_SUCCESS;
}
