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