axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From din...@apache.org
Subject svn commit: r678637 [42/46] - in /webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd: ./ autom4te.cache/ cygwin/ doc/ openwrt/ src/ tests/ tests/docroot/ tests/docroot/123/ tests/docroot/www/ tests/docroot/www/dummydir/ tests/docroot/www/expire/ ...
Date Tue, 22 Jul 2008 04:35:46 GMT
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,1493 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <signal.h>
+#include <assert.h>
+#include <locale.h>
+
+#include <stdio.h>
+
+#include "server.h"
+#include "buffer.h"
+#include "network.h"
+#include "log.h"
+#include "keyvalue.h"
+#include "response.h"
+#include "request.h"
+#include "chunk.h"
+#include "http_chunk.h"
+#include "fdevent.h"
+#include "connections.h"
+#include "stat_cache.h"
+#include "plugin.h"
+#include "joblist.h"
+#include "network_backends.h"
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <grp.h>
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
+#ifdef USE_OPENSSL
+# include <openssl/err.h> 
+#endif
+
+#ifndef __sgi
+/* IRIX doesn't like the alarm based time() optimization */
+/* #define USE_ALARM */
+#endif
+
+static volatile sig_atomic_t srv_shutdown = 0;
+static volatile sig_atomic_t graceful_shutdown = 0;
+static volatile sig_atomic_t handle_sig_alarm = 1;
+static volatile sig_atomic_t handle_sig_hup = 0;
+static volatile sig_atomic_t forwarded_sig_hup = 0;
+
+#if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
+static volatile siginfo_t last_sigterm_info;
+static volatile siginfo_t last_sighup_info;
+
+static void sigaction_handler(int sig, siginfo_t *si, void *context) {
+	UNUSED(context);
+
+	switch (sig) {
+	case SIGTERM:
+		srv_shutdown = 1;
+		memcpy(&last_sigterm_info, si, sizeof(*si));
+		break;
+	case SIGINT:
+		if (graceful_shutdown) {
+			srv_shutdown = 1;
+		} else {
+			graceful_shutdown = 1;
+		}
+		memcpy(&last_sigterm_info, si, sizeof(*si));
+
+		break;
+	case SIGALRM: 
+		handle_sig_alarm = 1; 
+		break;
+	case SIGHUP:
+		/** 
+		 * we send the SIGHUP to all procs in the process-group
+		 * this includes ourself
+		 * 
+		 * make sure we only send it once and don't create a 
+		 * infinite loop
+		 */
+		if (!forwarded_sig_hup) {
+			handle_sig_hup = 1;
+			memcpy(&last_sighup_info, si, sizeof(*si));
+		} else {
+			forwarded_sig_hup = 0;
+		}
+		break;
+	case SIGCHLD:
+		break;
+	}
+}
+#elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
+static void signal_handler(int sig) {
+	switch (sig) {
+	case SIGTERM: srv_shutdown = 1; break;
+	case SIGINT:
+	     if (graceful_shutdown) srv_shutdown = 1;
+	     else graceful_shutdown = 1;
+
+	     break;
+	case SIGALRM: handle_sig_alarm = 1; break;
+	case SIGHUP:  handle_sig_hup = 1; break;
+	case SIGCHLD:  break;
+	}
+}
+#endif
+
+#ifdef HAVE_FORK
+static void daemonize(void) {
+#ifdef SIGTTOU
+	signal(SIGTTOU, SIG_IGN);
+#endif
+#ifdef SIGTTIN
+	signal(SIGTTIN, SIG_IGN);
+#endif
+#ifdef SIGTSTP
+	signal(SIGTSTP, SIG_IGN);
+#endif
+	if (0 != fork()) exit(0);
+
+	if (-1 == setsid()) exit(0);
+
+	signal(SIGHUP, SIG_IGN);
+
+	if (0 != fork()) exit(0);
+
+	if (0 != chdir("/")) exit(0);
+}
+#endif
+
+static server *server_init(void) {
+	int i;
+
+	server *srv = calloc(1, sizeof(*srv));
+	assert(srv);
+#define CLEAN(x) \
+	srv->x = buffer_init();
+
+	CLEAN(response_header);
+	CLEAN(parse_full_path);
+	CLEAN(ts_debug_str);
+	CLEAN(ts_date_str);
+	CLEAN(errorlog_buf);
+	CLEAN(response_range);
+	CLEAN(tmp_buf);
+	srv->empty_string = buffer_init_string("");
+	CLEAN(cond_check_buf);
+
+	CLEAN(srvconf.errorlog_file);
+	CLEAN(srvconf.groupname);
+	CLEAN(srvconf.username);
+	CLEAN(srvconf.changeroot);
+	CLEAN(srvconf.bindhost);
+	CLEAN(srvconf.event_handler);
+	CLEAN(srvconf.pid_file);
+
+	CLEAN(tmp_chunk_len);
+#undef CLEAN
+
+#define CLEAN(x) \
+	srv->x = array_init();
+
+	CLEAN(config_context);
+	CLEAN(config_touched);
+	CLEAN(status);
+#undef CLEAN
+
+	for (i = 0; i < FILE_CACHE_MAX; i++) {
+		srv->mtime_cache[i].mtime = (time_t)-1;
+		srv->mtime_cache[i].str = buffer_init();
+	}
+
+	srv->cur_ts = time(NULL);
+	srv->startup_ts = srv->cur_ts;
+
+	srv->conns = calloc(1, sizeof(*srv->conns));
+	assert(srv->conns);
+
+	srv->joblist = calloc(1, sizeof(*srv->joblist));
+	assert(srv->joblist);
+
+	srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
+	assert(srv->fdwaitqueue);
+
+	srv->srvconf.modules = array_init();
+	srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
+	srv->srvconf.network_backend = buffer_init();
+	srv->srvconf.upload_tempdirs = array_init();
+
+	/* use syslog */
+	srv->errorlog_fd = -1;
+	srv->errorlog_mode = ERRORLOG_STDERR;
+
+	srv->split_vals = array_init();
+
+	return srv;
+}
+
+static void server_free(server *srv) {
+	size_t i;
+
+	for (i = 0; i < FILE_CACHE_MAX; i++) {
+		buffer_free(srv->mtime_cache[i].str);
+	}
+
+#define CLEAN(x) \
+	buffer_free(srv->x);
+
+	CLEAN(response_header);
+	CLEAN(parse_full_path);
+	CLEAN(ts_debug_str);
+	CLEAN(ts_date_str);
+	CLEAN(errorlog_buf);
+	CLEAN(response_range);
+	CLEAN(tmp_buf);
+	CLEAN(empty_string);
+	CLEAN(cond_check_buf);
+
+	CLEAN(srvconf.errorlog_file);
+	CLEAN(srvconf.groupname);
+	CLEAN(srvconf.username);
+	CLEAN(srvconf.changeroot);
+	CLEAN(srvconf.bindhost);
+	CLEAN(srvconf.event_handler);
+	CLEAN(srvconf.pid_file);
+	CLEAN(srvconf.modules_dir);
+	CLEAN(srvconf.network_backend);
+
+	CLEAN(tmp_chunk_len);
+#undef CLEAN
+
+#if 0
+	fdevent_unregister(srv->ev, srv->fd);
+#endif
+	fdevent_free(srv->ev);
+
+	free(srv->conns);
+
+	if (srv->config_storage) {
+		for (i = 0; i < srv->config_context->used; i++) {
+			specific_config *s = srv->config_storage[i];
+
+			if (!s) continue;
+
+			buffer_free(s->document_root);
+			buffer_free(s->server_name);
+			buffer_free(s->server_tag);
+			buffer_free(s->ssl_pemfile);
+			buffer_free(s->ssl_ca_file);
+			buffer_free(s->ssl_cipher_list);
+			buffer_free(s->error_handler);
+			buffer_free(s->errorfile_prefix);
+			array_free(s->mimetypes);
+#ifdef USE_OPENSSL
+			SSL_CTX_free(s->ssl_ctx);
+#endif
+			free(s);
+		}
+		free(srv->config_storage);
+		srv->config_storage = NULL;
+	}
+
+#define CLEAN(x) \
+	array_free(srv->x);
+
+	CLEAN(config_context);
+	CLEAN(config_touched);
+	CLEAN(status);
+	CLEAN(srvconf.upload_tempdirs);
+#undef CLEAN
+
+	joblist_free(srv, srv->joblist);
+	fdwaitqueue_free(srv, srv->fdwaitqueue);
+
+	if (srv->stat_cache) {
+		stat_cache_free(srv->stat_cache);
+	}
+
+	array_free(srv->srvconf.modules);
+	array_free(srv->split_vals);
+
+#ifdef USE_OPENSSL
+	if (srv->ssl_is_init) {
+		CRYPTO_cleanup_all_ex_data();
+		ERR_free_strings();
+		ERR_remove_state(0);
+		EVP_cleanup();
+	}
+#endif
+
+	free(srv);
+}
+
+static void show_version (void) {
+#ifdef USE_OPENSSL
+# define TEXT_SSL " (ssl)"
+#else
+# define TEXT_SSL
+#endif
+	char *b = PACKAGE_NAME "-" PACKAGE_VERSION TEXT_SSL \
+" - a light and fast webserver\n" \
+"Build-Date: " __DATE__ " " __TIME__ "\n";
+;
+#undef TEXT_SSL
+	write(STDOUT_FILENO, b, strlen(b));
+}
+
+static void show_features (void) {
+  const char features[] = ""
+#ifdef USE_SELECT
+      "\t+ select (generic)\n"
+#else
+      "\t- select (generic)\n"
+#endif
+#ifdef USE_POLL
+      "\t+ poll (Unix)\n"
+#else
+      "\t- poll (Unix)\n"
+#endif
+#ifdef USE_LINUX_SIGIO
+      "\t+ rt-signals (Linux 2.4+)\n"
+#else
+      "\t- rt-signals (Linux 2.4+)\n"
+#endif
+#ifdef USE_LINUX_EPOLL
+      "\t+ epoll (Linux 2.6)\n"
+#else
+      "\t- epoll (Linux 2.6)\n"
+#endif
+#ifdef USE_SOLARIS_DEVPOLL
+      "\t+ /dev/poll (Solaris)\n"
+#else
+      "\t- /dev/poll (Solaris)\n"
+#endif
+#ifdef USE_FREEBSD_KQUEUE
+      "\t+ kqueue (FreeBSD)\n"
+#else
+      "\t- kqueue (FreeBSD)\n"
+#endif
+      "\nNetwork handler:\n\n"
+#if defined(USE_LINUX_SENDFILE) || defined(USE_FREEBSD_SENDFILE) || defined(USE_SOLARIS_SENDFILEV) || defined(USE_AIX_SENDFILE)
+      "\t+ sendfile\n"
+#else
+  #ifdef USE_WRITEV
+      "\t+ writev\n"
+  #else
+      "\t+ write\n"
+  #endif
+  #ifdef USE_MMAP
+      "\t+ mmap support\n"
+  #else
+      "\t- mmap support\n"
+  #endif
+#endif
+      "\nFeatures:\n\n"
+#ifdef HAVE_IPV6
+      "\t+ IPv6 support\n"
+#else
+      "\t- IPv6 support\n"
+#endif
+#if defined HAVE_ZLIB_H && defined HAVE_LIBZ
+      "\t+ zlib support\n"
+#else
+      "\t- zlib support\n"
+#endif
+#if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
+      "\t+ bzip2 support\n"
+#else
+      "\t- bzip2 support\n"
+#endif
+#ifdef HAVE_LIBCRYPT
+      "\t+ crypt support\n"
+#else
+      "\t- crypt support\n"
+#endif
+#ifdef USE_OPENSSL
+      "\t+ SSL Support\n"
+#else
+      "\t- SSL Support\n"
+#endif
+#ifdef HAVE_LIBPCRE
+      "\t+ PCRE support\n"
+#else
+      "\t- PCRE support\n"
+#endif
+#ifdef HAVE_MYSQL
+      "\t+ mySQL support\n"
+#else
+      "\t- mySQL support\n"
+#endif
+#if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
+      "\t+ LDAP support\n"
+#else
+      "\t- LDAP support\n"
+#endif
+#ifdef HAVE_MEMCACHE_H
+      "\t+ memcached support\n"
+#else
+      "\t- memcached support\n"
+#endif
+#ifdef HAVE_FAM_H
+      "\t+ FAM support\n"
+#else
+      "\t- FAM support\n"
+#endif
+#ifdef HAVE_LUA_H
+      "\t+ LUA support\n"
+#else
+      "\t- LUA support\n"
+#endif
+#ifdef HAVE_LIBXML_H
+      "\t+ xml support\n"
+#else
+      "\t- xml support\n"
+#endif
+#ifdef HAVE_SQLITE3_H
+      "\t+ SQLite support\n"
+#else
+      "\t- SQLite support\n"
+#endif
+#ifdef HAVE_GDBM_H
+      "\t+ GDBM support\n"
+#else
+      "\t- GDBM support\n"
+#endif
+      "\n";
+  show_version();
+  printf("\nEvent Handlers:\n\n%s", features);
+}
+
+static void show_help (void) {
+#ifdef USE_OPENSSL
+# define TEXT_SSL " (ssl)"
+#else
+# define TEXT_SSL
+#endif
+	char *b = PACKAGE_NAME "-" PACKAGE_VERSION TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
+" - a light and fast webserver\n" \
+"usage:\n" \
+" -f <name>  filename of the config-file\n" \
+" -m <name>  module directory (default: "LIBRARY_DIR")\n" \
+" -p         print the parsed config-file in internal form, and exit\n" \
+" -t         test the config-file, and exit\n" \
+" -D         don't go to background (default: go to background)\n" \
+" -v         show version\n" \
+" -V         show compile-time features\n" \
+" -h         show this help\n" \
+"\n"
+;
+#undef TEXT_SSL
+#undef TEXT_IPV6
+	write(STDOUT_FILENO, b, strlen(b));
+}
+
+int main (int argc, char **argv) {
+	server *srv = NULL;
+	int print_config = 0;
+	int test_config = 0;
+	int i_am_root;
+	int o;
+	int num_childs = 0;
+	int pid_fd = -1, fd;
+	size_t i;
+#ifdef HAVE_SIGACTION
+	struct sigaction act;
+#endif
+#ifdef HAVE_GETRLIMIT
+	struct rlimit rlim;
+#endif
+
+#ifdef USE_ALARM
+	struct itimerval interval;
+
+	interval.it_interval.tv_sec = 1;
+	interval.it_interval.tv_usec = 0;
+	interval.it_value.tv_sec = 1;
+	interval.it_value.tv_usec = 0;
+#endif
+
+
+	/* for nice %b handling in strfime() */
+	setlocale(LC_TIME, "C");
+
+	if (NULL == (srv = server_init())) {
+		fprintf(stderr, "did this really happen?\n");
+		return -1;
+	}
+
+	/* init structs done */
+
+	srv->srvconf.port = 0;
+#ifdef HAVE_GETUID
+	i_am_root = (getuid() == 0);
+#else
+	i_am_root = 0;
+#endif
+	srv->srvconf.dont_daemonize = 0;
+
+	while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
+		switch(o) {
+		case 'f':
+			if (config_read(srv, optarg)) {
+				server_free(srv);
+				return -1;
+			}
+			break;
+		case 'm':
+			buffer_copy_string(srv->srvconf.modules_dir, optarg);
+			break;
+		case 'p': print_config = 1; break;
+		case 't': test_config = 1; break;
+		case 'D': srv->srvconf.dont_daemonize = 1; break;
+		case 'v': show_version(); return 0;
+		case 'V': show_features(); return 0;
+		case 'h': show_help(); return 0;
+		default:
+			show_help();
+			server_free(srv);
+			return -1;
+		}
+	}
+
+	if (!srv->config_storage) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"No configuration available. Try using -f option.");
+
+		server_free(srv);
+		return -1;
+	}
+
+	if (print_config) {
+		data_unset *dc = srv->config_context->data[0];
+		if (dc) {
+			dc->print(dc, 0);
+			fprintf(stdout, "\n");
+		} else {
+			/* shouldn't happend */
+			fprintf(stderr, "global config not found\n");
+		}
+	}
+
+	if (test_config) {
+		printf("Syntax OK\n");
+	}
+
+	if (test_config || print_config) {
+		server_free(srv);
+		return 0;
+	}
+
+	/* close stdin and stdout, as they are not needed */
+	/* move stdin to /dev/null */
+	if (-1 != (fd = open("/dev/null", O_RDONLY))) {
+		close(STDIN_FILENO);
+		dup2(fd, STDIN_FILENO);
+		close(fd);
+	}
+
+	/* move stdout to /dev/null */
+	if (-1 != (fd = open("/dev/null", O_WRONLY))) {
+		close(STDOUT_FILENO);
+		dup2(fd, STDOUT_FILENO);
+		close(fd);
+	}
+
+	if (0 != config_set_defaults(srv)) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"setting default values failed");
+		server_free(srv);
+		return -1;
+	}
+
+	/* UID handling */
+#ifdef HAVE_GETUID
+	if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
+		/* we are setuid-root */
+
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"Are you nuts ? Don't apply a SUID bit to this binary");
+
+		server_free(srv);
+		return -1;
+	}
+#endif
+
+	/* check document-root */
+	if (srv->config_storage[0]->document_root->used <= 1) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"document-root is not set\n");
+
+		server_free(srv);
+
+		return -1;
+	}
+
+	if (plugins_load(srv)) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"loading plugins finally failed");
+
+		plugins_free(srv);
+		server_free(srv);
+
+		return -1;
+	}
+
+	/* open pid file BEFORE chroot */
+	if (srv->srvconf.pid_file->used) {
+		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))) {
+			struct stat st;
+			if (errno != EEXIST) {
+				log_error_write(srv, __FILE__, __LINE__, "sbs",
+					"opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
+				return -1;
+			}
+
+			if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
+				log_error_write(srv, __FILE__, __LINE__, "sbs",
+						"stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
+			}
+
+			if (!S_ISREG(st.st_mode)) {
+				log_error_write(srv, __FILE__, __LINE__, "sb",
+						"pid-file exists and isn't regular file:", srv->srvconf.pid_file);
+				return -1;
+			}
+
+			if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
+				log_error_write(srv, __FILE__, __LINE__, "sbs",
+						"opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
+				return -1;
+			}
+		}
+	}
+
+	if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+		/* select limits itself
+		 *
+		 * as it is a hard limit and will lead to a segfault we add some safety
+		 * */
+		srv->max_fds = FD_SETSIZE - 200;
+	} else {
+		srv->max_fds = 4096;
+	}
+
+	if (i_am_root) {
+		struct group *grp = NULL;
+		struct passwd *pwd = NULL;
+		int use_rlimit = 1;
+
+#ifdef HAVE_VALGRIND_VALGRIND_H
+		if (RUNNING_ON_VALGRIND) use_rlimit = 0;
+#endif
+
+#ifdef HAVE_GETRLIMIT
+		if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
+			log_error_write(srv, __FILE__, __LINE__,
+					"ss", "couldn't get 'max filedescriptors'",
+					strerror(errno));
+			return -1;
+		}
+
+		if (use_rlimit && srv->srvconf.max_fds) {
+			/* set rlimits */
+
+			rlim.rlim_cur = srv->srvconf.max_fds;
+			rlim.rlim_max = srv->srvconf.max_fds;
+
+			if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
+				log_error_write(srv, __FILE__, __LINE__,
+						"ss", "couldn't set 'max filedescriptors'",
+						strerror(errno));
+				return -1;
+			}
+		}
+
+		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+			srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
+		} else {
+			srv->max_fds = rlim.rlim_cur;
+		}
+
+		/* set core file rlimit, if enable_cores is set */
+		if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
+			rlim.rlim_cur = rlim.rlim_max;
+			setrlimit(RLIMIT_CORE, &rlim);
+		}
+#endif
+		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+			/* don't raise the limit above FD_SET_SIZE */
+			if (srv->max_fds > FD_SETSIZE - 200) {
+				log_error_write(srv, __FILE__, __LINE__, "sd",
+						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
+						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
+				return -1;
+			}
+		}
+
+
+#ifdef HAVE_PWD_H
+		/* set user and group */
+		if (srv->srvconf.username->used) {
+			if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
+				log_error_write(srv, __FILE__, __LINE__, "sb",
+						"can't find username", srv->srvconf.username);
+				return -1;
+			}
+
+			if (pwd->pw_uid == 0) {
+				log_error_write(srv, __FILE__, __LINE__, "s",
+						"I will not set uid to 0\n");
+				return -1;
+			}
+		}
+
+		if (srv->srvconf.groupname->used) {
+			if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
+				log_error_write(srv, __FILE__, __LINE__, "sb",
+					"can't find groupname", srv->srvconf.groupname);
+				return -1;
+			}
+			if (grp->gr_gid == 0) {
+				log_error_write(srv, __FILE__, __LINE__, "s",
+						"I will not set gid to 0\n");
+				return -1;
+			}
+		}
+#endif
+		/* we need root-perms for port < 1024 */
+		if (0 != network_init(srv)) {
+			plugins_free(srv);
+			server_free(srv);
+
+			return -1;
+		}
+#ifdef HAVE_PWD_H
+		/* 
+		 * Change group before chroot, when we have access
+		 * to /etc/group
+		 * */
+		if (srv->srvconf.groupname->used) {
+			setgid(grp->gr_gid);
+			setgroups(0, NULL);
+			if (srv->srvconf.username->used) {
+				initgroups(srv->srvconf.username->ptr, grp->gr_gid);
+			}
+		}
+#endif
+#ifdef HAVE_CHROOT
+		if (srv->srvconf.changeroot->used) {
+			tzset();
+
+			if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
+				log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
+				return -1;
+			}
+			if (-1 == chdir("/")) {
+				log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
+				return -1;
+			}
+		}
+#endif
+#ifdef HAVE_PWD_H
+		/* drop root privs */
+		if (srv->srvconf.username->used) {
+			setuid(pwd->pw_uid);
+		}
+#endif
+#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
+		/**
+		 * on IRIX 6.5.30 they have prctl() but no DUMPABLE
+		 */
+		if (srv->srvconf.enable_cores) {
+			prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+		}
+#endif
+	} else {
+
+#ifdef HAVE_GETRLIMIT
+		if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
+			log_error_write(srv, __FILE__, __LINE__,
+					"ss", "couldn't get 'max filedescriptors'",
+					strerror(errno));
+			return -1;
+		}
+
+		/**
+		 * we are not root can can't increase the fd-limit, but we can reduce it
+		 */
+		if (srv->srvconf.max_fds && srv->srvconf.max_fds < rlim.rlim_cur) {
+			/* set rlimits */
+
+			rlim.rlim_cur = srv->srvconf.max_fds;
+
+			if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
+				log_error_write(srv, __FILE__, __LINE__,
+						"ss", "couldn't set 'max filedescriptors'",
+						strerror(errno));
+				return -1;
+			}
+		}
+
+		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+			srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
+		} else {
+			srv->max_fds = rlim.rlim_cur;
+		}
+
+		/* set core file rlimit, if enable_cores is set */
+		if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
+			rlim.rlim_cur = rlim.rlim_max;
+			setrlimit(RLIMIT_CORE, &rlim);
+		}
+
+#endif
+		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+			/* don't raise the limit above FD_SET_SIZE */
+			if (srv->max_fds > FD_SETSIZE - 200) {
+				log_error_write(srv, __FILE__, __LINE__, "sd",
+						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
+						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
+				return -1;
+			}
+		}
+
+		if (0 != network_init(srv)) {
+			plugins_free(srv);
+			server_free(srv);
+
+			return -1;
+		}
+	}
+
+	/* set max-conns */
+	if (srv->srvconf.max_conns > srv->max_fds) {
+		/* we can't have more connections than max-fds */
+		srv->max_conns = srv->max_fds;
+	} else if (srv->srvconf.max_conns) {
+		/* otherwise respect the wishes of the user */
+		srv->max_conns = srv->srvconf.max_conns;
+	} else {
+		/* or use the default */
+		srv->max_conns = srv->max_fds;
+	}
+
+	if (HANDLER_GO_ON != plugins_call_init(srv)) {
+		log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
+
+		plugins_free(srv);
+		network_close(srv);
+		server_free(srv);
+
+		return -1;
+	}
+
+#ifdef HAVE_FORK
+	/* network is up, let's deamonize ourself */
+	if (srv->srvconf.dont_daemonize == 0) daemonize();
+#endif
+
+	srv->gid = getgid();
+	srv->uid = getuid();
+
+	/* write pid file */
+	if (pid_fd != -1) {
+		buffer_copy_long(srv->tmp_buf, getpid());
+		buffer_append_string(srv->tmp_buf, "\n");
+		write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
+		close(pid_fd);
+		pid_fd = -1;
+	}
+
+	// Close stderr ASAP in the child process to make sure that nothing
+	// is being written to that fd which may not be valid anymore.
+	if (-1 == log_error_open(srv)) {
+		log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
+
+		plugins_free(srv);
+		network_close(srv);
+		server_free(srv);
+		return -1;
+	}
+
+	if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
+		log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
+
+		plugins_free(srv);
+		network_close(srv);
+		server_free(srv);
+
+		return -1;
+	}
+
+	/* dump unused config-keys */
+	for (i = 0; i < srv->config_context->used; i++) {
+		array *config = ((data_config *)srv->config_context->data[i])->value;
+		size_t j;
+
+		for (j = 0; config && j < config->used; j++) {
+			data_unset *du = config->data[j];
+
+			/* all var.* is known as user defined variable */
+			if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
+				continue;
+			}
+
+			if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
+				log_error_write(srv, __FILE__, __LINE__, "sbs",
+						"WARNING: unknown config-key:",
+						du->key,
+						"(ignored)");
+			}
+		}
+	}
+
+	if (srv->config_unsupported) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"Configuration contains unsupported keys. Going down.");
+	}
+
+	if (srv->config_deprecated) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"Configuration contains deprecated keys. Going down.");
+	}
+
+	if (srv->config_unsupported || srv->config_deprecated) {
+		plugins_free(srv);
+		network_close(srv);
+		server_free(srv);
+
+		return -1;
+	}
+
+
+
+
+#ifdef HAVE_SIGACTION
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = SIG_IGN;
+	sigaction(SIGPIPE, &act, NULL);
+	sigaction(SIGUSR1, &act, NULL);
+# if defined(SA_SIGINFO)
+	act.sa_sigaction = sigaction_handler;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = SA_SIGINFO;
+# else
+	act.sa_handler = signal_handler;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = 0;
+# endif
+	sigaction(SIGINT,  &act, NULL);
+	sigaction(SIGTERM, &act, NULL);
+	sigaction(SIGHUP,  &act, NULL);
+	sigaction(SIGALRM, &act, NULL);
+	sigaction(SIGCHLD, &act, NULL);
+
+#elif defined(HAVE_SIGNAL)
+	/* ignore the SIGPIPE from sendfile() */
+	signal(SIGPIPE, SIG_IGN);
+	signal(SIGUSR1, SIG_IGN);
+	signal(SIGALRM, signal_handler);
+	signal(SIGTERM, signal_handler);
+	signal(SIGHUP,  signal_handler);
+	signal(SIGCHLD,  signal_handler);
+	signal(SIGINT,  signal_handler);
+#endif
+
+#ifdef USE_ALARM
+	signal(SIGALRM, signal_handler);
+
+	/* setup periodic timer (1 second) */
+	if (setitimer(ITIMER_REAL, &interval, NULL)) {
+		log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
+		return -1;
+	}
+
+	getitimer(ITIMER_REAL, &interval);
+#endif
+
+#ifdef HAVE_FORK
+	/* start watcher and workers */
+	num_childs = srv->srvconf.max_worker;
+	if (num_childs > 0) {
+		int child = 0;
+		while (!child && !srv_shutdown && !graceful_shutdown) {
+			if (num_childs > 0) {
+				switch (fork()) {
+				case -1:
+					return -1;
+				case 0:
+					child = 1;
+					break;
+				default:
+					num_childs--;
+					break;
+				}
+			} else {
+				int status;
+
+				if (-1 != wait(&status)) {
+					/** 
+					 * one of our workers went away 
+					 */
+					num_childs++;
+				} else {
+					switch (errno) {
+					case EINTR:
+						/**
+						 * if we receive a SIGHUP we have to close our logs ourself as we don't 
+						 * have the mainloop who can help us here
+						 */
+						if (handle_sig_hup) {
+							handle_sig_hup = 0;
+
+							log_error_cycle(srv);
+
+							/**
+							 * forward to all procs in the process-group
+							 * 
+							 * we also send it ourself
+							 */
+							if (!forwarded_sig_hup) {
+								forwarded_sig_hup = 1;
+								kill(0, SIGHUP);
+							}
+						}
+						break;
+					default:
+						break;
+					}
+				}
+			}
+		}
+
+		/**
+		 * for the parent this is the exit-point 
+		 */
+		if (!child) {
+			/** 
+			 * kill all children too 
+			 */
+			if (graceful_shutdown) {
+				kill(0, SIGINT);
+			} else if (srv_shutdown) {
+				kill(0, SIGTERM);
+			}
+
+			log_error_close(srv);
+			network_close(srv);
+			connections_free(srv);
+			plugins_free(srv);
+			server_free(srv);
+			return 0;
+		}
+	}
+#endif
+
+	if (NULL == (srv->ev = fdevent_init(srv->max_fds + 1, srv->event_handler))) {
+		log_error_write(srv, __FILE__, __LINE__,
+				"s", "fdevent_init failed");
+		return -1;
+	}
+	/*
+	 * kqueue() is called here, select resets its internals,
+	 * all server sockets get their handlers
+	 *
+	 * */
+	if (0 != network_register_fdevents(srv)) {
+		plugins_free(srv);
+		network_close(srv);
+		server_free(srv);
+
+		return -1;
+	}
+
+	/* might fail if user is using fam (not gamin) and famd isn't running */
+	if (NULL == (srv->stat_cache = stat_cache_init())) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+			"stat-cache could not be setup, dieing.");
+		return -1;
+	}
+
+#ifdef HAVE_FAM_H
+	/* setup FAM */
+	if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
+		if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
+			log_error_write(srv, __FILE__, __LINE__, "s",
+					 "could not open a fam connection, dieing.");
+			return -1;
+		}
+#ifdef HAVE_FAMNOEXISTS
+		FAMNoExists(srv->stat_cache->fam);
+#endif
+
+		srv->stat_cache->fam_fcce_ndx = -1;
+		fdevent_register(srv->ev, FAMCONNECTION_GETFD(srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
+		fdevent_event_add(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(srv->stat_cache->fam), FDEVENT_IN);
+	}
+#endif
+
+
+	/* get the current number of FDs */
+	srv->cur_fds = open("/dev/null", O_RDONLY);
+	close(srv->cur_fds);
+
+	for (i = 0; i < srv->srv_sockets.used; i++) {
+		server_socket *srv_socket = srv->srv_sockets.ptr[i];
+		if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
+			log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
+			return -1;
+		}
+	}
+
+	/* main-loop */
+	while (!srv_shutdown) {
+		int n;
+		size_t ndx;
+		time_t min_ts;
+
+		if (handle_sig_hup) {
+			handler_t r;
+
+			/* reset notification */
+			handle_sig_hup = 0;
+
+
+			/* cycle logfiles */
+
+			switch(r = plugins_call_handle_sighup(srv)) {
+			case HANDLER_GO_ON:
+				break;
+			default:
+				log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
+				break;
+			}
+
+			if (-1 == log_error_cycle(srv)) {
+				log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
+
+				return -1;
+			} else {
+#ifdef HAVE_SIGACTION
+				log_error_write(srv, __FILE__, __LINE__, "sdsd", 
+					"logfiles cycled UID =",
+					last_sighup_info.si_uid,
+					"PID =",
+					last_sighup_info.si_pid);
+#else
+				log_error_write(srv, __FILE__, __LINE__, "s", 
+					"logfiles cycled");
+#endif
+			}
+		}
+
+		if (handle_sig_alarm) {
+			/* a new second */
+
+#ifdef USE_ALARM
+			/* reset notification */
+			handle_sig_alarm = 0;
+#endif
+
+			/* get current time */
+			min_ts = time(NULL);
+
+			if (min_ts != srv->cur_ts) {
+				int cs = 0;
+				connections *conns = srv->conns;
+				handler_t r;
+
+				switch(r = plugins_call_handle_trigger(srv)) {
+				case HANDLER_GO_ON:
+					break;
+				case HANDLER_ERROR:
+					log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
+					break;
+				default:
+					log_error_write(srv, __FILE__, __LINE__, "d", r);
+					break;
+				}
+
+				/* trigger waitpid */
+				srv->cur_ts = min_ts;
+
+				/* cleanup stat-cache */
+				stat_cache_trigger_cleanup(srv);
+				/**
+				 * check all connections for timeouts
+				 *
+				 */
+				for (ndx = 0; ndx < conns->used; ndx++) {
+					int changed = 0;
+					connection *con;
+					int t_diff;
+
+					con = conns->ptr[ndx];
+
+					if (con->state == CON_STATE_READ ||
+					    con->state == CON_STATE_READ_POST) {
+						if (con->request_count == 1) {
+							if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
+								/* time - out */
+#if 0
+								log_error_write(srv, __FILE__, __LINE__, "sd",
+										"connection closed - read-timeout:", con->fd);
+#endif
+								connection_set_state(srv, con, CON_STATE_ERROR);
+								changed = 1;
+							}
+						} else {
+							if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
+								/* time - out */
+#if 0
+								log_error_write(srv, __FILE__, __LINE__, "sd",
+										"connection closed - read-timeout:", con->fd);
+#endif
+								connection_set_state(srv, con, CON_STATE_ERROR);
+								changed = 1;
+							}
+						}
+					}
+
+					if ((con->state == CON_STATE_WRITE) &&
+					    (con->write_request_ts != 0)) {
+#if 0
+						if (srv->cur_ts - con->write_request_ts > 60) {
+							log_error_write(srv, __FILE__, __LINE__, "sdd",
+									"connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
+						}
+#endif
+
+						if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
+							/* time - out */
+#if 1
+							log_error_write(srv, __FILE__, __LINE__, "sbsosds",
+									"NOTE: a request for",
+									con->request.uri,
+									"timed out after writing",
+									con->bytes_written,
+									"bytes. We waited",
+									(int)con->conf.max_write_idle,
+									"seconds. If this a problem increase server.max-write-idle");
+#endif
+							connection_set_state(srv, con, CON_STATE_ERROR);
+							changed = 1;
+						}
+					}
+					/* we don't like div by zero */
+					if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
+
+					if (con->traffic_limit_reached &&
+					    (con->conf.kbytes_per_second == 0 ||
+					     ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
+						/* enable connection again */
+						con->traffic_limit_reached = 0;
+
+						changed = 1;
+					}
+
+					if (changed) {
+						connection_state_machine(srv, con);
+					}
+					con->bytes_written_cur_second = 0;
+					*(con->conf.global_bytes_per_second_cnt_ptr) = 0;
+
+#if 0
+					if (cs == 0) {
+						fprintf(stderr, "connection-state: ");
+						cs = 1;
+					}
+
+					fprintf(stderr, "c[%d,%d]: %s ",
+						con->fd,
+						con->fcgi.fd,
+						connection_get_state(con->state));
+#endif
+				}
+
+				if (cs == 1) fprintf(stderr, "\n");
+			}
+		}
+
+		if (srv->sockets_disabled) {
+			/* our server sockets are disabled, why ? */
+
+			if ((srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) && /* we have enough unused fds */
+			    (srv->conns->used < srv->max_conns * 0.9) &&
+			    (0 == graceful_shutdown)) {
+				for (i = 0; i < srv->srv_sockets.used; i++) {
+					server_socket *srv_socket = srv->srv_sockets.ptr[i];
+					fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
+				}
+
+				log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
+
+				srv->sockets_disabled = 0;
+			}
+		} else {
+			if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
+			    (srv->conns->used > srv->max_conns) || /* out of connections */
+			    (graceful_shutdown)) { /* graceful_shutdown */
+
+				/* disable server-fds */
+
+				for (i = 0; i < srv->srv_sockets.used; i++) {
+					server_socket *srv_socket = srv->srv_sockets.ptr[i];
+					fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
+
+					if (graceful_shutdown) {
+						/* we don't want this socket anymore,
+						 *
+						 * closing it right away will make it possible for
+						 * the next lighttpd to take over (graceful restart)
+						 *  */
+
+						fdevent_unregister(srv->ev, srv_socket->fd);
+						close(srv_socket->fd);
+						srv_socket->fd = -1;
+
+						/* network_close() will cleanup after us */
+
+						if (srv->srvconf.pid_file->used &&
+						    srv->srvconf.changeroot->used == 0) {
+							if (0 != unlink(srv->srvconf.pid_file->ptr)) {
+								if (errno != EACCES && errno != EPERM) {
+									log_error_write(srv, __FILE__, __LINE__, "sbds",
+											"unlink failed for:",
+											srv->srvconf.pid_file,
+											errno,
+											strerror(errno));
+								}
+							}
+						}
+					}
+				}
+
+				if (graceful_shutdown) {
+					log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
+				} else if (srv->conns->used > srv->max_conns) {
+					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
+				} else {
+					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
+				}
+
+				srv->sockets_disabled = 1;
+			}
+		}
+
+		if (graceful_shutdown && srv->conns->used == 0) {
+			/* we are in graceful shutdown phase and all connections are closed
+			 * we are ready to terminate without harming anyone */
+			srv_shutdown = 1;
+		}
+
+		/* we still have some fds to share */
+		if (srv->want_fds) {
+			/* check the fdwaitqueue for waiting fds */
+			int free_fds = srv->max_fds - srv->cur_fds - 16;
+			connection *con;
+
+			for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
+				connection_state_machine(srv, con);
+
+				srv->want_fds--;
+			}
+		}
+
+		if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
+			/* n is the number of events */
+			int revents;
+			int fd_ndx;
+#if 0
+			if (n > 0) {
+				log_error_write(srv, __FILE__, __LINE__, "sd",
+						"polls:", n);
+			}
+#endif
+			fd_ndx = -1;
+			do {
+				fdevent_handler handler;
+				void *context;
+				handler_t r;
+
+				fd_ndx  = fdevent_event_next_fdndx (srv->ev, fd_ndx);
+				revents = fdevent_event_get_revent (srv->ev, fd_ndx);
+				fd      = fdevent_event_get_fd     (srv->ev, fd_ndx);
+				handler = fdevent_get_handler(srv->ev, fd);
+				context = fdevent_get_context(srv->ev, fd);
+
+				/* connection_handle_fdevent needs a joblist_append */
+#if 0
+				log_error_write(srv, __FILE__, __LINE__, "sdd",
+						"event for", fd, revents);
+#endif
+				switch (r = (*handler)(srv, context, revents)) {
+				case HANDLER_FINISHED:
+				case HANDLER_GO_ON:
+				case HANDLER_WAIT_FOR_EVENT:
+				case HANDLER_WAIT_FOR_FD:
+					break;
+				case HANDLER_ERROR:
+					/* should never happen */
+					SEGFAULT();
+					break;
+				default:
+					log_error_write(srv, __FILE__, __LINE__, "d", r);
+					break;
+				}
+			} while (--n > 0);
+		} else if (n < 0 && errno != EINTR) {
+			log_error_write(srv, __FILE__, __LINE__, "ss",
+					"fdevent_poll failed:",
+					strerror(errno));
+		}
+
+		for (ndx = 0; ndx < srv->joblist->used; ndx++) {
+			connection *con = srv->joblist->ptr[ndx];
+			handler_t r;
+
+			connection_state_machine(srv, con);
+
+			switch(r = plugins_call_handle_joblist(srv, con)) {
+			case HANDLER_FINISHED:
+			case HANDLER_GO_ON:
+				break;
+			default:
+				log_error_write(srv, __FILE__, __LINE__, "d", r);
+				break;
+			}
+
+			con->in_joblist = 0;
+		}
+
+		srv->joblist->used = 0;
+	}
+
+	if (srv->srvconf.pid_file->used &&
+	    srv->srvconf.changeroot->used == 0 &&
+	    0 == graceful_shutdown) {
+		if (0 != unlink(srv->srvconf.pid_file->ptr)) {
+			if (errno != EACCES && errno != EPERM) {
+				log_error_write(srv, __FILE__, __LINE__, "sbds",
+						"unlink failed for:",
+						srv->srvconf.pid_file,
+						errno,
+						strerror(errno));
+			}
+		}
+	}
+
+#ifdef HAVE_SIGACTION
+	log_error_write(srv, __FILE__, __LINE__, "sdsd", 
+			"server stopped by UID =",
+			last_sigterm_info.si_uid,
+			"PID =",
+			last_sigterm_info.si_pid);
+#else
+	log_error_write(srv, __FILE__, __LINE__, "s", 
+			"server stopped");
+#endif
+
+	/* clean-up */
+	log_error_close(srv);
+	network_close(srv);
+	connections_free(srv);
+	plugins_free(srv);
+	server_free(srv);
+
+	return 0;
+}

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/server.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,17 @@
+#ifndef _SERVER_H_
+#define _SERVER_H_
+
+#include "base.h"
+
+typedef struct {
+	char *key;
+	char *value;
+} two_strings;
+
+typedef enum { CONFIG_UNSET, CONFIG_DOCUMENT_ROOT } config_var_t;
+
+int config_read(server *srv, const char *fn);
+int config_set_defaults(server *srv);
+buffer *config_get_value_buffer(server *srv, connection *con, config_var_t field);
+
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/settings.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/settings.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/settings.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/settings.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,44 @@
+#ifndef _LIGHTTPD_SETTINGS_H_
+#define _LIGHTTPD_SETTINGS_H_
+
+#define BV(x) (1 << x)
+
+#define INET_NTOP_CACHE_MAX 4
+#define FILE_CACHE_MAX      16
+
+/**
+ * max size of a buffer which will just be reset
+ * to ->used = 0 instead of really freeing the buffer
+ *
+ * 64kB (no real reason, just a guess)
+ */
+#define BUFFER_MAX_REUSE_SIZE  (4 * 1024)
+
+/**
+ * max size of the HTTP request header
+ *
+ * 32k should be enough for everything (just a guess)
+ *
+ */
+#define MAX_HTTP_REQUEST_HEADER  (32 * 1024)
+
+typedef enum { HANDLER_UNSET,
+		HANDLER_GO_ON,
+		HANDLER_FINISHED,
+		HANDLER_COMEBACK,
+		HANDLER_WAIT_FOR_EVENT,
+		HANDLER_ERROR,
+		HANDLER_WAIT_FOR_FD
+} handler_t;
+
+
+/* we use it in a enum */
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/spawn-fcgi.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/spawn-fcgi.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/spawn-fcgi.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/spawn-fcgi.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,460 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_PWD_H
+#include <grp.h>
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#define FCGI_LISTENSOCK_FILENO 0
+
+#include "sys-socket.h"
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+/* for solaris 2.5 and netbsd 1.3.x */
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+#ifdef HAVE_SYS_UN_H
+int fcgi_spawn_connection(char *appPath, char **appArgv, char *addr, unsigned short port, const char *unixsocket, int child_count, int pid_fd, int nofork) {
+	int fcgi_fd;
+	int socket_type, status;
+	struct timeval tv = { 0, 100 * 1000 };
+
+	struct sockaddr_un fcgi_addr_un;
+	struct sockaddr_in fcgi_addr_in;
+	struct sockaddr *fcgi_addr;
+
+	socklen_t servlen;
+
+	pid_t child;
+	int val;
+
+	if (child_count < 2) {
+		child_count = 5;
+	}
+
+	if (child_count > 256) {
+		child_count = 256;
+	}
+
+
+	if (unixsocket) {
+		memset(&fcgi_addr, 0, sizeof(fcgi_addr));
+
+		fcgi_addr_un.sun_family = AF_UNIX;
+		strcpy(fcgi_addr_un.sun_path, unixsocket);
+
+#ifdef SUN_LEN
+		servlen = SUN_LEN(&fcgi_addr_un);
+#else
+		/* stevens says: */
+		servlen = strlen(fcgi_addr_un.sun_path) + sizeof(fcgi_addr_un.sun_family);
+#endif
+		socket_type = AF_UNIX;
+		fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
+
+		/* check if some backend is listening on the socket
+		 * as if we delete the socket-file and rebind there will be no "socket already in use" error
+		 */
+		if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
+			fprintf(stderr, "%s.%d\n",
+				__FILE__, __LINE__);
+			return -1;
+		}
+
+		if (-1 != connect(fcgi_fd, fcgi_addr, servlen)) {
+			fprintf(stderr, "%s.%d: socket is already used, can't spawn\n",
+				__FILE__, __LINE__);
+			return -1;
+		}
+
+		/* cleanup previous socket if it exists */
+		unlink(unixsocket);
+		close(fcgi_fd);
+	} else {
+		fcgi_addr_in.sin_family = AF_INET;
+                if (addr != NULL) {
+                        fcgi_addr_in.sin_addr.s_addr = inet_addr(addr);
+                } else {
+                        fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
+                }
+		fcgi_addr_in.sin_port = htons(port);
+		servlen = sizeof(fcgi_addr_in);
+
+		socket_type = AF_INET;
+		fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
+	}
+
+	/* open socket */
+	if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
+		fprintf(stderr, "%s.%d\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	val = 1;
+	if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
+		fprintf(stderr, "%s.%d\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	/* create socket */
+	if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
+		fprintf(stderr, "%s.%d: bind failed: %s\n",
+			__FILE__, __LINE__,
+			strerror(errno));
+		return -1;
+	}
+
+	if (-1 == listen(fcgi_fd, 1024)) {
+		fprintf(stderr, "%s.%d: fd = -1\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	if (!nofork) {
+		child = fork();
+	} else {
+		child = 0;
+	}
+
+	switch (child) {
+	case 0: {
+		char cgi_childs[64];
+
+		int i = 0;
+
+		/* is safe as we limit to 256 childs */
+		sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
+
+		if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
+			close(FCGI_LISTENSOCK_FILENO);
+			dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
+			close(fcgi_fd);
+		}
+
+		/* we don't need the client socket */
+		for (i = 3; i < 256; i++) {
+			close(i);
+		}
+
+		/* create environment */
+
+		putenv(cgi_childs);
+
+		/* fork and replace shell */
+		if (appArgv) {
+			execv(appArgv[0], appArgv);
+
+		} else {
+			char *b = malloc(strlen("exec ") + strlen(appPath) + 1);
+			strcpy(b, "exec ");
+			strcat(b, appPath);
+
+			/* exec the cgi */
+			execl("/bin/sh", "sh", "-c", b, (char *)NULL);
+		}
+
+		exit(errno);
+
+		break;
+	}
+	case -1:
+		/* error */
+		break;
+	default:
+		/* father */
+
+		/* wait */
+		select(0, NULL, NULL, NULL, &tv);
+
+		switch (waitpid(child, &status, WNOHANG)) {
+		case 0:
+			fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n",
+				__FILE__, __LINE__,
+				child);
+
+			/* write pid file */
+			if (pid_fd != -1) {
+				/* assume a 32bit pid_t */
+				char pidbuf[12];
+
+				snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child);
+
+				write(pid_fd, pidbuf, strlen(pidbuf));
+				close(pid_fd);
+				pid_fd = -1;
+			}
+
+			break;
+		case -1:
+			break;
+		default:
+			if (WIFEXITED(status)) {
+				fprintf(stderr, "%s.%d: child exited with: %d, %s\n",
+					__FILE__, __LINE__,
+					WEXITSTATUS(status), strerror(WEXITSTATUS(status)));
+			} else if (WIFSIGNALED(status)) {
+				fprintf(stderr, "%s.%d: child signaled: %d\n",
+					__FILE__, __LINE__,
+					WTERMSIG(status));
+			} else {
+				fprintf(stderr, "%s.%d: child died somehow: %d\n",
+					__FILE__, __LINE__,
+					status);
+			}
+		}
+
+		break;
+	}
+
+	close(fcgi_fd);
+
+	return 0;
+}
+
+
+void show_version () {
+	char *b = "spawn-fcgi" "-" PACKAGE_VERSION \
+" - spawns fastcgi processes\n"
+;
+	write(1, b, strlen(b));
+}
+
+void show_help () {
+	char *b = \
+"Usage: spawn-fcgi [options] -- <fcgiapp> [fcgi app arguments]\n" \
+"\n" \
+"spawn-fcgi v" PACKAGE_VERSION " - spawns fastcgi processes\n" \
+"\n" \
+"Options:\n" \
+" -f <fcgiapp> filename of the fcgi-application\n" \
+" -a <addr>    bind to ip address\n" \
+" -p <port>    bind to tcp-port\n" \
+" -s <path>    bind to unix-domain socket\n" \
+" -C <childs>  (PHP only) numbers of childs to spawn (default 5)\n" \
+" -P <path>    name of PID-file for spawed process\n" \
+" -n           no fork (for daemontools)\n" \
+" -v           show version\n" \
+" -h           show this help\n" \
+"(root only)\n" \
+" -c <dir>     chroot to directory\n" \
+" -u <user>    change to user-id\n" \
+" -g <group>   change to group-id\n" \
+;
+	write(1, b, strlen(b));
+}
+
+
+int main(int argc, char **argv) {
+	char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
+               *groupname = NULL, *unixsocket = NULL, *pid_file = NULL,
+                *addr = NULL;
+	char **fcgi_app_argv = { NULL };
+	unsigned short port = 0;
+	int child_count = 5;
+	int i_am_root, o;
+	int pid_fd = -1;
+	int nofork = 0;
+	struct sockaddr_un un;
+	const size_t sun_path_len = sizeof(un.sun_path);
+
+	i_am_root = (getuid() == 0);
+
+	while(-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:s:P:"))) {
+		switch(o) {
+		case 'f': fcgi_app = optarg; break;
+		case 'a': addr = optarg;/* ip addr */ break;
+		case 'p': port = strtol(optarg, NULL, 10);/* port */ break;
+		case 'C': child_count = strtol(optarg, NULL, 10);/*  */ break;
+		case 's': unixsocket = optarg; /* unix-domain socket */ break;
+		case 'c': if (i_am_root) { changeroot = optarg; }/* chroot() */ break;
+		case 'u': if (i_am_root) { username = optarg; } /* set user */ break;
+		case 'g': if (i_am_root) { groupname = optarg; } /* set group */ break;
+		case 'n': nofork = 1; break;
+		case 'P': pid_file = optarg; /* PID file */ break;
+		case 'v': show_version(); return 0;
+		case 'h': show_help(); return 0;
+		default:
+			show_help();
+			return -1;
+		}
+	}
+
+	if (optind < argc) {
+		fcgi_app_argv = &argv[optind];
+	}
+
+	if ((fcgi_app == NULL && fcgi_app_argv == NULL) || (port == 0 && unixsocket == NULL)) {
+		show_help();
+		return -1;
+	}
+
+	if (unixsocket && port) {
+		fprintf(stderr, "%s.%d: %s\n",
+			__FILE__, __LINE__,
+			"either a unix domain socket or a tcp-port, but not both\n");
+
+		return -1;
+	}
+
+	if (unixsocket && strlen(unixsocket) > sun_path_len - 1) {
+		fprintf(stderr, "%s.%d: %s\n",
+			__FILE__, __LINE__,
+			"path of the unix socket is too long\n");
+
+		return -1;
+	}
+
+	/* UID handling */
+	if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
+		/* we are setuid-root */
+
+		fprintf(stderr, "%s.%d: %s\n",
+			__FILE__, __LINE__,
+			"Are you nuts ? Don't apply a SUID bit to this binary\n");
+
+		return -1;
+	}
+
+	if (pid_file &&
+	    (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) {
+		struct stat st;
+		if (errno != EEXIST) {
+			fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
+				__FILE__, __LINE__,
+				pid_file, strerror(errno));
+
+			return -1;
+		}
+
+		/* ok, file exists */
+
+		if (0 != stat(pid_file, &st)) {
+			fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
+				__FILE__, __LINE__,
+				pid_file, strerror(errno));
+
+			return -1;
+		}
+
+		/* is it a regular file ? */
+
+		if (!S_ISREG(st.st_mode)) {
+			fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
+				__FILE__, __LINE__,
+				pid_file);
+
+			return -1;
+		}
+
+		if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
+			fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
+				__FILE__, __LINE__,
+				pid_file, strerror(errno));
+
+			return -1;
+		}
+	}
+
+	if (i_am_root) {
+		struct group *grp = NULL;
+		struct passwd *pwd = NULL;
+
+		/* set user and group */
+
+		if (username) {
+			if (NULL == (pwd = getpwnam(username))) {
+				fprintf(stderr, "%s.%d: %s, %s\n",
+					__FILE__, __LINE__,
+					"can't find username", username);
+				return -1;
+			}
+
+			if (pwd->pw_uid == 0) {
+				fprintf(stderr, "%s.%d: %s\n",
+					__FILE__, __LINE__,
+					"I will not set uid to 0\n");
+				return -1;
+			}
+		}
+
+		if (groupname) {
+			if (NULL == (grp = getgrnam(groupname))) {
+				fprintf(stderr, "%s.%d: %s %s\n",
+					__FILE__, __LINE__,
+					"can't find groupname",
+					groupname);
+				return -1;
+			}
+			if (grp->gr_gid == 0) {
+				fprintf(stderr, "%s.%d: %s\n",
+					__FILE__, __LINE__,
+					"I will not set gid to 0\n");
+				return -1;
+			}
+		}
+
+		/*
+		 * Change group before chroot, when we have access
+		 * to /etc/group
+		 */
+		if (groupname) {
+			setgid(grp->gr_gid);
+			setgroups(0, NULL);
+			if (username) {
+				initgroups(username, grp->gr_gid);
+			}
+		}
+
+		if (changeroot) {
+			if (-1 == chroot(changeroot)) {
+				fprintf(stderr, "%s.%d: %s %s\n",
+					__FILE__, __LINE__,
+					"chroot failed: ", strerror(errno));
+				return -1;
+			}
+			if (-1 == chdir("/")) {
+				fprintf(stderr, "%s.%d: %s %s\n",
+					__FILE__, __LINE__,
+					"chdir failed: ", strerror(errno));
+				return -1;
+			}
+		}
+
+		/* drop root privs */
+		if (username) {
+			setuid(pwd->pw_uid);
+		}
+	}
+
+       return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, child_count, pid_fd, nofork);
+}
+#else
+int main() {
+	return -1;
+}
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,210 @@
+/*
+           An implementation of top-down splaying with sizes
+             D. Sleator <sleator@cs.cmu.edu>, January 1994.
+
+  This extends top-down-splay.c to maintain a size field in each node.
+  This is the number of nodes in the subtree rooted there.  This makes
+  it possible to efficiently compute the rank of a key.  (The rank is
+  the number of nodes to the left of the given key.)  It it also
+  possible to quickly find the node of a given rank.  Both of these
+  operations are illustrated in the code below.  The remainder of this
+  introduction is taken from top-down-splay.c.
+
+  "Splay trees", or "self-adjusting search trees" are a simple and
+  efficient data structure for storing an ordered set.  The data
+  structure consists of a binary tree, with no additional fields.  It
+  allows searching, insertion, deletion, deletemin, deletemax,
+  splitting, joining, and many other operations, all with amortized
+  logarithmic performance.  Since the trees adapt to the sequence of
+  requests, their performance on real access patterns is typically even
+  better.  Splay trees are described in a number of texts and papers
+  [1,2,3,4].
+
+  The code here is adapted from simple top-down splay, at the bottom of
+  page 669 of [2].  It can be obtained via anonymous ftp from
+  spade.pc.cs.cmu.edu in directory /usr/sleator/public.
+
+  The chief modification here is that the splay operation works even if the
+  item being splayed is not in the tree, and even if the tree root of the
+  tree is NULL.  So the line:
+
+                              t = splay(i, t);
+
+  causes it to search for item with key i in the tree rooted at t.  If it's
+  there, it is splayed to the root.  If it isn't there, then the node put
+  at the root is the last one before NULL that would have been reached in a
+  normal binary search for i.  (It's a neighbor of i in the tree.)  This
+  allows many other operations to be easily implemented, as shown below.
+
+  [1] "Data Structures and Their Algorithms", Lewis and Denenberg,
+       Harper Collins, 1991, pp 243-251.
+  [2] "Self-adjusting Binary Search Trees" Sleator and Tarjan,
+       JACM Volume 32, No 3, July 1985, pp 652-686.
+  [3] "Data Structure and Algorithm Analysis", Mark Weiss,
+       Benjamin Cummins, 1992, pp 119-130.
+  [4] "Data Structures, Algorithms, and Performance", Derick Wood,
+       Addison-Wesley, 1993, pp 367-375
+*/
+
+#include <stdlib.h>
+#include <assert.h>
+#include "splaytree.h"
+
+#define compare(i,j) ((i)-(j))
+/* This is the comparison.                                       */
+/* Returns <0 if i<j, =0 if i=j, and >0 if i>j                   */
+
+#define node_size splaytree_size
+
+/* Splay using the key i (which may or may not be in the tree.)
+ * The starting root is t, and the tree used is defined by rat
+ * size fields are maintained */
+splay_tree * splaytree_splay (splay_tree *t, int i) {
+    splay_tree N, *l, *r, *y;
+    int comp, root_size, l_size, r_size;
+
+    if (t == NULL) return t;
+    N.left = N.right = NULL;
+    l = r = &N;
+    root_size = node_size(t);
+    l_size = r_size = 0;
+
+    for (;;) {
+        comp = compare(i, t->key);
+        if (comp < 0) {
+            if (t->left == NULL) break;
+            if (compare(i, t->left->key) < 0) {
+                y = t->left;                           /* rotate right */
+                t->left = y->right;
+                y->right = t;
+                t->size = node_size(t->left) + node_size(t->right) + 1;
+                t = y;
+                if (t->left == NULL) break;
+            }
+            r->left = t;                               /* link right */
+            r = t;
+            t = t->left;
+            r_size += 1+node_size(r->right);
+        } else if (comp > 0) {
+            if (t->right == NULL) break;
+            if (compare(i, t->right->key) > 0) {
+                y = t->right;                          /* rotate left */
+                t->right = y->left;
+                y->left = t;
+		t->size = node_size(t->left) + node_size(t->right) + 1;
+                t = y;
+                if (t->right == NULL) break;
+            }
+            l->right = t;                              /* link left */
+            l = t;
+            t = t->right;
+            l_size += 1+node_size(l->left);
+        } else {
+            break;
+        }
+    }
+    l_size += node_size(t->left);  /* Now l_size and r_size are the sizes of */
+    r_size += node_size(t->right); /* the left and right trees we just built.*/
+    t->size = l_size + r_size + 1;
+
+    l->right = r->left = NULL;
+
+    /* The following two loops correct the size fields of the right path  */
+    /* from the left child of the root and the right path from the left   */
+    /* child of the root.                                                 */
+    for (y = N.right; y != NULL; y = y->right) {
+        y->size = l_size;
+        l_size -= 1+node_size(y->left);
+    }
+    for (y = N.left; y != NULL; y = y->left) {
+        y->size = r_size;
+        r_size -= 1+node_size(y->right);
+    }
+
+    l->right = t->left;                                /* assemble */
+    r->left = t->right;
+    t->left = N.right;
+    t->right = N.left;
+
+    return t;
+}
+
+splay_tree * splaytree_insert(splay_tree * t, int i, void *data) {
+/* Insert key i into the tree t, if it is not already there. */
+/* Return a pointer to the resulting tree.                   */
+    splay_tree * new;
+
+    if (t != NULL) {
+	t = splaytree_splay(t, i);
+	if (compare(i, t->key)==0) {
+	    return t;  /* it's already there */
+	}
+    }
+    new = (splay_tree *) malloc (sizeof (splay_tree));
+    assert(new);
+    if (t == NULL) {
+	new->left = new->right = NULL;
+    } else if (compare(i, t->key) < 0) {
+	new->left = t->left;
+	new->right = t;
+	t->left = NULL;
+	t->size = 1+node_size(t->right);
+    } else {
+	new->right = t->right;
+	new->left = t;
+	t->right = NULL;
+	t->size = 1+node_size(t->left);
+    }
+    new->key = i;
+    new->data = data;
+    new->size = 1 + node_size(new->left) + node_size(new->right);
+    return new;
+}
+
+splay_tree * splaytree_delete(splay_tree *t, int i) {
+/* Deletes i from the tree if it's there.               */
+/* Return a pointer to the resulting tree.              */
+    splay_tree * x;
+    int tsize;
+
+    if (t==NULL) return NULL;
+    tsize = t->size;
+    t = splaytree_splay(t, i);
+    if (compare(i, t->key) == 0) {               /* found it */
+	if (t->left == NULL) {
+	    x = t->right;
+	} else {
+	    x = splaytree_splay(t->left, i);
+	    x->right = t->right;
+	}
+	free(t);
+	if (x != NULL) {
+	    x->size = tsize-1;
+	}
+	return x;
+    } else {
+	return t;                         /* It wasn't there */
+    }
+}
+
+splay_tree *find_rank(int r, splay_tree *t) {
+/* Returns a pointer to the node in the tree with the given rank.  */
+/* Returns NULL if there is no such node.                          */
+/* Does not change the tree.  To guarantee logarithmic behavior,   */
+/* the node found here should be splayed to the root.              */
+    int lsize;
+    if ((r < 0) || (r >= node_size(t))) return NULL;
+    for (;;) {
+	lsize = node_size(t->left);
+	if (r < lsize) {
+	    t = t->left;
+	} else if (r > lsize) {
+	    r = r - lsize -1;
+	    t = t->right;
+	} else {
+	    return t;
+	}
+    }
+}
+
+

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/splaytree.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,24 @@
+#ifndef _SPLAY_TREE_H_
+#define _SPLAY_TREE_H_
+
+typedef struct tree_node {
+    struct tree_node * left, * right;
+    int key;
+    int size;   /* maintained to be the number of nodes rooted here */
+
+    void *data;
+} splay_tree;
+
+
+splay_tree * splaytree_splay (splay_tree *t, int key);
+splay_tree * splaytree_insert(splay_tree *t, int key, void *data);
+splay_tree * splaytree_delete(splay_tree *t, int key);
+splay_tree * splaytree_size(splay_tree *t);
+
+#define splaytree_size(x) (((x)==NULL) ? 0 : ((x)->size))
+/* This macro returns the size of a node.  Unlike "x->size",     */
+/* it works even if x=NULL.  The test could be avoided by using  */
+/* a special version of NULL which was a real node with size 0.  */
+
+
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,747 @@
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <assert.h>
+
+#include "log.h"
+#include "stat_cache.h"
+#include "fdevent.h"
+#include "etag.h"
+
+#ifdef HAVE_ATTR_ATTRIBUTES_H
+#include <attr/attributes.h>
+#endif
+
+#ifdef HAVE_FAM_H
+# include <fam.h>
+#endif
+
+#include "sys-mmap.h"
+
+/* NetBSD 1.3.x needs it */
+#ifndef MAP_FAILED
+# define MAP_FAILED -1
+#endif
+
+#ifndef O_LARGEFILE
+# define O_LARGEFILE 0
+#endif
+
+#ifndef HAVE_LSTAT
+#define lstat stat
+#endif
+
+#if 0
+/* enables debug code for testing if all nodes in the stat-cache as accessable */
+#define DEBUG_STAT_CACHE
+#endif
+
+/*
+ * stat-cache
+ *
+ * we cache the stat() calls in our own storage
+ * the directories are cached in FAM
+ *
+ * if we get a change-event from FAM, we increment the version in the FAM->dir mapping
+ *
+ * if the stat()-cache is queried we check if the version id for the directory is the
+ * same and return immediatly.
+ *
+ *
+ * What we need:
+ *
+ * - for each stat-cache entry we need a fast indirect lookup on the directory name
+ * - for each FAMRequest we have to find the version in the directory cache (index as userdata)
+ *
+ * stat <<-> directory <-> FAMRequest
+ *
+ * if file is deleted, directory is dirty, file is rechecked ...
+ * if directory is deleted, directory mapping is removed
+ *
+ * */
+
+#ifdef HAVE_FAM_H
+typedef struct {
+	FAMRequest *req;
+	FAMConnection *fc;
+
+	buffer *name;
+
+	int version;
+} fam_dir_entry;
+#endif
+
+/* the directory name is too long to always compare on it
+ * - we need a hash
+ * - the hash-key is used as sorting criteria for a tree
+ * - a splay-tree is used as we can use the caching effect of it
+ */
+
+/* we want to cleanup the stat-cache every few seconds, let's say 10
+ *
+ * - remove entries which are outdated since 30s
+ * - remove entries which are fresh but havn't been used since 60s
+ * - if we don't have a stat-cache entry for a directory, release it from the monitor
+ */
+
+#ifdef DEBUG_STAT_CACHE
+typedef struct {
+	int *ptr;
+
+	size_t used;
+	size_t size;
+} fake_keys;
+
+static fake_keys ctrl;
+#endif
+
+stat_cache *stat_cache_init(void) {
+	stat_cache *fc = NULL;
+
+	fc = calloc(1, sizeof(*fc));
+
+	fc->dir_name = buffer_init();
+	fc->hash_key = buffer_init();
+#ifdef HAVE_FAM_H
+	fc->fam = calloc(1, sizeof(*fc->fam));
+#endif
+
+#ifdef DEBUG_STAT_CACHE
+	ctrl.size = 0;
+#endif
+
+	return fc;
+}
+
+static stat_cache_entry * stat_cache_entry_init(void) {
+	stat_cache_entry *sce = NULL;
+
+	sce = calloc(1, sizeof(*sce));
+
+	sce->name = buffer_init();
+	sce->etag = buffer_init();
+	sce->content_type = buffer_init();
+
+	return sce;
+}
+
+static void stat_cache_entry_free(void *data) {
+	stat_cache_entry *sce = data;
+	if (!sce) return;
+
+	buffer_free(sce->etag);
+	buffer_free(sce->name);
+	buffer_free(sce->content_type);
+
+	free(sce);
+}
+
+#ifdef HAVE_FAM_H
+static fam_dir_entry * fam_dir_entry_init(void) {
+	fam_dir_entry *fam_dir = NULL;
+
+	fam_dir = calloc(1, sizeof(*fam_dir));
+
+	fam_dir->name = buffer_init();
+
+	return fam_dir;
+}
+
+static void fam_dir_entry_free(void *data) {
+	fam_dir_entry *fam_dir = data;
+
+	if (!fam_dir) return;
+
+	FAMCancelMonitor(fam_dir->fc, fam_dir->req);
+
+	buffer_free(fam_dir->name);
+	free(fam_dir->req);
+
+	free(fam_dir);
+}
+#endif
+
+void stat_cache_free(stat_cache *sc) {
+	while (sc->files) {
+		int osize;
+		splay_tree *node = sc->files;
+
+		osize = sc->files->size;
+
+		stat_cache_entry_free(node->data);
+		sc->files = splaytree_delete(sc->files, node->key);
+
+		assert(osize - 1 == splaytree_size(sc->files));
+	}
+
+	buffer_free(sc->dir_name);
+	buffer_free(sc->hash_key);
+
+#ifdef HAVE_FAM_H
+	while (sc->dirs) {
+		int osize;
+		splay_tree *node = sc->dirs;
+
+		osize = sc->dirs->size;
+
+		fam_dir_entry_free(node->data);
+		sc->dirs = splaytree_delete(sc->dirs, node->key);
+
+		if (osize == 1) {
+			assert(NULL == sc->dirs);
+		} else {
+			assert(osize == (sc->dirs->size + 1));
+		}
+	}
+
+	if (sc->fam) {
+		FAMClose(sc->fam);
+		free(sc->fam);
+	}
+#endif
+	free(sc);
+}
+
+#ifdef HAVE_XATTR
+static int stat_cache_attr_get(buffer *buf, char *name) {
+	int attrlen;
+	int ret;
+
+	attrlen = 1024;
+	buffer_prepare_copy(buf, attrlen);
+	attrlen--;
+	if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) {
+		buf->used = attrlen + 1;
+		buf->ptr[attrlen] = '\0';
+	}
+	return ret;
+}
+#endif
+
+/* the famous DJB hash function for strings */
+static uint32_t hashme(buffer *str) {
+	uint32_t hash = 5381;
+	const char *s;
+	for (s = str->ptr; *s; s++) {
+		hash = ((hash << 5) + hash) + *s;
+	}
+
+	hash &= ~(1 << 31); /* strip the highest bit */
+
+	return hash;
+}
+
+#ifdef HAVE_FAM_H
+handler_t stat_cache_handle_fdevent(void *_srv, void *_fce, int revent) {
+	size_t i;
+	server *srv = _srv;
+	stat_cache *sc = srv->stat_cache;
+	size_t events;
+
+	UNUSED(_fce);
+	/* */
+
+	if ((revent & FDEVENT_IN) &&
+	    sc->fam) {
+
+		events = FAMPending(sc->fam);
+
+		for (i = 0; i < events; i++) {
+			FAMEvent fe;
+			fam_dir_entry *fam_dir;
+			splay_tree *node;
+			int ndx, j;
+
+			FAMNextEvent(sc->fam, &fe);
+
+			/* handle event */
+
+			switch(fe.code) {
+			case FAMChanged:
+			case FAMDeleted:
+			case FAMMoved:
+				/* if the filename is a directory remove the entry */
+
+				fam_dir = fe.userdata;
+				fam_dir->version++;
+
+				/* file/dir is still here */
+				if (fe.code == FAMChanged) break;
+
+				/* we have 2 versions, follow and no-follow-symlink */
+
+				for (j = 0; j < 2; j++) {
+					buffer_copy_string(sc->hash_key, fe.filename);
+					buffer_append_long(sc->hash_key, j);
+
+					ndx = hashme(sc->hash_key);
+
+					sc->dirs = splaytree_splay(sc->dirs, ndx);
+					node = sc->dirs;
+
+					if (node && (node->key == ndx)) {
+						int osize = splaytree_size(sc->dirs);
+
+						fam_dir_entry_free(node->data);
+						sc->dirs = splaytree_delete(sc->dirs, ndx);
+
+						assert(osize - 1 == splaytree_size(sc->dirs));
+					}
+				}
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	if (revent & FDEVENT_HUP) {
+		/* fam closed the connection */
+		srv->stat_cache->fam_fcce_ndx = -1;
+
+		fdevent_event_del(srv->ev, &(sc->fam_fcce_ndx), FAMCONNECTION_GETFD(sc->fam));
+		fdevent_unregister(srv->ev, FAMCONNECTION_GETFD(sc->fam));
+
+		FAMClose(sc->fam);
+		free(sc->fam);
+
+		sc->fam = NULL;
+	}
+
+	return HANDLER_GO_ON;
+}
+
+static int buffer_copy_dirname(buffer *dst, buffer *file) {
+	size_t i;
+
+	if (buffer_is_empty(file)) return -1;
+
+	for (i = file->used - 1; i+1 > 0; i--) {
+		if (file->ptr[i] == '/') {
+			buffer_copy_string_len(dst, file->ptr, i);
+			return 0;
+		}
+	}
+
+	return -1;
+}
+#endif
+
+#ifdef HAVE_LSTAT
+static int stat_cache_lstat(server *srv, buffer *dname, struct stat *lst) {
+	if (lstat(dname->ptr, lst) == 0) {
+		return S_ISLNK(lst->st_mode) ? 0 : 1;
+	}
+	else {
+		log_error_write(srv, __FILE__, __LINE__, "sbs",
+				"lstat failed for:",
+				dname, strerror(errno));
+	};
+	return -1;
+}
+#endif
+
+/***
+ *
+ *
+ *
+ * returns:
+ *  - HANDLER_FINISHED on cache-miss (don't forget to reopen the file)
+ *  - HANDLER_ERROR on stat() failed -> see errno for problem
+ */
+
+handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_cache_entry **ret_sce) {
+#ifdef HAVE_FAM_H
+	fam_dir_entry *fam_dir = NULL;
+	int dir_ndx = -1;
+	splay_tree *dir_node = NULL;
+#endif
+	stat_cache_entry *sce = NULL;
+	stat_cache *sc;
+	struct stat st;
+	size_t k;
+	int fd;
+	struct stat lst;
+#ifdef DEBUG_STAT_CACHE
+	size_t i;
+#endif
+
+	int file_ndx;
+	splay_tree *file_node = NULL;
+
+	*ret_sce = NULL;
+
+	/*
+	 * check if the directory for this file has changed
+	 */
+
+	sc = srv->stat_cache;
+
+	buffer_copy_string_buffer(sc->hash_key, name);
+	buffer_append_long(sc->hash_key, con->conf.follow_symlink);
+
+	file_ndx = hashme(sc->hash_key);
+	sc->files = splaytree_splay(sc->files, file_ndx);
+
+#ifdef DEBUG_STAT_CACHE
+	for (i = 0; i < ctrl.used; i++) {
+		if (ctrl.ptr[i] == file_ndx) break;
+	}
+#endif
+
+	if (sc->files && (sc->files->key == file_ndx)) {
+#ifdef DEBUG_STAT_CACHE
+		/* it was in the cache */
+		assert(i < ctrl.used);
+#endif
+
+		/* we have seen this file already and
+		 * don't stat() it again in the same second */
+
+		file_node = sc->files;
+
+		sce = file_node->data;
+
+		/* check if the name is the same, we might have a collision */
+
+		if (buffer_is_equal(name, sce->name)) {
+			if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_SIMPLE) {
+				if (sce->stat_ts == srv->cur_ts) {
+					*ret_sce = sce;
+					return HANDLER_GO_ON;
+				}
+			}
+		} else {
+			/* oops, a collision,
+			 *
+			 * file_node is used by the FAM check below to see if we know this file
+			 * and if we can save a stat().
+			 *
+			 * BUT, the sce is not reset here as the entry into the cache is ok, we
+			 * it is just not pointing to our requested file.
+			 *
+			 *  */
+
+			file_node = NULL;
+		}
+	} else {
+#ifdef DEBUG_STAT_CACHE
+		if (i != ctrl.used) {
+			fprintf(stderr, "%s.%d: %08x was already inserted but not found in cache, %s\n", __FILE__, __LINE__, file_ndx, name->ptr);
+		}
+		assert(i == ctrl.used);
+#endif
+	}
+
+#ifdef HAVE_FAM_H
+	/* dir-check */
+	if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
+		if (0 != buffer_copy_dirname(sc->dir_name, name)) {
+			SEGFAULT();
+		}
+
+		buffer_copy_string_buffer(sc->hash_key, sc->dir_name);
+		buffer_append_long(sc->hash_key, con->conf.follow_symlink);
+
+		dir_ndx = hashme(sc->hash_key);
+
+		sc->dirs = splaytree_splay(sc->dirs, dir_ndx);
+
+		if (sc->dirs && (sc->dirs->key == dir_ndx)) {
+			dir_node = sc->dirs;
+		}
+
+		if (dir_node && file_node) {
+			/* we found a file */
+
+			sce = file_node->data;
+			fam_dir = dir_node->data;
+
+			if (fam_dir->version == sce->dir_version) {
+				/* the stat()-cache entry is still ok */
+
+				*ret_sce = sce;
+				return HANDLER_GO_ON;
+			}
+		}
+	}
+#endif
+
+	/*
+	 * *lol*
+	 * - open() + fstat() on a named-pipe results in a (intended) hang.
+	 * - stat() if regular file + open() to see if we can read from it is better
+	 *
+	 * */
+	if (-1 == stat(name->ptr, &st)) {
+		return HANDLER_ERROR;
+	}
+
+
+	if (S_ISREG(st.st_mode)) {
+		/* try to open the file to check if we can read it */
+		if (-1 == (fd = open(name->ptr, O_RDONLY))) {
+			return HANDLER_ERROR;
+		}
+		close(fd);
+	}
+
+	if (NULL == sce) {
+		int osize = 0;
+
+		if (sc->files) {
+			osize = sc->files->size;
+		}
+
+		sce = stat_cache_entry_init();
+		buffer_copy_string_buffer(sce->name, name);
+
+		sc->files = splaytree_insert(sc->files, file_ndx, sce);
+#ifdef DEBUG_STAT_CACHE
+		if (ctrl.size == 0) {
+			ctrl.size = 16;
+			ctrl.used = 0;
+			ctrl.ptr = malloc(ctrl.size * sizeof(*ctrl.ptr));
+		} else if (ctrl.size == ctrl.used) {
+			ctrl.size += 16;
+			ctrl.ptr = realloc(ctrl.ptr, ctrl.size * sizeof(*ctrl.ptr));
+		}
+
+		ctrl.ptr[ctrl.used++] = file_ndx;
+
+		assert(sc->files);
+		assert(sc->files->data == sce);
+		assert(osize + 1 == splaytree_size(sc->files));
+#endif
+	}
+
+	sce->st = st;
+	sce->stat_ts = srv->cur_ts;
+
+	/* catch the obvious symlinks
+	 *
+	 * this is not a secure check as we still have a race-condition between
+	 * the stat() and the open. We can only solve this by
+	 * 1. open() the file
+	 * 2. fstat() the fd
+	 *
+	 * and keeping the file open for the rest of the time. But this can
+	 * only be done at network level.
+	 *
+	 * per default it is not a symlink
+	 * */
+#ifdef HAVE_LSTAT
+	sce->is_symlink = 0;
+
+	/* we want to only check for symlinks if we should block symlinks.
+	 */
+	if (!con->conf.follow_symlink) {
+		if (stat_cache_lstat(srv, name, &lst)  == 0) {
+#ifdef DEBUG_STAT_CACHE
+				log_error_write(srv, __FILE__, __LINE__, "sb",
+						"found symlink", name);
+#endif
+				sce->is_symlink = 1;
+		}
+
+		/*
+		 * we assume "/" can not be symlink, so
+		 * skip the symlink stuff if our path is /
+		 **/
+		else if ((name->used > 2)) {
+			buffer *dname;
+			char *s_cur;
+
+			dname = buffer_init();
+			buffer_copy_string_buffer(dname, name);
+
+			while ((s_cur = strrchr(dname->ptr,'/'))) {
+				*s_cur = '\0';
+				dname->used = s_cur - dname->ptr + 1;
+				if (dname->ptr == s_cur) {
+#ifdef DEBUG_STAT_CACHE
+					log_error_write(srv, __FILE__, __LINE__, "s", "reached /");
+#endif
+					break;
+				}
+#ifdef DEBUG_STAT_CACHE
+				log_error_write(srv, __FILE__, __LINE__, "sbs",
+						"checking if", dname, "is a symlink");
+#endif
+				if (stat_cache_lstat(srv, dname, &lst)  == 0) {
+					sce->is_symlink = 1;
+#ifdef DEBUG_STAT_CACHE
+					log_error_write(srv, __FILE__, __LINE__, "sb",
+							"found symlink", dname);
+#endif
+					break;
+				};
+			};
+			buffer_free(dname);
+		};
+	};
+#endif
+
+	if (S_ISREG(st.st_mode)) {
+		/* determine mimetype */
+		buffer_reset(sce->content_type);
+
+		for (k = 0; k < con->conf.mimetypes->used; k++) {
+			data_string *ds = (data_string *)con->conf.mimetypes->data[k];
+			buffer *type = ds->key;
+
+			if (type->used == 0) continue;
+
+			/* check if the right side is the same */
+			if (type->used > name->used) continue;
+
+			if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
+				buffer_copy_string_buffer(sce->content_type, ds->value);
+				break;
+			}
+		}
+ 		etag_create(sce->etag, &(sce->st), con->etag_flags);
+#ifdef HAVE_XATTR
+		if (con->conf.use_xattr && buffer_is_empty(sce->content_type)) {
+			stat_cache_attr_get(sce->content_type, name->ptr);
+		}
+#endif
+	} else if (S_ISDIR(st.st_mode)) {
+ 		etag_create(sce->etag, &(sce->st), con->etag_flags);
+	}
+
+#ifdef HAVE_FAM_H
+	if (sc->fam &&
+	    (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) {
+		/* is this directory already registered ? */
+		if (!dir_node) {
+			fam_dir = fam_dir_entry_init();
+			fam_dir->fc = sc->fam;
+
+			buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
+
+			fam_dir->version = 1;
+
+			fam_dir->req = calloc(1, sizeof(FAMRequest));
+
+			if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr,
+						     fam_dir->req, fam_dir)) {
+
+				log_error_write(srv, __FILE__, __LINE__, "sbsbs",
+						"monitoring dir failed:",
+						fam_dir->name, 
+						"file:", name,
+						FamErrlist[FAMErrno]);
+
+				fam_dir_entry_free(fam_dir);
+			} else {
+				int osize = 0;
+
+			       	if (sc->dirs) {
+					osize = sc->dirs->size;
+				}
+
+				sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir);
+				assert(sc->dirs);
+				assert(sc->dirs->data == fam_dir);
+				assert(osize == (sc->dirs->size - 1));
+			}
+		} else {
+			fam_dir = dir_node->data;
+		}
+
+		/* bind the fam_fc to the stat() cache entry */
+
+		if (fam_dir) {
+			sce->dir_version = fam_dir->version;
+			sce->dir_ndx     = dir_ndx;
+		}
+	}
+#endif
+
+	*ret_sce = sce;
+
+	return HANDLER_GO_ON;
+}
+
+/**
+ * remove stat() from cache which havn't been stat()ed for
+ * more than 10 seconds
+ *
+ *
+ * walk though the stat-cache, collect the ids which are too old
+ * and remove them in a second loop
+ */
+
+static int stat_cache_tag_old_entries(server *srv, splay_tree *t, int *keys, size_t *ndx) {
+	stat_cache_entry *sce;
+
+	if (!t) return 0;
+
+	stat_cache_tag_old_entries(srv, t->left, keys, ndx);
+	stat_cache_tag_old_entries(srv, t->right, keys, ndx);
+
+	sce = t->data;
+
+	if (srv->cur_ts - sce->stat_ts > 2) {
+		keys[(*ndx)++] = t->key;
+	}
+
+	return 0;
+}
+
+int stat_cache_trigger_cleanup(server *srv) {
+	stat_cache *sc;
+	size_t max_ndx = 0, i;
+	int *keys;
+
+	sc = srv->stat_cache;
+
+	if (!sc->files) return 0;
+
+	keys = calloc(1, sizeof(size_t) * sc->files->size);
+
+	stat_cache_tag_old_entries(srv, sc->files, keys, &max_ndx);
+
+	for (i = 0; i < max_ndx; i++) {
+		int ndx = keys[i];
+		splay_tree *node;
+
+		sc->files = splaytree_splay(sc->files, ndx);
+
+		node = sc->files;
+
+		if (node && (node->key == ndx)) {
+#ifdef DEBUG_STAT_CACHE
+			size_t j;
+			int osize = splaytree_size(sc->files);
+			stat_cache_entry *sce = node->data;
+#endif
+			stat_cache_entry_free(node->data);
+			sc->files = splaytree_delete(sc->files, ndx);
+
+#ifdef DEBUG_STAT_CACHE
+			for (j = 0; j < ctrl.used; j++) {
+				if (ctrl.ptr[j] == ndx) {
+					ctrl.ptr[j] = ctrl.ptr[--ctrl.used];
+					break;
+				}
+			}
+
+			assert(osize - 1 == splaytree_size(sc->files));
+#endif
+		}
+	}
+
+	free(keys);
+
+	return 0;
+}

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stat_cache.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,13 @@
+#ifndef _FILE_CACHE_H_
+#define _FILE_CACHE_H_
+
+#include "base.h"
+
+stat_cache *stat_cache_init(void);
+void stat_cache_free(stat_cache *fc);
+
+handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_cache_entry **fce);
+handler_t stat_cache_handle_fdevent(void *_srv, void *_fce, int revent);
+
+int stat_cache_trigger_cleanup(server *srv);
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,60 @@
+#include <stdlib.h>
+
+#include "status_counter.h"
+/**
+ * The status array can carry all the status information you want
+ * the key to the array is <module-prefix>.<name>
+ * and the values are counters
+ *
+ * example:
+ *   fastcgi.backends        = 10
+ *   fastcgi.active-backends = 6
+ *   fastcgi.backend.<key>.load = 24
+ *   fastcgi.backend.<key>....
+ *
+ *   fastcgi.backend.<key>.disconnects = ...
+ */
+
+data_integer *status_counter_get_counter(server *srv, const char *s, size_t len) {
+	data_integer *di;
+
+	if (NULL == (di = (data_integer *)array_get_element(srv->status, s))) {
+		/* not found, create it */
+
+		if (NULL == (di = (data_integer *)array_get_unused_element(srv->status, TYPE_INTEGER))) {
+			di = data_integer_init();
+		}
+		buffer_copy_string_len(di->key, s, len);
+		di->value = 0;
+
+		array_insert_unique(srv->status, (data_unset *)di);
+	}
+	return di;
+}
+
+/* dummies of the statistic framework functions
+ * they will be moved to a statistics.c later */
+int status_counter_inc(server *srv, const char *s, size_t len) {
+	data_integer *di = status_counter_get_counter(srv, s, len);
+
+	di->value++;
+
+	return 0;
+}
+
+int status_counter_dec(server *srv, const char *s, size_t len) {
+	data_integer *di = status_counter_get_counter(srv, s, len);
+
+	if (di->value > 0) di->value--;
+
+	return 0;
+}
+
+int status_counter_set(server *srv, const char *s, size_t len, int val) {
+	data_integer *di = status_counter_get_counter(srv, s, len);
+
+	di->value = val;
+
+	return 0;
+}
+

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/status_counter.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,14 @@
+#ifndef _STATUS_COUNTER_H_
+#define _STATUS_COUNTER_H_
+
+#include <sys/types.h>
+
+#include "array.h"
+#include "base.h"
+
+data_integer *status_counter_get_counter(server *srv, const char *s, size_t len);
+int status_counter_inc(server *srv, const char *s, size_t len);
+int status_counter_dec(server *srv, const char *s, size_t len);
+int status_counter_set(server *srv, const char *s, size_t len, int val);
+
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,107 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "stream.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sys-mmap.h"
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+int stream_open(stream *f, buffer *fn) {
+	struct stat st;
+#ifdef HAVE_MMAP
+	int fd;
+#elif defined __WIN32
+	HANDLE *fh, *mh;
+	void *p;
+#endif
+
+	f->start = NULL;
+
+	if (-1 == stat(fn->ptr, &st)) {
+		return -1;
+	}
+
+	f->size = st.st_size;
+
+#ifdef HAVE_MMAP
+	if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY))) {
+		return -1;
+	}
+
+	f->start = mmap(0, f->size, PROT_READ, MAP_SHARED, fd, 0);
+
+	close(fd);
+
+	if (MAP_FAILED == f->start) {
+		return -1;
+	}
+
+#elif defined __WIN32
+	fh = CreateFile(fn->ptr,
+			GENERIC_READ,
+			FILE_SHARE_READ,
+			NULL,
+			OPEN_EXISTING,
+			FILE_ATTRIBUTE_READONLY,
+			NULL);
+
+	if (!fh) return -1;
+
+	mh = CreateFileMapping( fh,
+			NULL,
+			PAGE_READONLY,
+			(sizeof(off_t) > 4) ? f->size >> 32 : 0,
+			f->size & 0xffffffff,
+			NULL);
+
+	if (!mh) {
+/*
+		LPVOID lpMsgBuf;
+		FormatMessage(
+		        FORMAT_MESSAGE_ALLOCATE_BUFFER |
+		        FORMAT_MESSAGE_FROM_SYSTEM,
+		        NULL,
+		        GetLastError(),
+		        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		        (LPTSTR) &lpMsgBuf,
+		        0, NULL );
+*/
+		return -1;
+	}
+
+	p = MapViewOfFile(mh,
+			FILE_MAP_READ,
+			0,
+			0,
+			0);
+	CloseHandle(mh);
+	CloseHandle(fh);
+
+	f->start = p;
+#else
+# error no mmap found
+#endif
+
+	return 0;
+}
+
+int stream_close(stream *f) {
+#ifdef HAVE_MMAP
+	if (f->start) munmap(f->start, f->size);
+#elif defined(__WIN32)
+	if (f->start) UnmapViewOfFile(f->start);
+#endif
+
+	f->start = NULL;
+
+	return 0;
+}

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/stream.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,14 @@
+#ifndef _STREAM_H_
+#define _STREAM_H_
+
+#include "buffer.h"
+
+typedef struct {
+	char *start;
+	off_t size;
+} stream;
+
+int stream_open(stream *f, buffer *fn);
+int stream_close(stream *f);
+
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-mmap.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-mmap.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-mmap.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-mmap.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,24 @@
+#ifndef WIN32_MMAP_H
+#define WIN32_MMAP_H
+
+#ifdef __WIN32
+
+#define MAP_FAILED -1
+#define PROT_SHARED 0
+#define MAP_SHARED 0
+#define PROT_READ 0
+
+#define mmap(a, b, c, d, e, f) (-1)
+#define munmap(a, b) (-1)
+
+#include <windows.h>
+
+#else
+#include <sys/mman.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED -1
+#endif
+#endif
+
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-socket.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-socket.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-socket.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/sys-socket.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,25 @@
+#ifndef WIN32_SOCKET_H
+#define WIN32_SOCKET_H
+
+#ifdef __WIN32
+
+#include <winsock2.h>
+
+#define ECONNRESET WSAECONNRESET
+#define EINPROGRESS WSAEINPROGRESS
+#define EALREADY WSAEALREADY
+#define ECONNABORTED WSAECONNABORTED
+#define ioctl ioctlsocket
+#define hstrerror(x) ""
+#else
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+
+#include <netdb.h>
+#endif
+
+#endif

Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/tests/404-handler.conf
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/tests/404-handler.conf?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/tests/404-handler.conf (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/tests/404-handler.conf Mon Jul 21 21:35:35 2008
@@ -0,0 +1,49 @@
+debug.log-request-handling   = "enable"
+debug.log-response-header   = "enable"
+debug.log-request-header   = "enable"
+
+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
+
+## bind to port (default: 80)
+server.port                 = 2048
+
+## bind to localhost (default: all interfaces)
+server.bind                = "localhost"
+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
+server.name                = "www.example.org"
+server.tag                 = "Apache 1.3.29"
+
+
+server.modules              = (
+				  "mod_fastcgi",
+				  "mod_cgi",
+				"mod_accesslog" )
+
+######################## MODULE CONFIG ############################
+
+
+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
+
+mimetype.assign             = ( ".html" => "text/html" )
+
+cgi.assign = (".pl" => "/usr/bin/perl" )
+
+# fastcgi.server += ( "/404.pl" =>
+#                    ( "404-handler" =>
+#                      (
+#                        "socket" => env.SRCDIR + "/tmp/pl-404-fastcgi-1.socket",
+#                        "bin-path" => server.document-root + "/404.pl",
+#                        "max-procs" => 1,
+#                        "check-local" => "disable",
+#                        "broken-scriptfilename" => "enable",
+#                      )
+#                    ),
+#                  )
+
+$HTTP["url"] =~ "^/static/" {
+  server.error-handler-404 = "/404.html"
+}
+else $HTTP["url"] =~ "." {
+  server.error-handler-404 = "/404.pl"
+}



Mime
View raw message