File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / server.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:35:00 2016 UTC (7 years, 8 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_41p8, HEAD
lighttpd 1.4.41

    1: #include "first.h"
    2: 
    3: #include "server.h"
    4: #include "buffer.h"
    5: #include "network.h"
    6: #include "log.h"
    7: #include "keyvalue.h"
    8: #include "response.h"
    9: #include "request.h"
   10: #include "chunk.h"
   11: #include "http_chunk.h"
   12: #include "fdevent.h"
   13: #include "connections.h"
   14: #include "stat_cache.h"
   15: #include "plugin.h"
   16: #include "joblist.h"
   17: #include "network_backends.h"
   18: #include "version.h"
   19: 
   20: #include <sys/types.h>
   21: #include <sys/time.h>
   22: #include <sys/stat.h>
   23: 
   24: #include <string.h>
   25: #include <errno.h>
   26: #include <fcntl.h>
   27: #include <unistd.h>
   28: #include <stdlib.h>
   29: #include <time.h>
   30: #include <signal.h>
   31: #include <assert.h>
   32: #include <locale.h>
   33: 
   34: #include <stdio.h>
   35: 
   36: #ifdef HAVE_GETOPT_H
   37: # include <getopt.h>
   38: #endif
   39: 
   40: #ifdef HAVE_VALGRIND_VALGRIND_H
   41: # include <valgrind/valgrind.h>
   42: #endif
   43: 
   44: #ifdef HAVE_SYS_WAIT_H
   45: # include <sys/wait.h>
   46: #endif
   47: 
   48: #ifdef HAVE_PWD_H
   49: # include <grp.h>
   50: # include <pwd.h>
   51: #endif
   52: 
   53: #ifdef HAVE_SYS_RESOURCE_H
   54: # include <sys/resource.h>
   55: #endif
   56: 
   57: #ifdef HAVE_SYS_PRCTL_H
   58: # include <sys/prctl.h>
   59: #endif
   60: 
   61: #ifdef USE_OPENSSL
   62: # include <openssl/err.h> 
   63: #endif
   64: 
   65: #ifndef __sgi
   66: /* IRIX doesn't like the alarm based time() optimization */
   67: /* #define USE_ALARM */
   68: #endif
   69: 
   70: #ifdef HAVE_GETUID
   71: # ifndef HAVE_ISSETUGID
   72: 
   73: static int l_issetugid(void) {
   74: 	return (geteuid() != getuid() || getegid() != getgid());
   75: }
   76: 
   77: #  define issetugid l_issetugid
   78: # endif
   79: #endif
   80: 
   81: static int oneshot_fd = 0;
   82: static volatile sig_atomic_t srv_shutdown = 0;
   83: static volatile sig_atomic_t graceful_shutdown = 0;
   84: static volatile sig_atomic_t handle_sig_alarm = 1;
   85: static volatile sig_atomic_t handle_sig_hup = 0;
   86: static volatile sig_atomic_t forwarded_sig_hup = 0;
   87: 
   88: #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
   89: static volatile siginfo_t last_sigterm_info;
   90: static volatile siginfo_t last_sighup_info;
   91: 
   92: static void sigaction_handler(int sig, siginfo_t *si, void *context) {
   93: 	static siginfo_t empty_siginfo;
   94: 	UNUSED(context);
   95: 
   96: 	if (!si) si = &empty_siginfo;
   97: 
   98: 	switch (sig) {
   99: 	case SIGTERM:
  100: 		srv_shutdown = 1;
  101: 		last_sigterm_info = *si;
  102: 		break;
  103: 	case SIGINT:
  104: 		if (graceful_shutdown) {
  105: 			srv_shutdown = 1;
  106: 		} else {
  107: 			graceful_shutdown = 1;
  108: 		}
  109: 		last_sigterm_info = *si;
  110: 
  111: 		break;
  112: 	case SIGALRM: 
  113: 		handle_sig_alarm = 1; 
  114: 		break;
  115: 	case SIGHUP:
  116: 		/** 
  117: 		 * we send the SIGHUP to all procs in the process-group
  118: 		 * this includes ourself
  119: 		 * 
  120: 		 * make sure we only send it once and don't create a 
  121: 		 * infinite loop
  122: 		 */
  123: 		if (!forwarded_sig_hup) {
  124: 			handle_sig_hup = 1;
  125: 			last_sighup_info = *si;
  126: 		} else {
  127: 			forwarded_sig_hup = 0;
  128: 		}
  129: 		break;
  130: 	case SIGCHLD:
  131: 		break;
  132: 	}
  133: }
  134: #elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
  135: static void signal_handler(int sig) {
  136: 	switch (sig) {
  137: 	case SIGTERM: srv_shutdown = 1; break;
  138: 	case SIGINT:
  139: 	     if (graceful_shutdown) srv_shutdown = 1;
  140: 	     else graceful_shutdown = 1;
  141: 
  142: 	     break;
  143: 	case SIGALRM: handle_sig_alarm = 1; break;
  144: 	case SIGHUP:  handle_sig_hup = 1; break;
  145: 	case SIGCHLD:  break;
  146: 	}
  147: }
  148: #endif
  149: 
  150: #ifdef HAVE_FORK
  151: static int daemonize(void) {
  152: 	int pipefd[2];
  153: 	pid_t pid;
  154: #ifdef SIGTTOU
  155: 	signal(SIGTTOU, SIG_IGN);
  156: #endif
  157: #ifdef SIGTTIN
  158: 	signal(SIGTTIN, SIG_IGN);
  159: #endif
  160: #ifdef SIGTSTP
  161: 	signal(SIGTSTP, SIG_IGN);
  162: #endif
  163: 
  164: 	if (pipe(pipefd) < 0) exit(-1);
  165: 
  166: 	if (0 > (pid = fork())) exit(-1);
  167: 
  168: 	if (0 < pid) {
  169: 		char buf;
  170: 		ssize_t bytes;
  171: 
  172: 		close(pipefd[1]);
  173: 		/* parent waits for grandchild to be ready */
  174: 		do {
  175: 			bytes = read(pipefd[0], &buf, sizeof(buf));
  176: 		} while (bytes < 0 && EINTR == errno);
  177: 		close(pipefd[0]);
  178: 
  179: 		if (bytes <= 0) {
  180: 			/* closed fd (without writing) == failure in grandchild */
  181: 			fputs("daemonized server failed to start; check error log for details\n", stderr);
  182: 			exit(-1);
  183: 		}
  184: 
  185: 		exit(0);
  186: 	}
  187: 
  188: 	close(pipefd[0]);
  189: 
  190: 	if (-1 == setsid()) exit(0);
  191: 
  192: 	signal(SIGHUP, SIG_IGN);
  193: 
  194: 	if (0 != fork()) exit(0);
  195: 
  196: 	if (0 != chdir("/")) exit(0);
  197: 
  198: 	fd_close_on_exec(pipefd[1]);
  199: 	return pipefd[1];
  200: }
  201: #endif
  202: 
  203: static server *server_init(void) {
  204: 	int i;
  205: 	FILE *frandom = NULL;
  206: 
  207: 	server *srv = calloc(1, sizeof(*srv));
  208: 	force_assert(srv);
  209: #define CLEAN(x) \
  210: 	srv->x = buffer_init();
  211: 
  212: 	CLEAN(response_header);
  213: 	CLEAN(parse_full_path);
  214: 	CLEAN(ts_debug_str);
  215: 	CLEAN(ts_date_str);
  216: 	CLEAN(errorlog_buf);
  217: 	CLEAN(response_range);
  218: 	CLEAN(tmp_buf);
  219: 	srv->empty_string = buffer_init_string("");
  220: 	CLEAN(cond_check_buf);
  221: 
  222: 	CLEAN(srvconf.errorlog_file);
  223: 	CLEAN(srvconf.breakagelog_file);
  224: 	CLEAN(srvconf.groupname);
  225: 	CLEAN(srvconf.username);
  226: 	CLEAN(srvconf.changeroot);
  227: 	CLEAN(srvconf.bindhost);
  228: 	CLEAN(srvconf.event_handler);
  229: 	CLEAN(srvconf.pid_file);
  230: 
  231: 	CLEAN(tmp_chunk_len);
  232: #undef CLEAN
  233: 
  234: #define CLEAN(x) \
  235: 	srv->x = array_init();
  236: 
  237: 	CLEAN(config_context);
  238: 	CLEAN(config_touched);
  239: 	CLEAN(status);
  240: #undef CLEAN
  241: 
  242: 	for (i = 0; i < FILE_CACHE_MAX; i++) {
  243: 		srv->mtime_cache[i].mtime = (time_t)-1;
  244: 		srv->mtime_cache[i].str = buffer_init();
  245: 	}
  246: 
  247: 	if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
  248: 	            && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
  249: 		unsigned int e;
  250: 		memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
  251: 		srand(e);
  252: 		srv->is_real_entropy = 1;
  253: 	} else {
  254: 		unsigned int j;
  255: 		srand(time(NULL) ^ getpid());
  256: 		srv->is_real_entropy = 0;
  257: 		for (j = 0; j < sizeof(srv->entropy); j++)
  258: 			srv->entropy[j] = rand();
  259: 	}
  260: 	if (frandom) fclose(frandom);
  261: 
  262: 	srv->cur_ts = time(NULL);
  263: 	srv->startup_ts = srv->cur_ts;
  264: 
  265: 	srv->conns = calloc(1, sizeof(*srv->conns));
  266: 	force_assert(srv->conns);
  267: 
  268: 	srv->joblist = calloc(1, sizeof(*srv->joblist));
  269: 	force_assert(srv->joblist);
  270: 
  271: 	srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
  272: 	force_assert(srv->fdwaitqueue);
  273: 
  274: 	srv->srvconf.modules = array_init();
  275: 	srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
  276: 	srv->srvconf.network_backend = buffer_init();
  277: 	srv->srvconf.upload_tempdirs = array_init();
  278: 	srv->srvconf.reject_expect_100_with_417 = 1;
  279: 	srv->srvconf.xattr_name = buffer_init_string("Content-Type");
  280: 	srv->srvconf.http_header_strict  = 1;
  281: 	srv->srvconf.http_host_strict    = 1; /*(implies http_host_normalize)*/
  282: 	srv->srvconf.http_host_normalize = 0;
  283: 	srv->srvconf.high_precision_timestamps = 0;
  284: 
  285: 	/* use syslog */
  286: 	srv->errorlog_fd = STDERR_FILENO;
  287: 	srv->errorlog_mode = ERRORLOG_FD;
  288: 
  289: 	srv->split_vals = array_init();
  290: 
  291: 	return srv;
  292: }
  293: 
  294: static void server_free(server *srv) {
  295: 	size_t i;
  296: 
  297: 	for (i = 0; i < FILE_CACHE_MAX; i++) {
  298: 		buffer_free(srv->mtime_cache[i].str);
  299: 	}
  300: 
  301: 	if (oneshot_fd > 0) {
  302: 		close(oneshot_fd);
  303: 	}
  304: 
  305: #define CLEAN(x) \
  306: 	buffer_free(srv->x);
  307: 
  308: 	CLEAN(response_header);
  309: 	CLEAN(parse_full_path);
  310: 	CLEAN(ts_debug_str);
  311: 	CLEAN(ts_date_str);
  312: 	CLEAN(errorlog_buf);
  313: 	CLEAN(response_range);
  314: 	CLEAN(tmp_buf);
  315: 	CLEAN(empty_string);
  316: 	CLEAN(cond_check_buf);
  317: 
  318: 	CLEAN(srvconf.errorlog_file);
  319: 	CLEAN(srvconf.breakagelog_file);
  320: 	CLEAN(srvconf.groupname);
  321: 	CLEAN(srvconf.username);
  322: 	CLEAN(srvconf.changeroot);
  323: 	CLEAN(srvconf.bindhost);
  324: 	CLEAN(srvconf.event_handler);
  325: 	CLEAN(srvconf.pid_file);
  326: 	CLEAN(srvconf.modules_dir);
  327: 	CLEAN(srvconf.network_backend);
  328: 	CLEAN(srvconf.xattr_name);
  329: 
  330: 	CLEAN(tmp_chunk_len);
  331: #undef CLEAN
  332: 
  333: #if 0
  334: 	fdevent_unregister(srv->ev, srv->fd);
  335: #endif
  336: 	fdevent_free(srv->ev);
  337: 
  338: 	free(srv->conns);
  339: 
  340: 	if (srv->config_storage) {
  341: 		for (i = 0; i < srv->config_context->used; i++) {
  342: 			specific_config *s = srv->config_storage[i];
  343: 
  344: 			if (!s) continue;
  345: 
  346: 			buffer_free(s->document_root);
  347: 			buffer_free(s->server_name);
  348: 			buffer_free(s->server_tag);
  349: 			buffer_free(s->ssl_pemfile);
  350: 			buffer_free(s->ssl_ca_file);
  351: 			buffer_free(s->ssl_cipher_list);
  352: 			buffer_free(s->ssl_dh_file);
  353: 			buffer_free(s->ssl_ec_curve);
  354: 			buffer_free(s->error_handler);
  355: 			buffer_free(s->error_handler_404);
  356: 			buffer_free(s->errorfile_prefix);
  357: 			array_free(s->mimetypes);
  358: 			buffer_free(s->ssl_verifyclient_username);
  359: #ifdef USE_OPENSSL
  360: 			SSL_CTX_free(s->ssl_ctx);
  361: 			EVP_PKEY_free(s->ssl_pemfile_pkey);
  362: 			X509_free(s->ssl_pemfile_x509);
  363: 			if (NULL != s->ssl_ca_file_cert_names) sk_X509_NAME_pop_free(s->ssl_ca_file_cert_names, X509_NAME_free);
  364: #endif
  365: 			free(s);
  366: 		}
  367: 		free(srv->config_storage);
  368: 		srv->config_storage = NULL;
  369: 	}
  370: 
  371: #define CLEAN(x) \
  372: 	array_free(srv->x);
  373: 
  374: 	CLEAN(config_context);
  375: 	CLEAN(config_touched);
  376: 	CLEAN(status);
  377: 	CLEAN(srvconf.upload_tempdirs);
  378: #undef CLEAN
  379: 
  380: 	joblist_free(srv, srv->joblist);
  381: 	fdwaitqueue_free(srv, srv->fdwaitqueue);
  382: 
  383: 	if (srv->stat_cache) {
  384: 		stat_cache_free(srv->stat_cache);
  385: 	}
  386: 
  387: 	array_free(srv->srvconf.modules);
  388: 	array_free(srv->split_vals);
  389: 
  390: #ifdef USE_OPENSSL
  391: 	if (srv->ssl_is_init) {
  392: 		CRYPTO_cleanup_all_ex_data();
  393: 		ERR_free_strings();
  394: 	      #if   OPENSSL_VERSION_NUMBER >= 0x10100000L \
  395: 		&& !defined(LIBRESSL_VERSION_NUMBER)
  396: 		/*(OpenSSL libraries handle thread init and deinit)
  397: 		 * https://github.com/openssl/openssl/pull/1048 */
  398: 	      #elif OPENSSL_VERSION_NUMBER >= 0x10000000L
  399: 		ERR_remove_thread_state(NULL);
  400: 	      #else
  401: 		ERR_remove_state(0);
  402: 	      #endif
  403: 		EVP_cleanup();
  404: 	}
  405: #endif
  406: 
  407: 	free(srv);
  408: }
  409: 
  410: static void remove_pid_file(server *srv, int *pid_fd) {
  411: 	if (!buffer_string_is_empty(srv->srvconf.pid_file) && 0 <= *pid_fd) {
  412: 		if (0 != ftruncate(*pid_fd, 0)) {
  413: 			log_error_write(srv, __FILE__, __LINE__, "sbds",
  414: 					"ftruncate failed for:",
  415: 					srv->srvconf.pid_file,
  416: 					errno,
  417: 					strerror(errno));
  418: 		}
  419: 	}
  420: 	if (0 <= *pid_fd) {
  421: 		close(*pid_fd);
  422: 		*pid_fd = -1;
  423: 	}
  424: 	if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
  425: 	    buffer_string_is_empty(srv->srvconf.changeroot)) {
  426: 		if (0 != unlink(srv->srvconf.pid_file->ptr)) {
  427: 			if (errno != EACCES && errno != EPERM) {
  428: 				log_error_write(srv, __FILE__, __LINE__, "sbds",
  429: 						"unlink failed for:",
  430: 						srv->srvconf.pid_file,
  431: 						errno,
  432: 						strerror(errno));
  433: 			}
  434: 		}
  435: 	}
  436: }
  437: 
  438: 
  439: static server_socket * server_oneshot_getsock(server *srv, sock_addr *cnt_addr) {
  440: 	server_socket *srv_socket, *srv_socket_wild = NULL;
  441: 	size_t i;
  442: 	for (i = 0; i < srv->srv_sockets.used; ++i) {
  443: 		srv_socket = srv->srv_sockets.ptr[i];
  444: 		if (cnt_addr->plain.sa_family != srv_socket->addr.plain.sa_family) continue;
  445: 		switch (cnt_addr->plain.sa_family) {
  446: 		case AF_INET:
  447: 			if (srv_socket->addr.ipv4.sin_port != cnt_addr->ipv4.sin_port) continue;
  448: 			if (srv_socket->addr.ipv4.sin_addr.s_addr == cnt_addr->ipv4.sin_addr.s_addr) {
  449: 				return srv_socket;
  450: 			}
  451: 			if (srv_socket->addr.ipv4.sin_addr.s_addr == htonl(INADDR_ANY)) {
  452: 				srv_socket_wild = srv_socket;
  453: 			}
  454: 			continue;
  455: 		#ifdef HAVE_IPV6
  456: 		case AF_INET6:
  457: 			if (srv_socket->addr.ipv6.sin6_port != cnt_addr->ipv6.sin6_port) continue;
  458: 			if (0 == memcmp(&srv_socket->addr.ipv6.sin6_addr, &cnt_addr->ipv6.sin6_addr, sizeof(struct in6_addr))) {
  459: 				return srv_socket;
  460: 			}
  461: 			if (0 == memcmp(&srv_socket->addr.ipv6.sin6_addr, &in6addr_any, sizeof(struct in6_addr))) {
  462: 				srv_socket_wild = srv_socket;
  463: 			}
  464: 			continue;
  465: 		#endif
  466: 		#ifdef HAVE_SYS_UN_H
  467: 		case AF_UNIX:
  468: 			if (0 == strcmp(srv_socket->addr.un.sun_path, cnt_addr->un.sun_path)) {
  469: 				return srv_socket;
  470: 			}
  471: 			continue;
  472: 		#endif
  473: 		default: continue;
  474: 		}
  475: 	}
  476: 
  477: 	if (NULL != srv_socket_wild) {
  478: 		return srv_socket_wild;
  479: 	} else if (srv->srv_sockets.used) {
  480: 		return srv->srv_sockets.ptr[0];
  481: 	} else {
  482: 		log_error_write(srv, __FILE__, __LINE__, "s", "no sockets configured");
  483: 		return NULL;
  484: 	}
  485: }
  486: 
  487: 
  488: static int server_oneshot_init(server *srv, int fd) {
  489: 	/* Note: does not work with netcat due to requirement that fd be socket.
  490: 	 * STDOUT_FILENO was not saved earlier in startup, and that is to where
  491: 	 * netcat expects output to be sent.  Since lighttpd expects connections
  492: 	 * to be sockets, con->fd is where output is sent; separate fds are not
  493: 	 * stored for input and output, but netcat has different fds for stdin
  494: 	 * and * stdout.  To support netcat, would additionally need to avoid
  495: 	 * S_ISSOCK(), getsockname(), and getpeername() below, reconstructing
  496: 	 * addresses from environment variables:
  497: 	 *   NCAT_LOCAL_ADDR   NCAT_LOCAL_PORT
  498: 	 *   NCAT_REMOTE_ADDR  NCAT_REMOTE_PORT
  499: 	 *   NCAT_PROTO
  500: 	 */
  501: 	connection *con;
  502: 	server_socket *srv_socket;
  503: 	sock_addr cnt_addr;
  504: 	socklen_t cnt_len;
  505: 	struct stat st;
  506: 
  507: 	if (0 != fstat(fd, &st)) {
  508: 		log_error_write(srv, __FILE__, __LINE__, "ss", "fstat:", strerror(errno));
  509: 		return 0;
  510: 	}
  511: 
  512: 	if (!S_ISSOCK(st.st_mode)) {
  513: 		/* require that fd is a socket
  514: 		 * (modules might expect STDIN_FILENO and STDOUT_FILENO opened to /dev/null) */
  515: 		log_error_write(srv, __FILE__, __LINE__, "s", "lighttpd -1 stdin is not a socket");
  516: 		return 0;
  517: 	}
  518: 
  519: 	cnt_len = sizeof(cnt_addr);
  520: 	if (0 != getsockname(fd, (struct sockaddr *)&cnt_addr, &cnt_len)) {
  521: 		log_error_write(srv, __FILE__, __LINE__, "ss", "getsockname:", strerror(errno));
  522: 		return 0;
  523: 	}
  524: 
  525: 	srv_socket = server_oneshot_getsock(srv, &cnt_addr);
  526: 	if (NULL == srv_socket) return 0;
  527: 
  528: 	cnt_len = sizeof(cnt_addr);
  529: 	if (0 != getpeername(fd, (struct sockaddr *)&cnt_addr, &cnt_len)) {
  530: 		log_error_write(srv, __FILE__, __LINE__, "ss", "getpeername:", strerror(errno));
  531: 		return 0;
  532: 	}
  533: 
  534: 	if (cnt_addr.plain.sa_family != AF_UNIX) {
  535: 		network_accept_tcp_nagle_disable(fd);
  536: 	}
  537: 
  538: 	con = connection_accepted(srv, srv_socket, &cnt_addr, fd);
  539: 	if (NULL == con) return 0;
  540: 
  541: 	connection_state_machine(srv, con);
  542: 	return 1;
  543: }
  544: 
  545: 
  546: static void show_version (void) {
  547: #ifdef USE_OPENSSL
  548: # define TEXT_SSL " (ssl)"
  549: #else
  550: # define TEXT_SSL
  551: #endif
  552: 	char *b = PACKAGE_DESC TEXT_SSL \
  553: " - a light and fast webserver\n" \
  554: "Build-Date: " __DATE__ " " __TIME__ "\n";
  555: ;
  556: #undef TEXT_SSL
  557: 	write_all(STDOUT_FILENO, b, strlen(b));
  558: }
  559: 
  560: static void show_features (void) {
  561:   const char features[] = ""
  562: #ifdef USE_SELECT
  563:       "\t+ select (generic)\n"
  564: #else
  565:       "\t- select (generic)\n"
  566: #endif
  567: #ifdef USE_POLL
  568:       "\t+ poll (Unix)\n"
  569: #else
  570:       "\t- poll (Unix)\n"
  571: #endif
  572: #ifdef USE_LINUX_SIGIO
  573:       "\t+ rt-signals (Linux 2.4+)\n"
  574: #else
  575:       "\t- rt-signals (Linux 2.4+)\n"
  576: #endif
  577: #ifdef USE_LINUX_EPOLL
  578:       "\t+ epoll (Linux 2.6)\n"
  579: #else
  580:       "\t- epoll (Linux 2.6)\n"
  581: #endif
  582: #ifdef USE_SOLARIS_DEVPOLL
  583:       "\t+ /dev/poll (Solaris)\n"
  584: #else
  585:       "\t- /dev/poll (Solaris)\n"
  586: #endif
  587: #ifdef USE_SOLARIS_PORT
  588:       "\t+ eventports (Solaris)\n"
  589: #else
  590:       "\t- eventports (Solaris)\n"
  591: #endif
  592: #ifdef USE_FREEBSD_KQUEUE
  593:       "\t+ kqueue (FreeBSD)\n"
  594: #else
  595:       "\t- kqueue (FreeBSD)\n"
  596: #endif
  597: #ifdef USE_LIBEV
  598:       "\t+ libev (generic)\n"
  599: #else
  600:       "\t- libev (generic)\n"
  601: #endif
  602:       "\nNetwork handler:\n\n"
  603: #if defined USE_LINUX_SENDFILE
  604:       "\t+ linux-sendfile\n"
  605: #else
  606:       "\t- linux-sendfile\n"
  607: #endif
  608: #if defined USE_FREEBSD_SENDFILE
  609:       "\t+ freebsd-sendfile\n"
  610: #else
  611:       "\t- freebsd-sendfile\n"
  612: #endif
  613: #if defined USE_DARWIN_SENDFILE
  614:       "\t+ darwin-sendfile\n"
  615: #else
  616:       "\t- darwin-sendfile\n"
  617: #endif
  618: #if defined USE_SOLARIS_SENDFILEV
  619:       "\t+ solaris-sendfilev\n"
  620: #else
  621:       "\t- solaris-sendfilev\n"
  622: #endif
  623: #if defined USE_WRITEV
  624:       "\t+ writev\n"
  625: #else
  626:       "\t- writev\n"
  627: #endif
  628:       "\t+ write\n"
  629: #ifdef USE_MMAP
  630:       "\t+ mmap support\n"
  631: #else
  632:       "\t- mmap support\n"
  633: #endif
  634:       "\nFeatures:\n\n"
  635: #ifdef HAVE_IPV6
  636:       "\t+ IPv6 support\n"
  637: #else
  638:       "\t- IPv6 support\n"
  639: #endif
  640: #if defined HAVE_ZLIB_H && defined HAVE_LIBZ
  641:       "\t+ zlib support\n"
  642: #else
  643:       "\t- zlib support\n"
  644: #endif
  645: #if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
  646:       "\t+ bzip2 support\n"
  647: #else
  648:       "\t- bzip2 support\n"
  649: #endif
  650: #if defined(HAVE_CRYPT) || defined(HAVE_CRYPT_R) || defined(HAVE_LIBCRYPT)
  651:       "\t+ crypt support\n"
  652: #else
  653:       "\t- crypt support\n"
  654: #endif
  655: #ifdef USE_OPENSSL
  656:       "\t+ SSL Support\n"
  657: #else
  658:       "\t- SSL Support\n"
  659: #endif
  660: #ifdef HAVE_LIBPCRE
  661:       "\t+ PCRE support\n"
  662: #else
  663:       "\t- PCRE support\n"
  664: #endif
  665: #ifdef HAVE_MYSQL
  666:       "\t+ mySQL support\n"
  667: #else
  668:       "\t- mySQL support\n"
  669: #endif
  670: #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
  671:       "\t+ LDAP support\n"
  672: #else
  673:       "\t- LDAP support\n"
  674: #endif
  675: #ifdef USE_MEMCACHED
  676:       "\t+ memcached support\n"
  677: #else
  678:       "\t- memcached support\n"
  679: #endif
  680: #ifdef HAVE_FAM_H
  681:       "\t+ FAM support\n"
  682: #else
  683:       "\t- FAM support\n"
  684: #endif
  685: #ifdef HAVE_LUA_H
  686:       "\t+ LUA support\n"
  687: #else
  688:       "\t- LUA support\n"
  689: #endif
  690: #ifdef HAVE_LIBXML_H
  691:       "\t+ xml support\n"
  692: #else
  693:       "\t- xml support\n"
  694: #endif
  695: #ifdef HAVE_SQLITE3_H
  696:       "\t+ SQLite support\n"
  697: #else
  698:       "\t- SQLite support\n"
  699: #endif
  700: #ifdef HAVE_GDBM_H
  701:       "\t+ GDBM support\n"
  702: #else
  703:       "\t- GDBM support\n"
  704: #endif
  705:       "\n";
  706:   show_version();
  707:   printf("\nEvent Handlers:\n\n%s", features);
  708: }
  709: 
  710: static void show_help (void) {
  711: #ifdef USE_OPENSSL
  712: # define TEXT_SSL " (ssl)"
  713: #else
  714: # define TEXT_SSL
  715: #endif
  716: 	char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
  717: " - a light and fast webserver\n" \
  718: "usage:\n" \
  719: " -f <name>  filename of the config-file\n" \
  720: " -m <name>  module directory (default: "LIBRARY_DIR")\n" \
  721: " -i <secs>  graceful shutdown after <secs> of inactivity\n" \
  722: " -1         process single (one) request on stdin socket, then exit\n" \
  723: " -p         print the parsed config-file in internal form, and exit\n" \
  724: " -t         test config-file syntax, then exit\n" \
  725: " -tt        test config-file syntax, load and init modules, then exit\n" \
  726: " -D         don't go to background (default: go to background)\n" \
  727: " -v         show version\n" \
  728: " -V         show compile-time features\n" \
  729: " -h         show this help\n" \
  730: "\n"
  731: ;
  732: #undef TEXT_SSL
  733: #undef TEXT_IPV6
  734: 	write_all(STDOUT_FILENO, b, strlen(b));
  735: }
  736: 
  737: int main (int argc, char **argv) {
  738: 	server *srv = NULL;
  739: 	int print_config = 0;
  740: 	int test_config = 0;
  741: 	int i_am_root;
  742: 	int o;
  743: 	int num_childs = 0;
  744: 	int pid_fd = -1, fd;
  745: 	size_t i;
  746: 	time_t idle_limit = 0, last_active_ts = time(NULL);
  747: #ifdef HAVE_SIGACTION
  748: 	struct sigaction act;
  749: #endif
  750: #ifdef HAVE_GETRLIMIT
  751: 	struct rlimit rlim;
  752: #endif
  753: 
  754: #ifdef HAVE_FORK
  755: 	int parent_pipe_fd = -1;
  756: #endif
  757: 
  758: #ifdef USE_ALARM
  759: 	struct itimerval interval;
  760: 
  761: 	interval.it_interval.tv_sec = 1;
  762: 	interval.it_interval.tv_usec = 0;
  763: 	interval.it_value.tv_sec = 1;
  764: 	interval.it_value.tv_usec = 0;
  765: #endif
  766: 
  767: 	/* for nice %b handling in strfime() */
  768: 	setlocale(LC_TIME, "C");
  769: 
  770: 	if (NULL == (srv = server_init())) {
  771: 		fprintf(stderr, "did this really happen?\n");
  772: 		return -1;
  773: 	}
  774: 
  775: 	/* init structs done */
  776: 
  777: 	srv->srvconf.port = 0;
  778: #ifdef HAVE_GETUID
  779: 	i_am_root = (getuid() == 0);
  780: #else
  781: 	i_am_root = 0;
  782: #endif
  783: 	srv->srvconf.dont_daemonize = 0;
  784: 	srv->srvconf.preflight_check = 0;
  785: 
  786: 	while(-1 != (o = getopt(argc, argv, "f:m:i:hvVD1pt"))) {
  787: 		switch(o) {
  788: 		case 'f':
  789: 			if (srv->config_storage) {
  790: 				log_error_write(srv, __FILE__, __LINE__, "s",
  791: 						"Can only read one config file. Use the include command to use multiple config files.");
  792: 
  793: 				server_free(srv);
  794: 				return -1;
  795: 			}
  796: 			if (config_read(srv, optarg)) {
  797: 				server_free(srv);
  798: 				return -1;
  799: 			}
  800: 			break;
  801: 		case 'm':
  802: 			buffer_copy_string(srv->srvconf.modules_dir, optarg);
  803: 			break;
  804: 		case 'i': {
  805: 			char *endptr;
  806: 			long timeout = strtol(optarg, &endptr, 0);
  807: 			if (!*optarg || *endptr || timeout < 0) {
  808: 				log_error_write(srv, __FILE__, __LINE__, "ss",
  809: 						"Invalid idle timeout value:", optarg);
  810: 				server_free(srv);
  811: 				return -1;
  812: 			}
  813: 			idle_limit = (time_t)timeout;
  814: 			break;
  815: 		}
  816: 		case 'p': print_config = 1; break;
  817: 		case 't': ++test_config; break;
  818: 		case '1': oneshot_fd = dup(STDIN_FILENO); break;
  819: 		case 'D': srv->srvconf.dont_daemonize = 1; break;
  820: 		case 'v': show_version(); server_free(srv); return 0;
  821: 		case 'V': show_features(); server_free(srv); return 0;
  822: 		case 'h': show_help(); server_free(srv); return 0;
  823: 		default:
  824: 			show_help();
  825: 			server_free(srv);
  826: 			return -1;
  827: 		}
  828: 	}
  829: 
  830: 	if (!srv->config_storage) {
  831: 		log_error_write(srv, __FILE__, __LINE__, "s",
  832: 				"No configuration available. Try using -f option.");
  833: 
  834: 		server_free(srv);
  835: 		return -1;
  836: 	}
  837: 
  838: 	if (print_config) {
  839: 		data_unset *dc = srv->config_context->data[0];
  840: 		if (dc) {
  841: 			dc->print(dc, 0);
  842: 			fprintf(stdout, "\n");
  843: 		} else {
  844: 			/* shouldn't happend */
  845: 			fprintf(stderr, "global config not found\n");
  846: 		}
  847: 	}
  848: 
  849: 	if (test_config) {
  850: 		if (1 == test_config) {
  851: 			printf("Syntax OK\n");
  852: 		} else { /*(test_config > 1)*/
  853: 			test_config = 0;
  854: 			srv->srvconf.preflight_check = 1;
  855: 			srv->srvconf.dont_daemonize = 1;
  856: 			buffer_reset(srv->srvconf.pid_file);
  857: 		}
  858: 	}
  859: 
  860: 	if (test_config || print_config) {
  861: 		server_free(srv);
  862: 		return 0;
  863: 	}
  864: 
  865: 	if (oneshot_fd) {
  866: 		if (oneshot_fd <= STDERR_FILENO) {
  867: 			log_error_write(srv, __FILE__, __LINE__, "s",
  868: 					"Invalid fds at startup with lighttpd -1");
  869: 			server_free(srv);
  870: 			return -1;
  871: 		}
  872: 		graceful_shutdown = 1;
  873: 		srv->sockets_disabled = 1;
  874: 		srv->srvconf.dont_daemonize = 1;
  875: 		buffer_reset(srv->srvconf.pid_file);
  876: 		if (srv->srvconf.max_worker) {
  877: 			srv->srvconf.max_worker = 0;
  878: 			log_error_write(srv, __FILE__, __LINE__, "s",
  879: 					"server one-shot command line option disables server.max-worker config file option.");
  880: 		}
  881: 	}
  882: 
  883: 	/* close stdin and stdout, as they are not needed */
  884: 	openDevNull(STDIN_FILENO);
  885: 	openDevNull(STDOUT_FILENO);
  886: 
  887: 	if (0 != config_set_defaults(srv)) {
  888: 		log_error_write(srv, __FILE__, __LINE__, "s",
  889: 				"setting default values failed");
  890: 		server_free(srv);
  891: 		return -1;
  892: 	}
  893: 
  894: 	/* UID handling */
  895: #ifdef HAVE_GETUID
  896: 	if (!i_am_root && issetugid()) {
  897: 		/* we are setuid-root */
  898: 
  899: 		log_error_write(srv, __FILE__, __LINE__, "s",
  900: 				"Are you nuts ? Don't apply a SUID bit to this binary");
  901: 
  902: 		server_free(srv);
  903: 		return -1;
  904: 	}
  905: #endif
  906: 
  907: 	/* check document-root */
  908: 	if (buffer_string_is_empty(srv->config_storage[0]->document_root)) {
  909: 		log_error_write(srv, __FILE__, __LINE__, "s",
  910: 				"document-root is not set\n");
  911: 
  912: 		server_free(srv);
  913: 
  914: 		return -1;
  915: 	}
  916: 
  917: 	if (plugins_load(srv)) {
  918: 		log_error_write(srv, __FILE__, __LINE__, "s",
  919: 				"loading plugins finally failed");
  920: 
  921: 		plugins_free(srv);
  922: 		server_free(srv);
  923: 
  924: 		return -1;
  925: 	}
  926: 
  927: 	/* open pid file BEFORE chroot */
  928: 	if (!buffer_string_is_empty(srv->srvconf.pid_file)) {
  929: 		if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
  930: 			struct stat st;
  931: 			if (errno != EEXIST) {
  932: 				log_error_write(srv, __FILE__, __LINE__, "sbs",
  933: 					"opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
  934: 				return -1;
  935: 			}
  936: 
  937: 			if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
  938: 				log_error_write(srv, __FILE__, __LINE__, "sbs",
  939: 						"stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
  940: 			}
  941: 
  942: 			if (!S_ISREG(st.st_mode)) {
  943: 				log_error_write(srv, __FILE__, __LINE__, "sb",
  944: 						"pid-file exists and isn't regular file:", srv->srvconf.pid_file);
  945: 				return -1;
  946: 			}
  947: 
  948: 			if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
  949: 				log_error_write(srv, __FILE__, __LINE__, "sbs",
  950: 						"opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
  951: 				return -1;
  952: 			}
  953: 		}
  954: 		fd_close_on_exec(pid_fd);
  955: 	}
  956: 
  957: 	if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
  958: 		/* select limits itself
  959: 		 *
  960: 		 * as it is a hard limit and will lead to a segfault we add some safety
  961: 		 * */
  962: 		srv->max_fds = FD_SETSIZE - 200;
  963: 	} else {
  964: 		srv->max_fds = 4096;
  965: 	}
  966: 
  967: 	if (i_am_root) {
  968: 		struct group *grp = NULL;
  969: 		struct passwd *pwd = NULL;
  970: 		int use_rlimit = 1;
  971: 
  972: #ifdef HAVE_VALGRIND_VALGRIND_H
  973: 		if (RUNNING_ON_VALGRIND) use_rlimit = 0;
  974: #endif
  975: 
  976: #ifdef HAVE_GETRLIMIT
  977: 		if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
  978: 			log_error_write(srv, __FILE__, __LINE__,
  979: 					"ss", "couldn't get 'max filedescriptors'",
  980: 					strerror(errno));
  981: 			return -1;
  982: 		}
  983: 
  984: 		if (use_rlimit && srv->srvconf.max_fds) {
  985: 			/* set rlimits */
  986: 
  987: 			rlim.rlim_cur = srv->srvconf.max_fds;
  988: 			rlim.rlim_max = srv->srvconf.max_fds;
  989: 
  990: 			if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
  991: 				log_error_write(srv, __FILE__, __LINE__,
  992: 						"ss", "couldn't set 'max filedescriptors'",
  993: 						strerror(errno));
  994: 				return -1;
  995: 			}
  996: 		}
  997: 
  998: 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
  999: 			srv->max_fds = rlim.rlim_cur < (rlim_t)FD_SETSIZE - 200 ? (int)rlim.rlim_cur : (int)FD_SETSIZE - 200;
 1000: 		} else {
 1001: 			srv->max_fds = rlim.rlim_cur;
 1002: 		}
 1003: 
 1004: 		/* set core file rlimit, if enable_cores is set */
 1005: 		if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
 1006: 			rlim.rlim_cur = rlim.rlim_max;
 1007: 			setrlimit(RLIMIT_CORE, &rlim);
 1008: 		}
 1009: #endif
 1010: 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
 1011: 			/* don't raise the limit above FD_SET_SIZE */
 1012: 			if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
 1013: 				log_error_write(srv, __FILE__, __LINE__, "sd",
 1014: 						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
 1015: 						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
 1016: 				return -1;
 1017: 			}
 1018: 		}
 1019: 
 1020: 
 1021: #ifdef HAVE_PWD_H
 1022: 		/* set user and group */
 1023: 		if (!buffer_string_is_empty(srv->srvconf.groupname)) {
 1024: 			if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
 1025: 				log_error_write(srv, __FILE__, __LINE__, "sb",
 1026: 					"can't find groupname", srv->srvconf.groupname);
 1027: 				return -1;
 1028: 			}
 1029: 		}
 1030: 
 1031: 		if (!buffer_string_is_empty(srv->srvconf.username)) {
 1032: 			if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
 1033: 				log_error_write(srv, __FILE__, __LINE__, "sb",
 1034: 						"can't find username", srv->srvconf.username);
 1035: 				return -1;
 1036: 			}
 1037: 
 1038: 			if (pwd->pw_uid == 0) {
 1039: 				log_error_write(srv, __FILE__, __LINE__, "s",
 1040: 						"I will not set uid to 0\n");
 1041: 				return -1;
 1042: 			}
 1043: 
 1044: 			if (NULL == grp && NULL == (grp = getgrgid(pwd->pw_gid))) {
 1045: 				log_error_write(srv, __FILE__, __LINE__, "sd",
 1046: 					"can't find group id", pwd->pw_gid);
 1047: 				return -1;
 1048: 			}
 1049: 		}
 1050: 
 1051: 		if (NULL != grp) {
 1052: 			if (grp->gr_gid == 0) {
 1053: 				log_error_write(srv, __FILE__, __LINE__, "s",
 1054: 						"I will not set gid to 0\n");
 1055: 				return -1;
 1056: 			}
 1057: 		}
 1058: #endif
 1059: 		/* we need root-perms for port < 1024 */
 1060: 		if (0 != network_init(srv)) {
 1061: 			plugins_free(srv);
 1062: 			server_free(srv);
 1063: 
 1064: 			return -1;
 1065: 		}
 1066: #ifdef HAVE_PWD_H
 1067: 		/* 
 1068: 		 * Change group before chroot, when we have access
 1069: 		 * to /etc/group
 1070: 		 * */
 1071: 		if (NULL != grp) {
 1072: 			if (-1 == setgid(grp->gr_gid)) {
 1073: 				log_error_write(srv, __FILE__, __LINE__, "ss", "setgid failed: ", strerror(errno));
 1074: 				return -1;
 1075: 			}
 1076: 			if (-1 == setgroups(0, NULL)) {
 1077: 				log_error_write(srv, __FILE__, __LINE__, "ss", "setgroups failed: ", strerror(errno));
 1078: 				return -1;
 1079: 			}
 1080: 			if (!buffer_string_is_empty(srv->srvconf.username)) {
 1081: 				initgroups(srv->srvconf.username->ptr, grp->gr_gid);
 1082: 			}
 1083: 		}
 1084: #endif
 1085: #ifdef HAVE_CHROOT
 1086: 		if (!buffer_string_is_empty(srv->srvconf.changeroot)) {
 1087: 			tzset();
 1088: 
 1089: 			if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
 1090: 				log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
 1091: 				return -1;
 1092: 			}
 1093: 			if (-1 == chdir("/")) {
 1094: 				log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
 1095: 				return -1;
 1096: 			}
 1097: 		}
 1098: #endif
 1099: #ifdef HAVE_PWD_H
 1100: 		/* drop root privs */
 1101: 		if (NULL != pwd) {
 1102: 			if (-1 == setuid(pwd->pw_uid)) {
 1103: 				log_error_write(srv, __FILE__, __LINE__, "ss", "setuid failed: ", strerror(errno));
 1104: 				return -1;
 1105: 			}
 1106: 		}
 1107: #endif
 1108: #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
 1109: 		/**
 1110: 		 * on IRIX 6.5.30 they have prctl() but no DUMPABLE
 1111: 		 */
 1112: 		if (srv->srvconf.enable_cores) {
 1113: 			prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
 1114: 		}
 1115: #endif
 1116: 	} else {
 1117: 
 1118: #ifdef HAVE_GETRLIMIT
 1119: 		if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
 1120: 			log_error_write(srv, __FILE__, __LINE__,
 1121: 					"ss", "couldn't get 'max filedescriptors'",
 1122: 					strerror(errno));
 1123: 			return -1;
 1124: 		}
 1125: 
 1126: 		/**
 1127: 		 * we are not root can can't increase the fd-limit above rlim_max, but we can reduce it
 1128: 		 */
 1129: 		if (srv->srvconf.max_fds && srv->srvconf.max_fds <= rlim.rlim_max) {
 1130: 			/* set rlimits */
 1131: 
 1132: 			rlim.rlim_cur = srv->srvconf.max_fds;
 1133: 
 1134: 			if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
 1135: 				log_error_write(srv, __FILE__, __LINE__,
 1136: 						"ss", "couldn't set 'max filedescriptors'",
 1137: 						strerror(errno));
 1138: 				return -1;
 1139: 			}
 1140: 		}
 1141: 
 1142: 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
 1143: 			srv->max_fds = rlim.rlim_cur < (rlim_t)FD_SETSIZE - 200 ? (int)rlim.rlim_cur : (int)FD_SETSIZE - 200;
 1144: 		} else {
 1145: 			srv->max_fds = rlim.rlim_cur;
 1146: 		}
 1147: 
 1148: 		/* set core file rlimit, if enable_cores is set */
 1149: 		if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
 1150: 			rlim.rlim_cur = rlim.rlim_max;
 1151: 			setrlimit(RLIMIT_CORE, &rlim);
 1152: 		}
 1153: 
 1154: #endif
 1155: 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
 1156: 			/* don't raise the limit above FD_SET_SIZE */
 1157: 			if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
 1158: 				log_error_write(srv, __FILE__, __LINE__, "sd",
 1159: 						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
 1160: 						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
 1161: 				return -1;
 1162: 			}
 1163: 		}
 1164: 
 1165: 		if (0 != network_init(srv)) {
 1166: 			plugins_free(srv);
 1167: 			server_free(srv);
 1168: 
 1169: 			return -1;
 1170: 		}
 1171: 	}
 1172: 
 1173: 	/* set max-conns */
 1174: 	if (srv->srvconf.max_conns > srv->max_fds/2) {
 1175: 		/* we can't have more connections than max-fds/2 */
 1176: 		log_error_write(srv, __FILE__, __LINE__, "sdd", "can't have more connections than fds/2: ", srv->srvconf.max_conns, srv->max_fds);
 1177: 		srv->max_conns = srv->max_fds/2;
 1178: 	} else if (srv->srvconf.max_conns) {
 1179: 		/* otherwise respect the wishes of the user */
 1180: 		srv->max_conns = srv->srvconf.max_conns;
 1181: 	} else {
 1182: 		/* or use the default: we really don't want to hit max-fds */
 1183: 		srv->max_conns = srv->max_fds/3;
 1184: 	}
 1185: 
 1186: 	if (HANDLER_GO_ON != plugins_call_init(srv)) {
 1187: 		log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
 1188: 
 1189: 		plugins_free(srv);
 1190: 		network_close(srv);
 1191: 		server_free(srv);
 1192: 
 1193: 		return -1;
 1194: 	}
 1195: 
 1196: #ifdef HAVE_FORK
 1197: 	/* network is up, let's deamonize ourself */
 1198: 	if (srv->srvconf.dont_daemonize == 0) {
 1199: 		parent_pipe_fd = daemonize();
 1200: 	}
 1201: #endif
 1202: 
 1203: 
 1204: #ifdef HAVE_SIGACTION
 1205: 	memset(&act, 0, sizeof(act));
 1206: 	act.sa_handler = SIG_IGN;
 1207: 	sigaction(SIGPIPE, &act, NULL);
 1208: 	sigaction(SIGUSR1, &act, NULL);
 1209: # if defined(SA_SIGINFO)
 1210: 	act.sa_sigaction = sigaction_handler;
 1211: 	sigemptyset(&act.sa_mask);
 1212: 	act.sa_flags = SA_SIGINFO;
 1213: # else
 1214: 	act.sa_handler = signal_handler;
 1215: 	sigemptyset(&act.sa_mask);
 1216: 	act.sa_flags = 0;
 1217: # endif
 1218: 	sigaction(SIGINT,  &act, NULL);
 1219: 	sigaction(SIGTERM, &act, NULL);
 1220: 	sigaction(SIGHUP,  &act, NULL);
 1221: 	sigaction(SIGALRM, &act, NULL);
 1222: 
 1223: 	/* it should be safe to restart syscalls after SIGCHLD */
 1224: 	act.sa_flags |= SA_RESTART | SA_NOCLDSTOP;
 1225: 	sigaction(SIGCHLD, &act, NULL);
 1226: 
 1227: #elif defined(HAVE_SIGNAL)
 1228: 	/* ignore the SIGPIPE from sendfile() */
 1229: 	signal(SIGPIPE, SIG_IGN);
 1230: 	signal(SIGUSR1, SIG_IGN);
 1231: 	signal(SIGALRM, signal_handler);
 1232: 	signal(SIGTERM, signal_handler);
 1233: 	signal(SIGHUP,  signal_handler);
 1234: 	signal(SIGCHLD,  signal_handler);
 1235: 	signal(SIGINT,  signal_handler);
 1236: #endif
 1237: 
 1238: #ifdef USE_ALARM
 1239: 	signal(SIGALRM, signal_handler);
 1240: 
 1241: 	/* setup periodic timer (1 second) */
 1242: 	if (setitimer(ITIMER_REAL, &interval, NULL)) {
 1243: 		log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
 1244: 		return -1;
 1245: 	}
 1246: 
 1247: 	getitimer(ITIMER_REAL, &interval);
 1248: #endif
 1249: 
 1250: 
 1251: 	srv->gid = getgid();
 1252: 	srv->uid = getuid();
 1253: 
 1254: 	/* write pid file */
 1255: 	if (pid_fd != -1) {
 1256: 		buffer_copy_int(srv->tmp_buf, getpid());
 1257: 		buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
 1258: 		if (-1 == write_all(pid_fd, CONST_BUF_LEN(srv->tmp_buf))) {
 1259: 			log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't write pid file:", strerror(errno));
 1260: 			close(pid_fd);
 1261: 			return -1;
 1262: 		}
 1263: 	}
 1264: 
 1265: 	/* Close stderr ASAP in the child process to make sure that nothing
 1266: 	 * is being written to that fd which may not be valid anymore. */
 1267: 	if (!srv->srvconf.preflight_check && -1 == log_error_open(srv)) {
 1268: 		log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
 1269: 
 1270: 		plugins_free(srv);
 1271: 		network_close(srv);
 1272: 		server_free(srv);
 1273: 		return -1;
 1274: 	}
 1275: 
 1276: 	if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
 1277: 		log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
 1278: 
 1279: 		plugins_free(srv);
 1280: 		network_close(srv);
 1281: 		server_free(srv);
 1282: 
 1283: 		return -1;
 1284: 	}
 1285: 
 1286: 	/* settings might be enabled during module config set defaults */
 1287: 	srv->config_storage[0]->high_precision_timestamps = srv->srvconf.high_precision_timestamps;
 1288: 
 1289: 	/* dump unused config-keys */
 1290: 	for (i = 0; i < srv->config_context->used; i++) {
 1291: 		array *config = ((data_config *)srv->config_context->data[i])->value;
 1292: 		size_t j;
 1293: 
 1294: 		for (j = 0; config && j < config->used; j++) {
 1295: 			data_unset *du = config->data[j];
 1296: 
 1297: 			/* all var.* is known as user defined variable */
 1298: 			if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
 1299: 				continue;
 1300: 			}
 1301: 
 1302: 			if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
 1303: 				log_error_write(srv, __FILE__, __LINE__, "sbs",
 1304: 						"WARNING: unknown config-key:",
 1305: 						du->key,
 1306: 						"(ignored)");
 1307: 			}
 1308: 		}
 1309: 	}
 1310: 
 1311: 	if (srv->config_unsupported) {
 1312: 		log_error_write(srv, __FILE__, __LINE__, "s",
 1313: 				"Configuration contains unsupported keys. Going down.");
 1314: 	}
 1315: 
 1316: 	if (srv->config_deprecated) {
 1317: 		log_error_write(srv, __FILE__, __LINE__, "s",
 1318: 				"Configuration contains deprecated keys. Going down.");
 1319: 	}
 1320: 
 1321: 	if (srv->config_unsupported || srv->config_deprecated) {
 1322: 		plugins_free(srv);
 1323: 		network_close(srv);
 1324: 		server_free(srv);
 1325: 
 1326: 		return -1;
 1327: 	}
 1328: 
 1329: 	if (srv->srvconf.preflight_check) {
 1330: 		/*printf("Preflight OK");*//*(stdout reopened to /dev/null)*/
 1331: 		plugins_free(srv);
 1332: 		network_close(srv);
 1333: 		server_free(srv);
 1334: 
 1335: 		exit(0);
 1336: 	}
 1337: 
 1338: 
 1339: #ifdef HAVE_FORK
 1340: 	/**
 1341: 	 * notify daemonize-grandparent of successful startup
 1342: 	 * do this before any further forking is done (workers)
 1343: 	 */
 1344: 	if (srv->srvconf.dont_daemonize == 0) {
 1345: 		if (0 > write(parent_pipe_fd, "", 1)) return -1;
 1346: 		close(parent_pipe_fd);
 1347: 	}
 1348: 
 1349: 	if (idle_limit && srv->srvconf.max_worker) {
 1350: 		srv->srvconf.max_worker = 0;
 1351: 		log_error_write(srv, __FILE__, __LINE__, "s",
 1352: 				"server idle time limit command line option disables server.max-worker config file option.");
 1353: 	}
 1354: 
 1355: 	/* start watcher and workers */
 1356: 	num_childs = srv->srvconf.max_worker;
 1357: 	if (num_childs > 0) {
 1358: 		int child = 0;
 1359: 		while (!child && !srv_shutdown && !graceful_shutdown) {
 1360: 			if (num_childs > 0) {
 1361: 				switch (fork()) {
 1362: 				case -1:
 1363: 					return -1;
 1364: 				case 0:
 1365: 					child = 1;
 1366: 					break;
 1367: 				default:
 1368: 					num_childs--;
 1369: 					break;
 1370: 				}
 1371: 			} else {
 1372: 				int status;
 1373: 
 1374: 				if (-1 != wait(&status)) {
 1375: 					/** 
 1376: 					 * one of our workers went away 
 1377: 					 */
 1378: 					num_childs++;
 1379: 				} else {
 1380: 					switch (errno) {
 1381: 					case EINTR:
 1382: 						/**
 1383: 						 * if we receive a SIGHUP we have to close our logs ourself as we don't 
 1384: 						 * have the mainloop who can help us here
 1385: 						 */
 1386: 						if (handle_sig_hup) {
 1387: 							handle_sig_hup = 0;
 1388: 
 1389: 							log_error_cycle(srv);
 1390: 
 1391: 							/**
 1392: 							 * forward to all procs in the process-group
 1393: 							 * 
 1394: 							 * we also send it ourself
 1395: 							 */
 1396: 							if (!forwarded_sig_hup && 0 != srv->srvconf.max_worker) {
 1397: 								forwarded_sig_hup = 1;
 1398: 								kill(0, SIGHUP);
 1399: 							}
 1400: 						}
 1401: 						break;
 1402: 					default:
 1403: 						break;
 1404: 					}
 1405: 				}
 1406: 			}
 1407: 		}
 1408: 
 1409: 		/**
 1410: 		 * for the parent this is the exit-point 
 1411: 		 */
 1412: 		if (!child) {
 1413: 			/** 
 1414: 			 * kill all children too 
 1415: 			 */
 1416: 			if (graceful_shutdown) {
 1417: 				kill(0, SIGINT);
 1418: 			} else if (srv_shutdown) {
 1419: 				kill(0, SIGTERM);
 1420: 			}
 1421: 
 1422: 			remove_pid_file(srv, &pid_fd);
 1423: 			log_error_close(srv);
 1424: 			network_close(srv);
 1425: 			connections_free(srv);
 1426: 			plugins_free(srv);
 1427: 			server_free(srv);
 1428: 			return 0;
 1429: 		}
 1430: 
 1431: 		/**
 1432: 		 * make sure workers do not muck with pid-file
 1433: 		 */
 1434: 		if (0 <= pid_fd) {
 1435: 			close(pid_fd);
 1436: 			pid_fd = -1;
 1437: 		}
 1438: 		buffer_reset(srv->srvconf.pid_file);
 1439: 	}
 1440: #endif
 1441: 
 1442: 	if (NULL == (srv->ev = fdevent_init(srv, srv->max_fds + 1, srv->event_handler))) {
 1443: 		log_error_write(srv, __FILE__, __LINE__,
 1444: 				"s", "fdevent_init failed");
 1445: 		return -1;
 1446: 	}
 1447: 
 1448: 	/* libev backend overwrites our SIGCHLD handler and calls waitpid on SIGCHLD; we want our own SIGCHLD handling. */
 1449: #ifdef HAVE_SIGACTION
 1450: 	sigaction(SIGCHLD, &act, NULL);
 1451: #elif defined(HAVE_SIGNAL)
 1452: 	signal(SIGCHLD,  signal_handler);
 1453: #endif
 1454: 
 1455: 	/*
 1456: 	 * kqueue() is called here, select resets its internals,
 1457: 	 * all server sockets get their handlers
 1458: 	 *
 1459: 	 * */
 1460: 	if (0 != network_register_fdevents(srv)) {
 1461: 		plugins_free(srv);
 1462: 		network_close(srv);
 1463: 		server_free(srv);
 1464: 
 1465: 		return -1;
 1466: 	}
 1467: 
 1468: 	/* might fail if user is using fam (not gamin) and famd isn't running */
 1469: 	if (NULL == (srv->stat_cache = stat_cache_init())) {
 1470: 		log_error_write(srv, __FILE__, __LINE__, "s",
 1471: 			"stat-cache could not be setup, dieing.");
 1472: 		return -1;
 1473: 	}
 1474: 
 1475: #ifdef HAVE_FAM_H
 1476: 	/* setup FAM */
 1477: 	if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
 1478: 		if (0 != FAMOpen2(&srv->stat_cache->fam, "lighttpd")) {
 1479: 			log_error_write(srv, __FILE__, __LINE__, "s",
 1480: 					 "could not open a fam connection, dieing.");
 1481: 			return -1;
 1482: 		}
 1483: #ifdef HAVE_FAMNOEXISTS
 1484: 		FAMNoExists(&srv->stat_cache->fam);
 1485: #endif
 1486: 
 1487: 		fdevent_register(srv->ev, FAMCONNECTION_GETFD(&srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
 1488: 		fdevent_event_set(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(&srv->stat_cache->fam), FDEVENT_IN);
 1489: 	}
 1490: #endif
 1491: 
 1492: 
 1493: 	/* get the current number of FDs */
 1494: 	srv->cur_fds = open("/dev/null", O_RDONLY);
 1495: 	close(srv->cur_fds);
 1496: 
 1497: 	for (i = 0; i < srv->srv_sockets.used; i++) {
 1498: 		server_socket *srv_socket = srv->srv_sockets.ptr[i];
 1499: 		if (srv->sockets_disabled) continue; /* lighttpd -1 (one-shot mode) */
 1500: 		if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
 1501: 			log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
 1502: 			return -1;
 1503: 		}
 1504: 	}
 1505: 
 1506: 	if (oneshot_fd && server_oneshot_init(srv, oneshot_fd)) {
 1507: 		oneshot_fd = -1;
 1508: 	}
 1509: 
 1510: 	/* main-loop */
 1511: 	while (!srv_shutdown) {
 1512: 		int n;
 1513: 		size_t ndx;
 1514: 		time_t min_ts;
 1515: 
 1516: 		if (handle_sig_hup) {
 1517: 			handler_t r;
 1518: 
 1519: 			/* reset notification */
 1520: 			handle_sig_hup = 0;
 1521: 
 1522: 
 1523: 			/* cycle logfiles */
 1524: 
 1525: 			switch(r = plugins_call_handle_sighup(srv)) {
 1526: 			case HANDLER_GO_ON:
 1527: 				break;
 1528: 			default:
 1529: 				log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
 1530: 				break;
 1531: 			}
 1532: 
 1533: 			if (-1 == log_error_cycle(srv)) {
 1534: 				log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
 1535: 
 1536: 				return -1;
 1537: 			} else {
 1538: #ifdef HAVE_SIGACTION
 1539: 				log_error_write(srv, __FILE__, __LINE__, "sdsd", 
 1540: 					"logfiles cycled UID =",
 1541: 					last_sighup_info.si_uid,
 1542: 					"PID =",
 1543: 					last_sighup_info.si_pid);
 1544: #else
 1545: 				log_error_write(srv, __FILE__, __LINE__, "s", 
 1546: 					"logfiles cycled");
 1547: #endif
 1548: 			}
 1549: 		}
 1550: 
 1551: 		if (handle_sig_alarm) {
 1552: 			/* a new second */
 1553: 
 1554: #ifdef USE_ALARM
 1555: 			/* reset notification */
 1556: 			handle_sig_alarm = 0;
 1557: #endif
 1558: 
 1559: 			/* get current time */
 1560: 			min_ts = time(NULL);
 1561: 
 1562: 			if (min_ts != srv->cur_ts) {
 1563: #ifdef DEBUG_CONNECTION_STATES
 1564: 				int cs = 0;
 1565: #endif
 1566: 				connections *conns = srv->conns;
 1567: 				handler_t r;
 1568: 
 1569: 				switch(r = plugins_call_handle_trigger(srv)) {
 1570: 				case HANDLER_GO_ON:
 1571: 					break;
 1572: 				case HANDLER_ERROR:
 1573: 					log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
 1574: 					break;
 1575: 				default:
 1576: 					log_error_write(srv, __FILE__, __LINE__, "d", r);
 1577: 					break;
 1578: 				}
 1579: 
 1580: 				/* trigger waitpid */
 1581: 				srv->cur_ts = min_ts;
 1582: 
 1583: 				/* check idle time limit, if enabled */
 1584: 				if (idle_limit && idle_limit < min_ts - last_active_ts && !graceful_shutdown) {
 1585: 					log_error_write(srv, __FILE__, __LINE__, "sDs", "[note] idle timeout", (int)idle_limit,
 1586: 							"s exceeded, initiating graceful shutdown");
 1587: 					graceful_shutdown = 2; /* value 2 indicates idle timeout */
 1588: 				}
 1589: 
 1590: 				/* cleanup stat-cache */
 1591: 				stat_cache_trigger_cleanup(srv);
 1592: 				/**
 1593: 				 * check all connections for timeouts
 1594: 				 *
 1595: 				 */
 1596: 				for (ndx = 0; ndx < conns->used; ndx++) {
 1597: 					connection * const con = conns->ptr[ndx];
 1598: 					const int waitevents = fdevent_event_get_interest(srv->ev, con->fd);
 1599: 					int changed = 0;
 1600: 					int t_diff;
 1601: 
 1602: 					if (con->state == CON_STATE_CLOSE) {
 1603: 						if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {
 1604: 							changed = 1;
 1605: 						}
 1606: 					} else if (waitevents & FDEVENT_IN) {
 1607: 						if (con->request_count == 1 || con->state != CON_STATE_READ) { /* e.g. CON_STATE_READ_POST || CON_STATE_WRITE */
 1608: 							if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
 1609: 								/* time - out */
 1610: 								if (con->conf.log_request_handling) {
 1611: 									log_error_write(srv, __FILE__, __LINE__, "sd",
 1612: 										"connection closed - read timeout:", con->fd);
 1613: 								}
 1614: 
 1615: 								connection_set_state(srv, con, CON_STATE_ERROR);
 1616: 								changed = 1;
 1617: 							}
 1618: 						} else {
 1619: 							if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
 1620: 								/* time - out */
 1621: 								if (con->conf.log_request_handling) {
 1622: 									log_error_write(srv, __FILE__, __LINE__, "sd",
 1623: 										"connection closed - keep-alive timeout:", con->fd);
 1624: 								}
 1625: 
 1626: 								connection_set_state(srv, con, CON_STATE_ERROR);
 1627: 								changed = 1;
 1628: 							}
 1629: 						}
 1630: 					}
 1631: 
 1632: 					/* max_write_idle timeout currently functions as backend timeout,
 1633: 					 * too, after response has been started.
 1634: 					 * future: have separate backend timeout, and then change this
 1635: 					 * to check for write interest before checking for timeout */
 1636: 					/*if (waitevents & FDEVENT_OUT)*/
 1637: 					if ((con->state == CON_STATE_WRITE) &&
 1638: 					    (con->write_request_ts != 0)) {
 1639: #if 0
 1640: 						if (srv->cur_ts - con->write_request_ts > 60) {
 1641: 							log_error_write(srv, __FILE__, __LINE__, "sdd",
 1642: 									"connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
 1643: 						}
 1644: #endif
 1645: 
 1646: 						if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
 1647: 							/* time - out */
 1648: 							if (con->conf.log_timeouts) {
 1649: 								log_error_write(srv, __FILE__, __LINE__, "sbsbsosds",
 1650: 									"NOTE: a request from",
 1651: 									con->dst_addr_buf,
 1652: 									"for",
 1653: 									con->request.uri,
 1654: 									"timed out after writing",
 1655: 									con->bytes_written,
 1656: 									"bytes. We waited",
 1657: 									(int)con->conf.max_write_idle,
 1658: 									"seconds. If this a problem increase server.max-write-idle");
 1659: 							}
 1660: 							connection_set_state(srv, con, CON_STATE_ERROR);
 1661: 							changed = 1;
 1662: 						}
 1663: 					}
 1664: 
 1665: 					/* we don't like div by zero */
 1666: 					if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
 1667: 
 1668: 					if (con->traffic_limit_reached &&
 1669: 					    (con->conf.kbytes_per_second == 0 ||
 1670: 					     ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
 1671: 						/* enable connection again */
 1672: 						con->traffic_limit_reached = 0;
 1673: 
 1674: 						changed = 1;
 1675: 					}
 1676: 
 1677: 					if (changed) {
 1678: 						connection_state_machine(srv, con);
 1679: 					}
 1680: 					con->bytes_written_cur_second = 0;
 1681: 					*(con->conf.global_bytes_per_second_cnt_ptr) = 0;
 1682: 
 1683: #if DEBUG_CONNECTION_STATES
 1684: 					if (cs == 0) {
 1685: 						fprintf(stderr, "connection-state: ");
 1686: 						cs = 1;
 1687: 					}
 1688: 
 1689: 					fprintf(stderr, "c[%d,%d]: %s ",
 1690: 						con->fd,
 1691: 						con->fcgi.fd,
 1692: 						connection_get_state(con->state));
 1693: #endif
 1694: 				}
 1695: 
 1696: #ifdef DEBUG_CONNECTION_STATES
 1697: 				if (cs == 1) fprintf(stderr, "\n");
 1698: #endif
 1699: 			}
 1700: 		}
 1701: 
 1702: 		if (srv->sockets_disabled) {
 1703: 			/* our server sockets are disabled, why ? */
 1704: 
 1705: 			if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
 1706: 			    (srv->conns->used <= srv->max_conns * 9 / 10) &&
 1707: 			    (0 == graceful_shutdown)) {
 1708: 				for (i = 0; i < srv->srv_sockets.used; i++) {
 1709: 					server_socket *srv_socket = srv->srv_sockets.ptr[i];
 1710: 					fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
 1711: 				}
 1712: 
 1713: 				log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
 1714: 
 1715: 				srv->sockets_disabled = 0;
 1716: 			}
 1717: 		} else {
 1718: 			if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
 1719: 			    (srv->conns->used >= srv->max_conns) || /* out of connections */
 1720: 			    (graceful_shutdown)) { /* graceful_shutdown */
 1721: 
 1722: 				/* disable server-fds */
 1723: 
 1724: 				for (i = 0; i < srv->srv_sockets.used; i++) {
 1725: 					server_socket *srv_socket = srv->srv_sockets.ptr[i];
 1726: 
 1727: 					if (graceful_shutdown) {
 1728: 						/* we don't want this socket anymore,
 1729: 						 *
 1730: 						 * closing it right away will make it possible for
 1731: 						 * the next lighttpd to take over (graceful restart)
 1732: 						 *  */
 1733: 
 1734: 						fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
 1735: 						fdevent_unregister(srv->ev, srv_socket->fd);
 1736: 						close(srv_socket->fd);
 1737: 						srv_socket->fd = -1;
 1738: 
 1739: 						/* network_close() will cleanup after us */
 1740: 					} else {
 1741: 						fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, 0);
 1742: 					}
 1743: 				}
 1744: 
 1745: 				if (graceful_shutdown) {
 1746: 					remove_pid_file(srv, &pid_fd);
 1747: 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
 1748: 				} else if (srv->conns->used >= srv->max_conns) {
 1749: 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
 1750: 				} else {
 1751: 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
 1752: 				}
 1753: 
 1754: 				srv->sockets_disabled = 1;
 1755: 			}
 1756: 		}
 1757: 
 1758: 		if (graceful_shutdown && srv->conns->used == 0) {
 1759: 			/* we are in graceful shutdown phase and all connections are closed
 1760: 			 * we are ready to terminate without harming anyone */
 1761: 			srv_shutdown = 1;
 1762: 			break;
 1763: 		}
 1764: 
 1765: 		/* we still have some fds to share */
 1766: 		if (srv->want_fds) {
 1767: 			/* check the fdwaitqueue for waiting fds */
 1768: 			int free_fds = srv->max_fds - srv->cur_fds - 16;
 1769: 			connection *con;
 1770: 
 1771: 			for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
 1772: 				connection_state_machine(srv, con);
 1773: 
 1774: 				srv->want_fds--;
 1775: 			}
 1776: 		}
 1777: 
 1778: 		if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
 1779: 			/* n is the number of events */
 1780: 			int revents;
 1781: 			int fd_ndx;
 1782: 			last_active_ts = srv->cur_ts;
 1783: 			fd_ndx = -1;
 1784: 			do {
 1785: 				fdevent_handler handler;
 1786: 				void *context;
 1787: 
 1788: 				fd_ndx  = fdevent_event_next_fdndx (srv->ev, fd_ndx);
 1789: 				if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
 1790: 
 1791: 				revents = fdevent_event_get_revent (srv->ev, fd_ndx);
 1792: 				fd      = fdevent_event_get_fd     (srv->ev, fd_ndx);
 1793: 				handler = fdevent_get_handler(srv->ev, fd);
 1794: 				context = fdevent_get_context(srv->ev, fd);
 1795: 				(*handler)(srv, context, revents);
 1796: 			} while (--n > 0);
 1797: 		} else if (n < 0 && errno != EINTR) {
 1798: 			log_error_write(srv, __FILE__, __LINE__, "ss",
 1799: 					"fdevent_poll failed:",
 1800: 					strerror(errno));
 1801: 		}
 1802: 
 1803: 		for (ndx = 0; ndx < srv->joblist->used; ndx++) {
 1804: 			connection *con = srv->joblist->ptr[ndx];
 1805: 			connection_state_machine(srv, con);
 1806: 			con->in_joblist = 0;
 1807: 		}
 1808: 
 1809: 		srv->joblist->used = 0;
 1810: 	}
 1811: 
 1812: 	if (0 == graceful_shutdown) {
 1813: 		remove_pid_file(srv, &pid_fd);
 1814: 	}
 1815: 
 1816: 	if (2 == graceful_shutdown) { /* value 2 indicates idle timeout */
 1817: 		log_error_write(srv, __FILE__, __LINE__, "s",
 1818: 				"server stopped after idle timeout");
 1819: 	} else {
 1820: #ifdef HAVE_SIGACTION
 1821: 		log_error_write(srv, __FILE__, __LINE__, "sdsd",
 1822: 				"server stopped by UID =",
 1823: 				last_sigterm_info.si_uid,
 1824: 				"PID =",
 1825: 				last_sigterm_info.si_pid);
 1826: #else
 1827: 		log_error_write(srv, __FILE__, __LINE__, "s",
 1828: 				"server stopped");
 1829: #endif
 1830: 	}
 1831: 
 1832: 	/* clean-up */
 1833: 	log_error_close(srv);
 1834: 	network_close(srv);
 1835: 	connections_free(srv);
 1836: 	plugins_free(srv);
 1837: 	server_free(srv);
 1838: 
 1839: 	return 0;
 1840: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>