2016-03-19 15:14:35 +00:00
|
|
|
#include "first.h"
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
#include "server.h"
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "keyvalue.h"
|
|
|
|
#include "response.h"
|
|
|
|
#include "request.h"
|
|
|
|
#include "chunk.h"
|
|
|
|
#include "http_chunk.h"
|
|
|
|
#include "fdevent.h"
|
|
|
|
#include "connections.h"
|
2005-08-08 08:22:06 +00:00
|
|
|
#include "stat_cache.h"
|
2005-02-20 14:27:00 +00:00
|
|
|
#include "plugin.h"
|
|
|
|
#include "joblist.h"
|
2006-02-03 17:22:43 +00:00
|
|
|
#include "network_backends.h"
|
2009-04-10 17:35:19 +00:00
|
|
|
#include "version.h"
|
2005-02-20 14:27:00 +00:00
|
|
|
|
2009-10-11 14:31:42 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <locale.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
#ifdef HAVE_GETOPT_H
|
2009-10-11 14:31:42 +00:00
|
|
|
# include <getopt.h>
|
2005-02-20 14:27:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_VALGRIND_VALGRIND_H
|
2009-10-11 14:31:42 +00:00
|
|
|
# include <valgrind/valgrind.h>
|
2005-02-20 14:27:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_WAIT_H
|
2009-10-11 14:31:42 +00:00
|
|
|
# include <sys/wait.h>
|
2005-02-20 14:27:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_PWD_H
|
2009-10-11 14:31:42 +00:00
|
|
|
# include <grp.h>
|
|
|
|
# include <pwd.h>
|
2005-02-20 14:27:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_RESOURCE_H
|
2009-10-11 14:31:42 +00:00
|
|
|
# include <sys/resource.h>
|
2005-02-20 14:27:00 +00:00
|
|
|
#endif
|
|
|
|
|
2005-12-15 14:30:46 +00:00
|
|
|
#ifdef HAVE_SYS_PRCTL_H
|
2009-10-11 14:31:42 +00:00
|
|
|
# include <sys/prctl.h>
|
2005-12-15 14:30:46 +00:00
|
|
|
#endif
|
|
|
|
|
2006-10-04 13:31:49 +00:00
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
# include <openssl/err.h>
|
|
|
|
#endif
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
#ifndef __sgi
|
|
|
|
/* IRIX doesn't like the alarm based time() optimization */
|
|
|
|
/* #define USE_ALARM */
|
|
|
|
#endif
|
|
|
|
|
2009-04-09 16:51:52 +00:00
|
|
|
#ifdef HAVE_GETUID
|
|
|
|
# ifndef HAVE_ISSETUGID
|
|
|
|
|
2012-08-31 14:11:41 +00:00
|
|
|
static int l_issetugid(void) {
|
2009-04-09 16:51:52 +00:00
|
|
|
return (geteuid() != getuid() || getegid() != getgid());
|
|
|
|
}
|
|
|
|
|
|
|
|
# define issetugid l_issetugid
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2005-08-08 09:48:38 +00:00
|
|
|
static volatile sig_atomic_t srv_shutdown = 0;
|
2005-10-10 12:03:09 +00:00
|
|
|
static volatile sig_atomic_t graceful_shutdown = 0;
|
2005-08-08 09:48:38 +00:00
|
|
|
static volatile sig_atomic_t handle_sig_alarm = 1;
|
|
|
|
static volatile sig_atomic_t handle_sig_hup = 0;
|
2007-09-05 10:39:56 +00:00
|
|
|
static volatile sig_atomic_t forwarded_sig_hup = 0;
|
2005-02-20 14:27:00 +00:00
|
|
|
|
|
|
|
#if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
|
2007-08-21 17:40:03 +00:00
|
|
|
static volatile siginfo_t last_sigterm_info;
|
|
|
|
static volatile siginfo_t last_sighup_info;
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
static void sigaction_handler(int sig, siginfo_t *si, void *context) {
|
2009-03-07 13:58:25 +00:00
|
|
|
static siginfo_t empty_siginfo;
|
2005-02-20 14:27:00 +00:00
|
|
|
UNUSED(context);
|
|
|
|
|
2009-03-07 13:58:25 +00:00
|
|
|
if (!si) si = &empty_siginfo;
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
switch (sig) {
|
2007-08-21 17:40:03 +00:00
|
|
|
case SIGTERM:
|
|
|
|
srv_shutdown = 1;
|
2008-08-19 22:23:34 +00:00
|
|
|
last_sigterm_info = *si;
|
2007-08-21 17:40:03 +00:00
|
|
|
break;
|
2006-10-04 13:26:23 +00:00
|
|
|
case SIGINT:
|
2007-08-21 17:40:03 +00:00
|
|
|
if (graceful_shutdown) {
|
|
|
|
srv_shutdown = 1;
|
|
|
|
} else {
|
|
|
|
graceful_shutdown = 1;
|
|
|
|
}
|
2008-08-19 22:23:34 +00:00
|
|
|
last_sigterm_info = *si;
|
2007-08-21 17:40:03 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
case SIGALRM:
|
|
|
|
handle_sig_alarm = 1;
|
|
|
|
break;
|
|
|
|
case SIGHUP:
|
2007-09-05 10:39:56 +00:00
|
|
|
/**
|
|
|
|
* we send the SIGHUP to all procs in the process-group
|
|
|
|
* this includes ourself
|
|
|
|
*
|
|
|
|
* make sure we only send it once and don't create a
|
|
|
|
* infinite loop
|
|
|
|
*/
|
|
|
|
if (!forwarded_sig_hup) {
|
|
|
|
handle_sig_hup = 1;
|
2008-08-19 22:23:34 +00:00
|
|
|
last_sighup_info = *si;
|
2007-09-05 10:39:56 +00:00
|
|
|
} else {
|
|
|
|
forwarded_sig_hup = 0;
|
|
|
|
}
|
2007-08-21 17:40:03 +00:00
|
|
|
break;
|
|
|
|
case SIGCHLD:
|
|
|
|
break;
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
|
|
|
|
static void signal_handler(int sig) {
|
|
|
|
switch (sig) {
|
|
|
|
case SIGTERM: srv_shutdown = 1; break;
|
2006-10-04 13:26:23 +00:00
|
|
|
case SIGINT:
|
2006-01-03 14:44:47 +00:00
|
|
|
if (graceful_shutdown) srv_shutdown = 1;
|
2006-10-04 13:26:23 +00:00
|
|
|
else graceful_shutdown = 1;
|
2006-01-03 14:44:47 +00:00
|
|
|
|
|
|
|
break;
|
2005-02-20 14:27:00 +00:00
|
|
|
case SIGALRM: handle_sig_alarm = 1; break;
|
|
|
|
case SIGHUP: handle_sig_hup = 1; break;
|
2005-03-02 15:50:50 +00:00
|
|
|
case SIGCHLD: break;
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_FORK
|
2016-03-26 12:52:23 +00:00
|
|
|
static int daemonize(void) {
|
|
|
|
int pipefd[2];
|
|
|
|
pid_t pid;
|
2005-02-20 14:27:00 +00:00
|
|
|
#ifdef SIGTTOU
|
|
|
|
signal(SIGTTOU, SIG_IGN);
|
|
|
|
#endif
|
|
|
|
#ifdef SIGTTIN
|
|
|
|
signal(SIGTTIN, SIG_IGN);
|
|
|
|
#endif
|
|
|
|
#ifdef SIGTSTP
|
|
|
|
signal(SIGTSTP, SIG_IGN);
|
|
|
|
#endif
|
2016-03-26 12:52:23 +00:00
|
|
|
|
|
|
|
if (pipe(pipefd) < 0) exit(-1);
|
|
|
|
|
|
|
|
if (0 > (pid = fork())) exit(-1);
|
|
|
|
|
|
|
|
if (0 < pid) {
|
|
|
|
char buf;
|
|
|
|
ssize_t bytes;
|
|
|
|
|
|
|
|
close(pipefd[1]);
|
|
|
|
/* parent waits for grandchild to be ready */
|
|
|
|
do {
|
|
|
|
bytes = read(pipefd[0], &buf, sizeof(buf));
|
|
|
|
} while (bytes < 0 && EINTR == errno);
|
|
|
|
close(pipefd[0]);
|
|
|
|
|
|
|
|
if (bytes <= 0) {
|
|
|
|
/* closed fd (without writing) == failure in grandchild */
|
|
|
|
fputs("daemonized server failed to start; check error log for details\n", stderr);
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
close(pipefd[0]);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-11-10 12:10:11 +00:00
|
|
|
if (-1 == setsid()) exit(0);
|
2005-02-20 14:27:00 +00:00
|
|
|
|
|
|
|
signal(SIGHUP, SIG_IGN);
|
|
|
|
|
2005-11-10 12:10:11 +00:00
|
|
|
if (0 != fork()) exit(0);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-11-10 12:10:11 +00:00
|
|
|
if (0 != chdir("/")) exit(0);
|
2016-03-26 12:52:23 +00:00
|
|
|
|
|
|
|
fd_close_on_exec(pipefd[1]);
|
|
|
|
return pipefd[1];
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static server *server_init(void) {
|
|
|
|
int i;
|
2009-06-11 09:53:34 +00:00
|
|
|
FILE *frandom = NULL;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
server *srv = calloc(1, sizeof(*srv));
|
2014-02-16 13:08:20 +00:00
|
|
|
force_assert(srv);
|
2005-02-20 14:27:00 +00:00
|
|
|
#define CLEAN(x) \
|
|
|
|
srv->x = buffer_init();
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(response_header);
|
|
|
|
CLEAN(parse_full_path);
|
|
|
|
CLEAN(ts_debug_str);
|
|
|
|
CLEAN(ts_date_str);
|
2005-07-26 08:26:28 +00:00
|
|
|
CLEAN(errorlog_buf);
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(response_range);
|
|
|
|
CLEAN(tmp_buf);
|
2005-09-29 14:42:35 +00:00
|
|
|
srv->empty_string = buffer_init_string("");
|
2005-08-15 09:55:23 +00:00
|
|
|
CLEAN(cond_check_buf);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-07-26 08:26:28 +00:00
|
|
|
CLEAN(srvconf.errorlog_file);
|
2009-06-21 17:25:39 +00:00
|
|
|
CLEAN(srvconf.breakagelog_file);
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(srvconf.groupname);
|
|
|
|
CLEAN(srvconf.username);
|
|
|
|
CLEAN(srvconf.changeroot);
|
|
|
|
CLEAN(srvconf.bindhost);
|
|
|
|
CLEAN(srvconf.event_handler);
|
|
|
|
CLEAN(srvconf.pid_file);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(tmp_chunk_len);
|
|
|
|
#undef CLEAN
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
#define CLEAN(x) \
|
|
|
|
srv->x = array_init();
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(config_context);
|
|
|
|
CLEAN(config_touched);
|
2006-01-02 23:15:26 +00:00
|
|
|
CLEAN(status);
|
2005-02-20 14:27:00 +00:00
|
|
|
#undef CLEAN
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
for (i = 0; i < FILE_CACHE_MAX; i++) {
|
2007-01-14 09:58:14 +00:00
|
|
|
srv->mtime_cache[i].mtime = (time_t)-1;
|
2005-02-20 14:27:00 +00:00
|
|
|
srv->mtime_cache[i].str = buffer_init();
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2009-06-11 09:53:34 +00:00
|
|
|
if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
|
|
|
|
&& 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
|
2010-07-04 07:45:25 +00:00
|
|
|
unsigned int e;
|
|
|
|
memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
|
|
|
|
srand(e);
|
2009-06-11 09:53:34 +00:00
|
|
|
srv->is_real_entropy = 1;
|
|
|
|
} else {
|
|
|
|
unsigned int j;
|
|
|
|
srand(time(NULL) ^ getpid());
|
|
|
|
srv->is_real_entropy = 0;
|
|
|
|
for (j = 0; j < sizeof(srv->entropy); j++)
|
|
|
|
srv->entropy[j] = rand();
|
|
|
|
}
|
|
|
|
if (frandom) fclose(frandom);
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
srv->cur_ts = time(NULL);
|
|
|
|
srv->startup_ts = srv->cur_ts;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
srv->conns = calloc(1, sizeof(*srv->conns));
|
2014-02-16 13:08:20 +00:00
|
|
|
force_assert(srv->conns);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
srv->joblist = calloc(1, sizeof(*srv->joblist));
|
2014-02-16 13:08:20 +00:00
|
|
|
force_assert(srv->joblist);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
|
2014-02-16 13:08:20 +00:00
|
|
|
force_assert(srv->fdwaitqueue);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
srv->srvconf.modules = array_init();
|
2005-08-27 14:43:45 +00:00
|
|
|
srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
|
2005-10-31 15:34:00 +00:00
|
|
|
srv->srvconf.network_backend = buffer_init();
|
2005-11-01 07:50:08 +00:00
|
|
|
srv->srvconf.upload_tempdirs = array_init();
|
2009-02-04 15:16:29 +00:00
|
|
|
srv->srvconf.reject_expect_100_with_417 = 1;
|
2016-03-26 13:49:43 +00:00
|
|
|
srv->srvconf.xattr_name = buffer_init_string("Content-Type");
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
/* use syslog */
|
2009-06-21 17:25:39 +00:00
|
|
|
srv->errorlog_fd = STDERR_FILENO;
|
|
|
|
srv->errorlog_mode = ERRORLOG_FD;
|
2005-02-20 14:27:00 +00:00
|
|
|
|
|
|
|
srv->split_vals = array_init();
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
return srv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void server_free(server *srv) {
|
|
|
|
size_t i;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
for (i = 0; i < FILE_CACHE_MAX; i++) {
|
|
|
|
buffer_free(srv->mtime_cache[i].str);
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
#define CLEAN(x) \
|
|
|
|
buffer_free(srv->x);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(response_header);
|
|
|
|
CLEAN(parse_full_path);
|
|
|
|
CLEAN(ts_debug_str);
|
|
|
|
CLEAN(ts_date_str);
|
2005-07-26 08:26:28 +00:00
|
|
|
CLEAN(errorlog_buf);
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(response_range);
|
|
|
|
CLEAN(tmp_buf);
|
2005-09-29 14:42:35 +00:00
|
|
|
CLEAN(empty_string);
|
2005-08-15 09:55:23 +00:00
|
|
|
CLEAN(cond_check_buf);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-07-26 08:26:28 +00:00
|
|
|
CLEAN(srvconf.errorlog_file);
|
2009-06-21 17:25:39 +00:00
|
|
|
CLEAN(srvconf.breakagelog_file);
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(srvconf.groupname);
|
|
|
|
CLEAN(srvconf.username);
|
|
|
|
CLEAN(srvconf.changeroot);
|
|
|
|
CLEAN(srvconf.bindhost);
|
|
|
|
CLEAN(srvconf.event_handler);
|
|
|
|
CLEAN(srvconf.pid_file);
|
2005-08-27 14:43:45 +00:00
|
|
|
CLEAN(srvconf.modules_dir);
|
2006-03-04 14:57:35 +00:00
|
|
|
CLEAN(srvconf.network_backend);
|
2016-03-26 13:49:43 +00:00
|
|
|
CLEAN(srvconf.xattr_name);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(tmp_chunk_len);
|
|
|
|
#undef CLEAN
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
fdevent_unregister(srv->ev, srv->fd);
|
|
|
|
#endif
|
|
|
|
fdevent_free(srv->ev);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
free(srv->conns);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
if (srv->config_storage) {
|
|
|
|
for (i = 0; i < srv->config_context->used; i++) {
|
|
|
|
specific_config *s = srv->config_storage[i];
|
2005-06-29 15:31:54 +00:00
|
|
|
|
|
|
|
if (!s) continue;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
buffer_free(s->document_root);
|
|
|
|
buffer_free(s->server_name);
|
|
|
|
buffer_free(s->server_tag);
|
|
|
|
buffer_free(s->ssl_pemfile);
|
2005-02-28 00:00:55 +00:00
|
|
|
buffer_free(s->ssl_ca_file);
|
2006-10-04 13:31:49 +00:00
|
|
|
buffer_free(s->ssl_cipher_list);
|
2011-04-24 16:02:55 +00:00
|
|
|
buffer_free(s->ssl_dh_file);
|
|
|
|
buffer_free(s->ssl_ec_curve);
|
2005-02-20 14:27:00 +00:00
|
|
|
buffer_free(s->error_handler);
|
[core] server.error-handler new directive for error pages (fixes #2702)
server.error-handler preserves HTTP status error code when error page
is static, and allows dynamic handlers to change HTTP status code
when error page is provided by dynamic handler. server.error-handler
intercepts all HTTP status codes >= 400 except when the content is
generated by a dynamic handler (cgi, ssi, fastcgi, scgi, proxy, lua).
The request method is unconditionally changed to GET for the request
to service the error handler, and the original request method is
later restored (for logging purposes). request body from the
original request, if present, is discarded.
server.error-handler is somewhat similar to server.error-handler-404,
but server.error-handler-404 is now deprecated, intercepts only 404
and 403 HTTP status codes, and returns 200 OK for static error pages,
a source of confusion for some admins. On the other hand, the new
server.error-handler, when set, will intercept all HTTP status error
codes >= 400. server.error-handler takes precedence over
server.error-handler-404 when both are set.
NOTE: a major difference between server.error-handler and the
now-deprecated server.error-handler-404 is that the values of the
non-standard CGI environment variables REQUEST_URI and REDIRECT_URI
have been swapped. Since REDIRECT_STATUS is the original HTTP
status code, REDIRECT_URI is now the original request, and REQUEST_URI
is the current request (e.g. the URI/URL to the error handler).
The prior behavior -- which reversed REQUEST_URI and REDIRECT_URI values
from those described above -- is preserved for server.error-handler-404.
Additionally, REDIRECT_STATUS is now available to mod_magnet, which
continues to have access to request.uri and request.orig_uri.
See further discussion at https://redmine.lighttpd.net/issues/2702
and https://redmine.lighttpd.net/issues/1828
github: closes #36
2016-03-01 05:57:48 +00:00
|
|
|
buffer_free(s->error_handler_404);
|
2005-07-15 17:11:19 +00:00
|
|
|
buffer_free(s->errorfile_prefix);
|
2005-02-20 14:27:00 +00:00
|
|
|
array_free(s->mimetypes);
|
2009-10-14 18:19:19 +00:00
|
|
|
buffer_free(s->ssl_verifyclient_username);
|
2006-10-04 13:31:49 +00:00
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
SSL_CTX_free(s->ssl_ctx);
|
2013-11-05 15:29:07 +00:00
|
|
|
EVP_PKEY_free(s->ssl_pemfile_pkey);
|
|
|
|
X509_free(s->ssl_pemfile_x509);
|
|
|
|
if (NULL != s->ssl_ca_file_cert_names) sk_X509_NAME_pop_free(s->ssl_ca_file_cert_names, X509_NAME_free);
|
2006-10-04 13:31:49 +00:00
|
|
|
#endif
|
2005-02-20 14:27:00 +00:00
|
|
|
free(s);
|
|
|
|
}
|
|
|
|
free(srv->config_storage);
|
|
|
|
srv->config_storage = NULL;
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
#define CLEAN(x) \
|
|
|
|
array_free(srv->x);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
CLEAN(config_context);
|
|
|
|
CLEAN(config_touched);
|
2006-01-02 23:15:26 +00:00
|
|
|
CLEAN(status);
|
2006-03-04 14:57:35 +00:00
|
|
|
CLEAN(srvconf.upload_tempdirs);
|
2005-02-20 14:27:00 +00:00
|
|
|
#undef CLEAN
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
joblist_free(srv, srv->joblist);
|
|
|
|
fdwaitqueue_free(srv, srv->fdwaitqueue);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-08-27 14:36:02 +00:00
|
|
|
if (srv->stat_cache) {
|
|
|
|
stat_cache_free(srv->stat_cache);
|
|
|
|
}
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
array_free(srv->srvconf.modules);
|
|
|
|
array_free(srv->split_vals);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2006-10-04 13:31:49 +00:00
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
if (srv->ssl_is_init) {
|
|
|
|
CRYPTO_cleanup_all_ex_data();
|
|
|
|
ERR_free_strings();
|
2016-04-20 07:57:38 +00:00
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
|
|
|
ERR_remove_thread_state();
|
|
|
|
#elif OPENSSL_VERSION_NUMBER >= 0x10000000L
|
|
|
|
ERR_remove_thread_state(NULL);
|
|
|
|
#else
|
2006-10-04 13:31:49 +00:00
|
|
|
ERR_remove_state(0);
|
2016-04-20 07:57:38 +00:00
|
|
|
#endif
|
2006-10-04 13:31:49 +00:00
|
|
|
EVP_cleanup();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
free(srv);
|
|
|
|
}
|
|
|
|
|
2016-03-19 15:01:23 +00:00
|
|
|
static void remove_pid_file(server *srv, int *pid_fd) {
|
|
|
|
if (!buffer_string_is_empty(srv->srvconf.pid_file) && 0 <= *pid_fd) {
|
|
|
|
if (0 != ftruncate(*pid_fd, 0)) {
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
|
|
"ftruncate failed for:",
|
|
|
|
srv->srvconf.pid_file,
|
|
|
|
errno,
|
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (0 <= *pid_fd) {
|
|
|
|
close(*pid_fd);
|
|
|
|
*pid_fd = -1;
|
|
|
|
}
|
|
|
|
if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
|
|
|
|
buffer_string_is_empty(srv->srvconf.changeroot)) {
|
|
|
|
if (0 != unlink(srv->srvconf.pid_file->ptr)) {
|
|
|
|
if (errno != EACCES && errno != EPERM) {
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbds",
|
|
|
|
"unlink failed for:",
|
|
|
|
srv->srvconf.pid_file,
|
|
|
|
errno,
|
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
static void show_version (void) {
|
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
# define TEXT_SSL " (ssl)"
|
|
|
|
#else
|
|
|
|
# define TEXT_SSL
|
|
|
|
#endif
|
2009-04-10 17:35:19 +00:00
|
|
|
char *b = PACKAGE_DESC TEXT_SSL \
|
2005-02-20 14:27:00 +00:00
|
|
|
" - a light and fast webserver\n" \
|
|
|
|
"Build-Date: " __DATE__ " " __TIME__ "\n";
|
|
|
|
;
|
2006-10-04 13:26:23 +00:00
|
|
|
#undef TEXT_SSL
|
2015-08-22 16:01:08 +00:00
|
|
|
write_all(STDOUT_FILENO, b, strlen(b));
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
|
2006-02-03 17:22:43 +00:00
|
|
|
static void show_features (void) {
|
2006-09-15 13:23:07 +00:00
|
|
|
const char features[] = ""
|
2006-02-03 17:22:43 +00:00
|
|
|
#ifdef USE_SELECT
|
|
|
|
"\t+ select (generic)\n"
|
|
|
|
#else
|
|
|
|
"\t- select (generic)\n"
|
|
|
|
#endif
|
|
|
|
#ifdef USE_POLL
|
|
|
|
"\t+ poll (Unix)\n"
|
|
|
|
#else
|
|
|
|
"\t- poll (Unix)\n"
|
|
|
|
#endif
|
|
|
|
#ifdef USE_LINUX_SIGIO
|
|
|
|
"\t+ rt-signals (Linux 2.4+)\n"
|
|
|
|
#else
|
|
|
|
"\t- rt-signals (Linux 2.4+)\n"
|
|
|
|
#endif
|
|
|
|
#ifdef USE_LINUX_EPOLL
|
|
|
|
"\t+ epoll (Linux 2.6)\n"
|
|
|
|
#else
|
|
|
|
"\t- epoll (Linux 2.6)\n"
|
|
|
|
#endif
|
|
|
|
#ifdef USE_SOLARIS_DEVPOLL
|
|
|
|
"\t+ /dev/poll (Solaris)\n"
|
|
|
|
#else
|
|
|
|
"\t- /dev/poll (Solaris)\n"
|
|
|
|
#endif
|
2011-06-13 17:34:57 +00:00
|
|
|
#ifdef USE_SOLARIS_PORT
|
|
|
|
"\t+ eventports (Solaris)\n"
|
|
|
|
#else
|
|
|
|
"\t- eventports (Solaris)\n"
|
|
|
|
#endif
|
2006-02-03 17:22:43 +00:00
|
|
|
#ifdef USE_FREEBSD_KQUEUE
|
|
|
|
"\t+ kqueue (FreeBSD)\n"
|
|
|
|
#else
|
|
|
|
"\t- kqueue (FreeBSD)\n"
|
2010-08-07 11:03:30 +00:00
|
|
|
#endif
|
|
|
|
#ifdef USE_LIBEV
|
|
|
|
"\t+ libev (generic)\n"
|
|
|
|
#else
|
|
|
|
"\t- libev (generic)\n"
|
2006-02-03 17:22:43 +00:00
|
|
|
#endif
|
|
|
|
"\nNetwork handler:\n\n"
|
2011-12-27 12:14:23 +00:00
|
|
|
#if defined USE_LINUX_SENDFILE
|
|
|
|
"\t+ linux-sendfile\n"
|
2006-02-03 17:22:43 +00:00
|
|
|
#else
|
2011-12-27 12:14:23 +00:00
|
|
|
"\t- linux-sendfile\n"
|
|
|
|
#endif
|
|
|
|
#if defined USE_FREEBSD_SENDFILE
|
|
|
|
"\t+ freebsd-sendfile\n"
|
|
|
|
#else
|
|
|
|
"\t- freebsd-sendfile\n"
|
|
|
|
#endif
|
2015-12-04 20:48:21 +00:00
|
|
|
#if defined USE_DARWIN_SENDFILE
|
|
|
|
"\t+ darwin-sendfile\n"
|
|
|
|
#else
|
|
|
|
"\t- darwin-sendfile\n"
|
|
|
|
#endif
|
2011-12-27 12:14:23 +00:00
|
|
|
#if defined USE_SOLARIS_SENDFILEV
|
|
|
|
"\t+ solaris-sendfilev\n"
|
|
|
|
#else
|
|
|
|
"\t- solaris-sendfilev\n"
|
|
|
|
#endif
|
|
|
|
#if defined USE_WRITEV
|
2006-02-03 17:22:43 +00:00
|
|
|
"\t+ writev\n"
|
2011-12-27 12:14:23 +00:00
|
|
|
#else
|
|
|
|
"\t- writev\n"
|
|
|
|
#endif
|
2006-02-03 17:22:43 +00:00
|
|
|
"\t+ write\n"
|
2011-12-27 12:14:23 +00:00
|
|
|
#ifdef USE_MMAP
|
2006-02-03 17:22:43 +00:00
|
|
|
"\t+ mmap support\n"
|
2011-12-27 12:14:23 +00:00
|
|
|
#else
|
2006-02-03 17:22:43 +00:00
|
|
|
"\t- mmap support\n"
|
|
|
|
#endif
|
|
|
|
"\nFeatures:\n\n"
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
"\t+ IPv6 support\n"
|
|
|
|
#else
|
|
|
|
"\t- IPv6 support\n"
|
|
|
|
#endif
|
|
|
|
#if defined HAVE_ZLIB_H && defined HAVE_LIBZ
|
|
|
|
"\t+ zlib support\n"
|
|
|
|
#else
|
|
|
|
"\t- zlib support\n"
|
|
|
|
#endif
|
|
|
|
#if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
|
|
|
|
"\t+ bzip2 support\n"
|
|
|
|
#else
|
|
|
|
"\t- bzip2 support\n"
|
|
|
|
#endif
|
2015-12-04 20:53:51 +00:00
|
|
|
#if defined(HAVE_CRYPT) || defined(HAVE_CRYPT_R) || defined(HAVE_LIBCRYPT)
|
2006-02-03 17:22:43 +00:00
|
|
|
"\t+ crypt support\n"
|
|
|
|
#else
|
|
|
|
"\t- crypt support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
"\t+ SSL Support\n"
|
|
|
|
#else
|
|
|
|
"\t- SSL Support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBPCRE
|
|
|
|
"\t+ PCRE support\n"
|
|
|
|
#else
|
|
|
|
"\t- PCRE support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_MYSQL
|
|
|
|
"\t+ mySQL support\n"
|
|
|
|
#else
|
|
|
|
"\t- mySQL support\n"
|
|
|
|
#endif
|
|
|
|
#if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
|
|
|
|
"\t+ LDAP support\n"
|
|
|
|
#else
|
|
|
|
"\t- LDAP support\n"
|
|
|
|
#endif
|
2016-01-03 14:48:11 +00:00
|
|
|
#ifdef USE_MEMCACHED
|
2006-02-03 17:22:43 +00:00
|
|
|
"\t+ memcached support\n"
|
|
|
|
#else
|
|
|
|
"\t- memcached support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_FAM_H
|
|
|
|
"\t+ FAM support\n"
|
|
|
|
#else
|
|
|
|
"\t- FAM support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LUA_H
|
|
|
|
"\t+ LUA support\n"
|
|
|
|
#else
|
|
|
|
"\t- LUA support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBXML_H
|
|
|
|
"\t+ xml support\n"
|
|
|
|
#else
|
|
|
|
"\t- xml support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SQLITE3_H
|
|
|
|
"\t+ SQLite support\n"
|
|
|
|
#else
|
|
|
|
"\t- SQLite support\n"
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_GDBM_H
|
|
|
|
"\t+ GDBM support\n"
|
|
|
|
#else
|
|
|
|
"\t- GDBM support\n"
|
|
|
|
#endif
|
2006-09-15 13:23:07 +00:00
|
|
|
"\n";
|
|
|
|
show_version();
|
|
|
|
printf("\nEvent Handlers:\n\n%s", features);
|
2006-02-03 17:22:43 +00:00
|
|
|
}
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
static void show_help (void) {
|
|
|
|
#ifdef USE_OPENSSL
|
|
|
|
# define TEXT_SSL " (ssl)"
|
|
|
|
#else
|
|
|
|
# define TEXT_SSL
|
|
|
|
#endif
|
2009-04-10 17:35:19 +00:00
|
|
|
char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
|
2005-02-20 14:27:00 +00:00
|
|
|
" - a light and fast webserver\n" \
|
|
|
|
"usage:\n" \
|
|
|
|
" -f <name> filename of the config-file\n" \
|
2005-08-27 14:43:45 +00:00
|
|
|
" -m <name> module directory (default: "LIBRARY_DIR")\n" \
|
2005-08-08 17:07:55 +00:00
|
|
|
" -p print the parsed config-file in internal form, and exit\n" \
|
|
|
|
" -t test the config-file, and exit\n" \
|
2005-02-20 14:27:00 +00:00
|
|
|
" -D don't go to background (default: go to background)\n" \
|
|
|
|
" -v show version\n" \
|
2006-02-03 17:22:43 +00:00
|
|
|
" -V show compile-time features\n" \
|
2005-02-20 14:27:00 +00:00
|
|
|
" -h show this help\n" \
|
|
|
|
"\n"
|
|
|
|
;
|
2006-10-04 13:26:23 +00:00
|
|
|
#undef TEXT_SSL
|
2005-02-20 14:27:00 +00:00
|
|
|
#undef TEXT_IPV6
|
2015-08-22 16:01:08 +00:00
|
|
|
write_all(STDOUT_FILENO, b, strlen(b));
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int main (int argc, char **argv) {
|
|
|
|
server *srv = NULL;
|
2005-08-08 17:07:55 +00:00
|
|
|
int print_config = 0;
|
|
|
|
int test_config = 0;
|
2005-02-20 14:27:00 +00:00
|
|
|
int i_am_root;
|
|
|
|
int o;
|
|
|
|
int num_childs = 0;
|
|
|
|
int pid_fd = -1, fd;
|
|
|
|
size_t i;
|
|
|
|
#ifdef HAVE_SIGACTION
|
|
|
|
struct sigaction act;
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_GETRLIMIT
|
|
|
|
struct rlimit rlim;
|
|
|
|
#endif
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2016-03-26 12:52:23 +00:00
|
|
|
#ifdef HAVE_FORK
|
|
|
|
int parent_pipe_fd = -1;
|
|
|
|
#endif
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
#ifdef USE_ALARM
|
|
|
|
struct itimerval interval;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
interval.it_interval.tv_sec = 1;
|
|
|
|
interval.it_interval.tv_usec = 0;
|
|
|
|
interval.it_value.tv_sec = 1;
|
|
|
|
interval.it_value.tv_usec = 0;
|
|
|
|
#endif
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
/* for nice %b handling in strfime() */
|
|
|
|
setlocale(LC_TIME, "C");
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
if (NULL == (srv = server_init())) {
|
2005-12-15 14:30:46 +00:00
|
|
|
fprintf(stderr, "did this really happen?\n");
|
2005-02-20 14:27:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
/* init structs done */
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
srv->srvconf.port = 0;
|
|
|
|
#ifdef HAVE_GETUID
|
|
|
|
i_am_root = (getuid() == 0);
|
|
|
|
#else
|
|
|
|
i_am_root = 0;
|
|
|
|
#endif
|
|
|
|
srv->srvconf.dont_daemonize = 0;
|
2016-03-26 13:39:54 +00:00
|
|
|
srv->srvconf.preflight_check = 0;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2006-02-03 17:22:43 +00:00
|
|
|
while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
|
2005-02-20 14:27:00 +00:00
|
|
|
switch(o) {
|
2006-10-04 13:26:23 +00:00
|
|
|
case 'f':
|
2012-05-18 12:56:30 +00:00
|
|
|
if (srv->config_storage) {
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s",
|
|
|
|
"Can only read one config file. Use the include command to use multiple config files.");
|
|
|
|
|
|
|
|
server_free(srv);
|
|
|
|
return -1;
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
if (config_read(srv, optarg)) {
|
2005-02-20 14:27:00 +00:00
|
|
|
server_free(srv);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
break;
|
2005-08-27 14:43:45 +00:00
|
|
|
case 'm':
|
|
|
|
buffer_copy_string(srv->srvconf.modules_dir, optarg);
|
|
|
|
break;
|
2005-08-08 17:07:55 +00:00
|
|
|
case 'p': print_config = 1; break;
|
2016-03-26 13:39:54 +00:00
|
|
|
case 't': ++test_config; break;
|
2005-02-20 14:27:00 +00:00
|
|
|
case 'D': srv->srvconf.dont_daemonize = 1; break;
|
2016-04-01 17:38:32 +00:00
|
|
|
case 'v': show_version(); server_free(srv); return 0;
|
|
|
|
case 'V': show_features(); server_free(srv); return 0;
|
|
|
|
case 'h': show_help(); server_free(srv); return 0;
|
2006-10-04 13:26:23 +00:00
|
|
|
default:
|
2005-02-20 14:27:00 +00:00
|
|
|
show_help();
|
|
|
|
server_free(srv);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
if (!srv->config_storage) {
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s",
|
|
|
|
"No configuration available. Try using -f option.");
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
server_free(srv);
|
|
|
|
return -1;
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-08-08 17:07:55 +00:00
|
|
|
if (print_config) {
|
|
|
|
data_unset *dc = srv->config_context->data[0];
|
|
|
|
if (dc) {
|
|
|
|
dc->print(dc, 0);
|
2006-09-20 14:37:15 +00:00
|
|
|
fprintf(stdout, "\n");
|
2005-08-08 17:07:55 +00:00
|
|
|
} else {
|
|
|
|
/* shouldn't happend */
|
|
|
|
fprintf(stderr, "global config not found\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (test_config) {
|
2016-03-26 13:39:54 +00:00
|
|
|
if (1 == test_config) {
|
|
|
|
printf("Syntax OK\n");
|
|
|
|
} else { /*(test_config > 1)*/
|
|
|
|
test_config = 0;
|
|
|
|
srv->srvconf.preflight_check = 1;
|
|
|
|
srv->srvconf.dont_daemonize = 1;
|
|
|
|
buffer_reset(srv->srvconf.pid_file);
|
|
|
|
}
|
2005-08-08 17:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (test_config || print_config) {
|
|
|
|
server_free(srv);
|
|
|
|
return 0;
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
/* close stdin and stdout, as they are not needed */
|
2008-04-29 20:59:39 +00:00
|
|
|
openDevNull(STDIN_FILENO);
|
|
|
|
openDevNull(STDOUT_FILENO);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
if (0 != config_set_defaults(srv)) {
|
2006-10-04 13:26:23 +00:00
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s",
|
2005-02-20 14:27:00 +00:00
|
|
|
"setting default values failed");
|
|
|
|
server_free(srv);
|
|
|
|
return -1;
|
|
|
|
}
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
/* UID handling */
|
|
|
|
#ifdef HAVE_GETUID
|
2009-04-09 16:51:52 +00:00
|
|