File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / server.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:20:06 2014 UTC (10 years ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_35p0, v1_4_35, HEAD
lighttpd 1.4.35

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

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