<commit_before>/*
 * Copyright (c) 2013 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/epoll.h>
#include <sys/prctl.h>
#include <sys/wait.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <openssl/err.h>
#include <openssl/ssl.h>

#include <pwd.h>
#include <errno.h>
#include <grp.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <syslog.h>
#include <unistd.h>
#include <time.h>
#include <regex.h>
#include <zlib.h>
#include <unistd.h>

#include "spdy.h"
#include "kore.h"
#include "http.h"

#define EPOLL_EVENTS	500

static int	efd = -1;
static SSL_CTX	*ssl_ctx = NULL;

volatile sig_atomic_t			sig_recv;
static struct listener			server;
static TAILQ_HEAD(, connection)		disconnected;
static TAILQ_HEAD(, connection)		worker_clients;
static TAILQ_HEAD(, kore_worker)	kore_workers;
static struct passwd			*pw = NULL;
static u_int16_t			workerid = 0;
static u_int16_t			cpu_count = 1;

pid_t			mypid = -1;
int			kore_debug = 0;
int			server_port = 0;
u_int8_t		worker_count = 0;
char			*server_ip = NULL;
char			*runas_user = NULL;
char			*chroot_path = NULL;
char			*kore_certkey = NULL;
char			*kore_certfile = NULL;
char			*kore_pidfile = KORE_PIDFILE_DEFAULT;

static void	usage(void);
static void	kore_signal(int);
static void	kore_worker_wait(int);
static void	kore_worker_init(void);
static void	kore_write_mypid(void);
static int	kore_socket_nonblock(int);
static int	kore_server_sslstart(void);
static void	kore_event(int, int, void *);
static void	kore_worker_spawn(u_int16_t);
static int	kore_server_accept(struct listener *);
static void	kore_worker_entry(struct kore_worker *);
static void	kore_worker_setcpu(struct kore_worker *);
static int	kore_connection_handle(struct connection *, int);
static void	kore_server_final_disconnect(struct connection *);
static int	kore_server_bind(struct listener *, const char *, int);
static int	kore_ssl_npn_cb(SSL *, const u_char **, unsigned int *, void *);

static void
usage(void)
{
	fprintf(stderr, "Usage: kore [-c config] [-d]\n");
	exit(1);
}

int
main(int argc, char *argv[])
{
	int			ch;
	struct kore_worker	*kw, *next;
	char			*config_file;

	kore_log_init();
	mypid = getpid();

	if (getuid() != 0)
		fatal("kore must be started as root");

	kore_debug = 0;
	config_file = NULL;
	while ((ch = getopt(argc, argv, "c:d")) != -1) {
		switch (ch) {
		case 'c':
			config_file = optarg;
			break;
		case 'd':
			kore_debug = 1;
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (config_file == NULL)
		fatal("please specify a configuration file to use (-c)");

	kore_parse_config(config_file);
	if (!kore_module_loaded())
		fatal("no site module was loaded");

	if (server_ip == NULL || server_port == 0)
		fatal("missing a correct bind directive in configuration");
	if (chroot_path == NULL)
		fatal("missing a chroot path");
	if (runas_user == NULL)
		fatal("missing a username to run as");
	if ((pw = getpwnam(runas_user)) == NULL)
		fatal("user '%s' does not exist", runas_user);
	if (kore_certfile == NULL || kore_certkey == NULL)
		fatal("missing certificate information");

	if ((cpu_count = sysconf(_SC_NPROCESSORS_ONLN)) == -1) {
		kore_debug("could not get number of cpu's falling back to 1");
		cpu_count = 1;
	}

	if (!kore_server_sslstart())
		fatal("cannot initiate SSL");
	if (!kore_server_bind(&server, server_ip, server_port))
		fatal("cannot bind to %s:%d", server_ip, server_port);
	if (daemon(1, 1) == -1)
		fatal("cannot daemon(): %s", errno_s);

	mypid = getpid();
	kore_write_mypid();

	kore_log(LOG_NOTICE, "kore is starting up");
	kore_worker_init();

	if (prctl(PR_SET_NAME, "kore [main]"))
		kore_debug("cannot set process title");

	sig_recv = 0;
	signal(SIGHUP, kore_signal);
	signal(SIGQUIT, kore_signal);

	free(server_ip);
	free(runas_user);
	free(kore_certkey);
	free(kore_certfile);

	for (;;) {
		if (sig_recv != 0) {
			if (sig_recv == SIGHUP) {
				TAILQ_FOREACH(kw, &kore_workers, list) {
					if (kill(kw->pid, SIGHUP) == -1) {
						kore_debug("kill(%d, HUP): %s",
						    kw->pid, errno_s);
					}
				}
			} else if (sig_recv == SIGQUIT) {
				break;
			}
			sig_recv = 0;
		}

		kore_worker_wait(0);<commit_msg>Reload the module in the main process as well when SIGHUP is received. Otherwise new worker processes will not receive the updated module.<commit_after>/*
 * Copyright (c) 2013 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/epoll.h>
#include <sys/prctl.h>
#include <sys/wait.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <openssl/err.h>
#include <openssl/ssl.h>

#include <pwd.h>
#include <errno.h>
#include <grp.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <syslog.h>
#include <unistd.h>
#include <time.h>
#include <regex.h>
#include <zlib.h>
#include <unistd.h>

#include "spdy.h"
#include "kore.h"
#include "http.h"

#define EPOLL_EVENTS	500

static int	efd = -1;
static SSL_CTX	*ssl_ctx = NULL;

volatile sig_atomic_t			sig_recv;
static struct listener			server;
static TAILQ_HEAD(, connection)		disconnected;
static TAILQ_HEAD(, connection)		worker_clients;
static TAILQ_HEAD(, kore_worker)	kore_workers;
static struct passwd			*pw = NULL;
static u_int16_t			workerid = 0;
static u_int16_t			cpu_count = 1;

pid_t			mypid = -1;
int			kore_debug = 0;
int			server_port = 0;
u_int8_t		worker_count = 0;
char			*server_ip = NULL;
char			*runas_user = NULL;
char			*chroot_path = NULL;
char			*kore_certkey = NULL;
char			*kore_certfile = NULL;
char			*kore_pidfile = KORE_PIDFILE_DEFAULT;

static void	usage(void);
static void	kore_signal(int);
static void	kore_worker_wait(int);
static void	kore_worker_init(void);
static void	kore_write_mypid(void);
static int	kore_socket_nonblock(int);
static int	kore_server_sslstart(void);
static void	kore_event(int, int, void *);
static void	kore_worker_spawn(u_int16_t);
static int	kore_server_accept(struct listener *);
static void	kore_worker_entry(struct kore_worker *);
static void	kore_worker_setcpu(struct kore_worker *);
static int	kore_connection_handle(struct connection *, int);
static void	kore_server_final_disconnect(struct connection *);
static int	kore_server_bind(struct listener *, const char *, int);
static int	kore_ssl_npn_cb(SSL *, const u_char **, unsigned int *, void *);

static void
usage(void)
{
	fprintf(stderr, "Usage: kore [-c config] [-d]\n");
	exit(1);
}

int
main(int argc, char *argv[])
{
	int			ch;
	struct kore_worker	*kw, *next;
	char			*config_file;

	kore_log_init();
	mypid = getpid();

	if (getuid() != 0)
		fatal("kore must be started as root");

	kore_debug = 0;
	config_file = NULL;
	while ((ch = getopt(argc, argv, "c:d")) != -1) {
		switch (ch) {
		case 'c':
			config_file = optarg;
			break;
		case 'd':
			kore_debug = 1;
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (config_file == NULL)
		fatal("please specify a configuration file to use (-c)");

	kore_parse_config(config_file);
	if (!kore_module_loaded())
		fatal("no site module was loaded");

	if (server_ip == NULL || server_port == 0)
		fatal("missing a correct bind directive in configuration");
	if (chroot_path == NULL)
		fatal("missing a chroot path");
	if (runas_user == NULL)
		fatal("missing a username to run as");
	if ((pw = getpwnam(runas_user)) == NULL)
		fatal("user '%s' does not exist", runas_user);
	if (kore_certfile == NULL || kore_certkey == NULL)
		fatal("missing certificate information");

	if ((cpu_count = sysconf(_SC_NPROCESSORS_ONLN)) == -1) {
		kore_debug("could not get number of cpu's falling back to 1");
		cpu_count = 1;
	}

	if (!kore_server_sslstart())
		fatal("cannot initiate SSL");
	if (!kore_server_bind(&server, server_ip, server_port))
		fatal("cannot bind to %s:%d", server_ip, server_port);
	if (daemon(1, 1) == -1)
		fatal("cannot daemon(): %s", errno_s);

	mypid = getpid();
	kore_write_mypid();

	kore_log(LOG_NOTICE, "kore is starting up");
	kore_worker_init();

	if (prctl(PR_SET_NAME, "kore [main]"))
		kore_debug("cannot set process title");

	sig_recv = 0;
	signal(SIGHUP, kore_signal);
	signal(SIGQUIT, kore_signal);

	free(server_ip);
	free(runas_user);
	free(kore_certkey);
	free(kore_certfile);

	for (;;) {
		if (sig_recv != 0) {
			if (sig_recv == SIGHUP) {
				kore_module_reload();
				TAILQ_FOREACH(kw, &kore_workers, list) {
					if (kill(kw->pid, SIGHUP) == -1) {
						kore_debug("kill(%d, HUP): %s",
						    kw->pid, errno_s);
					}
				}
			} else if (sig_recv == SIGQUIT) {
				break;
			}
			sig_recv = 0;
		}

		kore_worker_wait(0);
{'fraction_non_alphanumeric': 0.12996777658431793, 'fraction_numerical': 0.0074211502782931356, 'mean_word_length': 4.5302375809935205, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2579571', 'n_tokens_mistral': 4147, 'n_tokens_neox': 3783, 'n_words': 1090}