File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / server.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 10:32:48 2013 UTC (10 years, 8 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_33, HEAD
1.4.33

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

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